Published on

前端性能优化

Authors
  • avatar
    Name
    hpoenixf
    Twitter

背景

在开发好页面后,如何让页面更快更好地运行,是区分程序员技术水平和视野的重要指标。因此,面试时,面试官经常会问你一个问题:如何进行性能优化?

如果你在这时感到头脑一片空白,或者像之前的我一样,靠死记硬背或者仅凭过去的经验回答一些诸如压缩代码、打包代码、雪碧图、CDN、事件代理等方法,这说明你对性能优化的整体掌握还不够深入,还处于“听说过某方法就加入”的阶段。这种方法很难进行系统化的优化。

最近一周,通过大量的面试和资料查询,我积累了一些经验和思考。在这个招聘的黄金时间,希望能分享给大家,帮助大家更好地理解和掌握性能优化。


什么是性能优化

从前端的角度来看,性能优化可以分为两个方向:

  1. 页面加载速度快
  2. 页面使用流畅

因此,我们对性能优化的研究可以聚焦在两个方面:页面加载时间页面运行效率


从浏览器打开到页面渲染完成,花费了多少时间?

这个问题在面试中经常被问到:从浏览器打开到页面渲染完成,发生了什么事情?

主要的过程如下:

  • 浏览器解析
  • 查询缓存
  • DNS 查询
  • 建立连接
  • 服务器处理请求
  • 服务器发送响应
  • 客户端收到页面
  • 解析 HTML
  • 构建渲染树
  • 开始显示内容(白屏时间)
  • 首屏内容加载完成(首屏时间)
  • 用户可交互(DOMContentLoaded)
  • 页面加载完成(load)

很显然,如果要优化加载时间,我们需要从上述每一个步骤进行思考和总结,而不是零散地东拼西凑。


页面加载时间监控

有句话说得好:If You Can’t Measure It, You Can’t Manage It。 在优化这些环节之前,我们需要知道如何监控每个环节所花费的时间。

推荐工具:PerformanceTiming

PerformanceTiming 可以获取许多与页面加载相关的数据,常用的数据有:

  • DNS 解析时间domainLookupEnd - domainLookupStart
  • TCP 建立连接时间connectEnd - connectStart
  • 白屏时间responseStart - navigationStart
  • DOM 渲染完成时间domContentLoadedEventEnd - navigationStart
  • 页面 onload 时间loadEventEnd - navigationStart

如果不使用该 API,也可以通过以下方法监控:

  • 以服务器渲染返回的时间或 SPA 路由跳转离开的时间为起点;
  • DOMContentLoadedload 等事件为结束点进行记录;
  • 或直接使用 Google Analytics 等工具。

方法很多,这里不展开细讲。


服务器部分优化要点

后端部分可以从以下几个方面进行优化:

  1. 缓存:缓存优化这里不细说。
  2. DNS 查询时间:可以使用 httpdns 或 DNS 预加载、域名收敛等手段优化。
  3. 链接时间
    • 使用长连接和连接复用,如 keep-alivelong-pollinghttp-streamingwebsocket 或自定义协议;
    • 最好直接使用 HTTP/2。
    • 为了优化连接环节,前端需要结合资源使用 CDN、雪碧图、代码合并等手段。
  4. 服务器处理请求时间
    • 移动端访问 PC 页面时,应在服务器端使用 302 跳转,而非前端跳转;
    • 启用 HSTS,要求浏览器之后访问使用 HTTPS,减少 HTTP 到 HTTPS 的无谓跳转,同时防止 SSL 剥离攻击,提升安全性。
  5. 服务器发送响应时间
    • 使用 Transfer-Encoding=chunked 以多次返回响应,具体可参考 bigpipe
    • 减小 cookie 的体积等。

前端部分优化要点

前端部分的优化可以聚焦于以下时间点:

  1. 白屏时间
  2. 首屏时间
  3. 可交互时间
  4. 加载完成时间

针对每个时间点的优化方法有很多,可以结合业务场景灵活使用。