常见性能优化手段

URL 从输入到显示的流程

简写:DNS -> HTTP/HTTPS -> 缓存 -> 回馈报文 -> 构建 DOM、构建 CSSOM、构建渲染树 -> 回流和重绘

性能优化

可以从上面的过程去分析每一部分的优化点。

指标评估

  • chrome 开发者工具中的 network 和 performace
  • window.performace 数据
  • webpack 插件静态资源打包分析

DNS

  • dns-prefetch:DNS 预解析

HTTP/HTTPS

减少请求数量

  • 雪碧图
  • HTTP 2.0 多路复用

缓存

充分利用浏览器缓存

  • loacalStorage、sessionStorage
  • 强缓存(expires、cache-control)
  • 协商缓存(Etag、Last-Modified)

回馈报文

减少体积

  • 服务端 Gzip 打包压缩
  • 代码压缩
  • http 2.0 首部压缩
  • webpack 插件能力(tree-shaking)

构建 DOM、渲染树等过程

这部分技术上的手段不太多,更多的可以从用户体验上做一些优化

  • 骨架屏
  • 图片懒加载

回流、重绘

这一部分主要是减少回流。重绘的次数很频繁,优化效果不会很大。

  • DOM 统一处理减少回流

字体加载策略优化

之前做过的一个字体加载策略上的一个问题。

当字体文件过大(比如一些中文包),一直没有下载完毕的情况下,会有这样一种现象,页面一直字体白屏,而且 Chrome 的表现和 Firefox 的表现还不一样。会有两种策略 FOUT 和 FOIT。

  • FOIT 是指是指浏览器在自定义字体还没有下载完成的情况下,会隐藏文本(一般会以 3s 为界限)。
  • FOUT 是指浏览器在自定义字体没下载完成之前,会使用降级字体,也就是 web 安全字体,后面如果下载完成,会替换掉。

在上面两种策略的情况下,不同场景就会有不同的选择。而且为了体验上的友好,需要对不同浏览器的策略做一个统一。css 有一个属性,是 font-display,可以指定字体的展示策略。

阻塞周期 & 交换周期

字体展示会有两个时间段:阻塞周期、交换周期。

  • 阻塞周期:如果未加载字体,则任何使用的元素都会被隐藏。
  • 交换周期:如果未加载字体,则任何使用的元素都会呈现后备字体。

因此就可以根据场景去选择具体的展示策略。对于我们的页面来讲,是一个有很多文本的页面,由于自定义字体只是一个锦上添花的效果,并没有十分的重要,如果采用浏览器默认的方式,阻塞 3s 就会造成一个非常影响用户体验的问题。

我们就可以设置 font-size:optional,为字体提供一个很小的阻塞周期,并且没有交换周期。表现是,对于第一次进来的用户,100ms 下载不完,就直接使用降级字体,并且后续下载完也不会替换(因为字体不同,高度也不同,替换会有一个页面抖动的问题)。对于第二次进入,会有字体缓存,因此会直接使用自定义字体。

最后达成了一个比较符合心理预期的展示效果。