Web全链路优化

前言

从访问一个页面到页面的呈现,要经历以下的过程:
DNS查询-TCP连接 > 客户端http请求 > 服务端响应 > 客户端渲染
下面就从整个过程分析下有哪些可以优化的地方和措施。

DNS查询优化:

client > os > hosts > os发起DNS请求

DNS查询总是要经过上述过程的,不可避免。
可以优化的地方是前端的 DNS-Prefetch 链接预取。在页面的head头部加入:

1
<link ref="prefetch" href="">

这样可以预查询DNS和预加载资源到缓存。

请求速度优化:

资源优化:

  1. 对同一个域名的同类资源进行请求合并,减少http请求数,需要后端支持;
  2. 对资源进行压缩及合并处理,如果可以的话;
  3. 如果一次性加载的资源少,尽量使用一个cdn,如果加载的资源非常多,则可以启用多个cdn域名,从而突破前端连接数限制;
  4. 资源按需加载,比如在 SPA 单页应用中,如果单页应用比较大,就不要一次性加载全部资源和页面,而应该按需异步加载访问的页面组件。webpack提供了 Code Splitting 代码分割功能,Vue就使用该功能实现异步组件;

http协议选择:

各大浏览器厂商都已经支持 http2了,如果可以,尽量启用 http2。http2 有很多优点:

  1. 服务端推送,可以缓存;
  2. 多路复用:单连接并发多请求。基于流的实现;
  3. 头部压缩:使用 HPACK 算法压缩头部;
  4. 请求优先级和依赖性:优先级高的需要首先处理,优先级低的可以稍微排排队;
  5. 二进制文件,解析更有效率,更紧密,更不容易出错;

渲染优化:

script优化:

  1. script标签放到body闭合标签前面,不阻塞页面渲染,加快页面显示;
  2. 永远只在必要的情况下使用框架和库,如果业务很小但是用了较大的库,即使是 jQuery 也是得不偿失的;
  3. 能异步加载和延迟加载的script就异步和延迟加载,比如统计代码;

css优化:

  1. 删除无用规则和重复规则;
  2. 可以考虑内联关键CSS;
  3. 避免@imports和Base64;
    避免 Bas64 可以提高css文件的压缩比率;甚至在任何文件里都应该避免使用 Base64;
  4. 尽量少的使用耗性能的 css 属性和选择器,比如 * 通配符,从而加快CSSOM构建和渲染。css优化细节挺多的,这里不细说;
  5. style标签放到head标签,防止页面的跳动渲染;

image优化:

  1. 尽量使用压缩比率高的格式,比如 webp;
  2. 对于图标,尽量使用svg或者iconfont字体图标。也可以使用兼容性较好的 css sprite;
  3. 尽量不要包含太多的 Base64 格式的图片,会降低文件压缩率;
  4. 如果页面有大量图片,建议做图片延迟加载和预加载;
    在分页业务里,可以考虑使用图片预加载。
    在一次性展示大量图片的页面里,可以考虑使用延迟加载。

    注:更具体的图片优化,可以看这篇文章:图片优化

html优化:

  1. 尽量使用语义化标签,提高SEO优化;
  2. 对于不支持h5标签的浏览器采用html5.shim.js来支持;
  3. 标签不要嵌套过深;
  4. 对于移动端的响应式布局和高清显式,可以看我的原创项目flexible,该项目在生产环境下经历了多个版本,目前已经很稳定了,具体可以查看项目。

服务端:

  1. 避免不必要的重定向;
  2. 使用内容分发网络 CDN ,加快资源响应;
  3. 适当调节CDN的TTL值,增加缓存时间,提高缓存命中率;
  4. 开启 gzip 压缩;

缓存优化:

  1. Last-Modified: 能初步检测文件是否更改,没更改则返回304,但是 Last-Modified 也有它自己的缺点,比如文件内容没改变,只是最后修改时间改变,还有它的检测时间是秒级的,还有它不能精确得到文件的最后修改时间,这些问题都会导致问题;
  2. ETag:ETag可以解决Last-Modified的问题,ETag是内容相关的。所有把两者放在一起,可以很好的做到缓存优化;
  3. Cache-Control: 用于代替 Expires,对于某些只需要在一定时间之后过期的资源来说,使用它最合适了;

其他:

  1. 服务端的其他优化,比如负载均衡等,由于尚不了解,这里就不说了;
  2. 数据库也不甚了解,这里也不说了;
  3. 哪里说的不对,可以提issue交流;