前言
从访问一个页面到页面的呈现,要经历以下的过程:
DNS查询-TCP连接 > 客户端http请求 > 服务端响应 > 客户端渲染
下面就从整个过程分析下有哪些可以优化的地方和措施。
DNS查询优化:
client > os > hosts > os发起DNS请求
DNS查询总是要经过上述过程的,不可避免。
可以优化的地方是前端的 DNS-Prefetch 链接预取。在页面的head头部加入:1
<link ref="prefetch" href="">
这样可以预查询DNS和预加载资源到缓存。
请求速度优化:
资源优化:
- 对同一个域名的同类资源进行请求合并,减少http请求数,需要后端支持;
- 对资源进行压缩及合并处理,如果可以的话;
- 如果一次性加载的资源少,尽量使用一个cdn,如果加载的资源非常多,则可以启用多个cdn域名,从而突破前端连接数限制;
- 资源按需加载,比如在 SPA 单页应用中,如果单页应用比较大,就不要一次性加载全部资源和页面,而应该按需异步加载访问的页面组件。webpack提供了 Code Splitting 代码分割功能,Vue就使用该功能实现异步组件;
http协议选择:
各大浏览器厂商都已经支持 http2了,如果可以,尽量启用 http2。http2 有很多优点:
- 服务端推送,可以缓存;
- 多路复用:单连接并发多请求。基于流的实现;
- 头部压缩:使用 HPACK 算法压缩头部;
- 请求优先级和依赖性:优先级高的需要首先处理,优先级低的可以稍微排排队;
- 二进制文件,解析更有效率,更紧密,更不容易出错;
渲染优化:
script优化:
- script标签放到body闭合标签前面,不阻塞页面渲染,加快页面显示;
- 永远只在必要的情况下使用框架和库,如果业务很小但是用了较大的库,即使是 jQuery 也是得不偿失的;
- 能异步加载和延迟加载的script就异步和延迟加载,比如统计代码;
css优化:
- 删除无用规则和重复规则;
- 可以考虑内联关键CSS;
- 避免@imports和Base64;
避免 Bas64 可以提高css文件的压缩比率;甚至在任何文件里都应该避免使用 Base64; - 尽量少的使用耗性能的 css 属性和选择器,比如 * 通配符,从而加快CSSOM构建和渲染。css优化细节挺多的,这里不细说;
- style标签放到head标签,防止页面的跳动渲染;
image优化:
- 尽量使用压缩比率高的格式,比如 webp;
- 对于图标,尽量使用svg或者iconfont字体图标。也可以使用兼容性较好的 css sprite;
- 尽量不要包含太多的 Base64 格式的图片,会降低文件压缩率;
如果页面有大量图片,建议做图片延迟加载和预加载;
在分页业务里,可以考虑使用图片预加载。
在一次性展示大量图片的页面里,可以考虑使用延迟加载。注:更具体的图片优化,可以看这篇文章:图片优化
html优化:
- 尽量使用语义化标签,提高SEO优化;
- 对于不支持h5标签的浏览器采用html5.shim.js来支持;
- 标签不要嵌套过深;
- 对于移动端的响应式布局和高清显式,可以看我的原创项目flexible,该项目在生产环境下经历了多个版本,目前已经很稳定了,具体可以查看项目。
服务端:
- 避免不必要的重定向;
- 使用内容分发网络 CDN ,加快资源响应;
- 适当调节CDN的TTL值,增加缓存时间,提高缓存命中率;
- 开启 gzip 压缩;
缓存优化:
- Last-Modified: 能初步检测文件是否更改,没更改则返回304,但是 Last-Modified 也有它自己的缺点,比如文件内容没改变,只是最后修改时间改变,还有它的检测时间是秒级的,还有它不能精确得到文件的最后修改时间,这些问题都会导致问题;
- ETag:ETag可以解决Last-Modified的问题,ETag是内容相关的。所有把两者放在一起,可以很好的做到缓存优化;
- Cache-Control: 用于代替 Expires,对于某些只需要在一定时间之后过期的资源来说,使用它最合适了;
其他:
- 服务端的其他优化,比如负载均衡等,由于尚不了解,这里就不说了;
- 数据库也不甚了解,这里也不说了;
- 哪里说的不对,可以提issue交流;