前端性能优化之性能优化方法论

612 阅读7分钟

image.png

性能优化体系概览

性能优化主要包含这几个方面:性能优化流程、性能指标采集及上报、性能监控预警平台。

  1. 性能优化流程

    选取性能指标,根据指标设定标准(时间、空间),进行投入产出(收益)评估,然后出优化清单和手段,看是否可以项目立项(赢得产品经理、后端同事支持,让优化顺利执行下去不可或缺的内容),最后是性能实践,即经过优化之后发起项目上线,并跟踪进行效果评估。

  2. 性能指标采集与上报

    把前面提到的性能指标以代码的形式分解落地,确保可以采集,然后在 SDK 封装后集合统计埋点,最后根据实际情况,制定上报策略。

  3. 性能监控预警平台

    包括性能数据处理后台和性能可视化展现前台两部分。

    其中,性能数据处理后台,主要是在性能采集数据上报到性能平台后,对数据进行预处理、数据清洗和数据计算,然后生成前台可视化所需数据。

    性能可视化展现前台包括性能展示、性能监控预警,主要是对核心数据指标进行可视化展现,对性能数据波动进行监控,对超出阈值的数据给出短信或邮件报警。

image.png

性能优化关键指标设定及标准

要确定关键的性能指标,必须满足两点:

  • 可衡量,就是可以通过代码来度量;
  • 关注以用户为中心的关键结果和真实体验。
  1. 加载

    进入页面时,页面内容的载入过程,加载缓慢严重消耗用户的耐心,会让用户离开页面。

  2. 交互性

    用户点击网站或 App 的某个功能,页面给出的回应。

  3. 视觉稳定性

    CLS(Cumulative Layout Shift),也就是布局偏移量,它是指页面从一帧切换到另外一帧时,视线中不稳定元素的偏移情况

在性能优化关键指标方面,目前业界主要集中在加载方面,特别是白屏时间和首屏时间。它们直接和用户体验相关,且相关的衡量标准已经达成共识。在采集方式上,除了手动采集之外,还可以自动化采集。而交互性和视觉稳定性关键指标,业界还在探索,没有统一的衡量标准,且必须手动采集。

性能瓶颈点:从 URL 输入到页面加载整过程分析

想要对 Web 前端进行性能优化,除了了解性能体系、关键性能指标之外,还需要了解页面加载全过程。通过这个过程,我们可以找到其中影响性能的关键点、瓶颈点,接下来才好有的放矢。

假设一个人正在上网,当他在浏览器输入 URL 并回车后,为了把 URL 解析为 IP 地址,浏览器会向 DNS 服务器发起 DNS 查询,获取 IP 地址。然后浏览器通过 IP 地址找到目标服务器,发起 TCP 三次握手和 TLS 协商,从而建立起 TCP 连接。

在建立连接后,浏览器就可以发起 HTTP 请求,而服务端接收到后,对请求进行响应。浏览器从响应结果中拿到数据,并进行解析和渲染,最后在用户面前就出现了一个网页。

以上的整个过程大致可以分为三个阶段:客户端发起请求阶段、服务端数据处理请求阶段、客户端页面渲染阶段。

客户端请求阶段的瓶颈点

本地缓存、DNS查询、HTTP 请求很容易成为影响前端性能的瓶颈点

  1. 本地缓存

    本地缓存可以让静态资源加载更快,当客户端发起一个请求时,静态资源可以直接从客户端中获取,不需要再向服务器请求。而想要让本地缓存发挥这个作用,就需要先在服务器上进行配置。

    本地缓存一般包括强缓存和协商缓存两种形式。

    强缓存是指浏览器在加载资源时,根据请求头的 expires 和 cache-control 判断是否命中客户端缓存。如果命中,则直接从缓存读取资源,不会发请求到服务器,反之还需要走完整的资源请求流程。

  2. DNS查询

    每进行一次 DNS 查询,都要经历从手机到移动信号塔,再到认证 DNS 服务器的过程。这中间需要很长的时间。

    浏览器提供了 DNS 预获取的接口,我们可以在打开浏览器或者 WebView 的同时就进行配置。这样真正请求时,DNS 域名解析可以检查一下浏览器缓存,一旦缓存命中,就不需要去 DNS 服务器查询了。

  3. HTTP请求

    HTTP 请求阶段,最大的瓶颈点来源于请求阻塞。所谓请求阻塞,就是浏览器为保证访问速度,会默认对同一域下的资源保持一定的连接数,请求过多就会进行阻塞。

    所以我们在项目之初,做一些域名规划很重要。我们可以先看看当前页面需要用到哪些域名,最关键的首屏中需要用到哪些域名,规划一下这些域名发送的顺序。除了域名规划,为了解决同域名下的阻塞问题,还可以做域名散列,通过不同的域名,增加请求并行连接数。

服务端数据处理阶段的瓶颈点

服务端数据处理阶段,是指 WebServer 接收到请求后,从数据存储层取到数据,再返回给前端的过程。

这个过程中的瓶颈点,就在于是否做了数据缓存处理、是否做了 Gip 压缩,以及是否有重定向。

  1. 数据缓存

    数据缓存分为两种:借助 Service Worker 的数据接口缓存、借助本地存储的接口缓存和CDN(Content Delivery Network,内容分发网络)

  2. 重定向

    在服务端处理阶段,重定向分为三类:服务端发挥的302重定向,META 标签实现的重定向和前端 Javasript 通过window.location 实现的重定向。

页面解析和渲染阶段的瓶颈点

所谓解析,就是 HTML 解析器把页面内容转换为 DOM 树和 CSSOM树的过程。解析完后就是渲染。主线程会计算 DOM 节点的最终样式,生成布局树。

构建 DOM 树的瓶颈点

  1. 当 HTML 标签不满足 Web 语义化时,浏览器就需要更多时间去解析 DOM 标签的含义。特别解析器是对标签的容错,比如将<br>写成了</br>,又或者表格嵌套不标准,标签层次结构复杂等。遇到这些情况时,浏览器会进行语法纠错。这就会导致页面总的解析和渲染阶段需要更长的时间,严重影响页面展示性能。
  2. DOM 节点的数量越多,构建 DOM 树的时间就会变长,进而延长解析时间,拖慢页面展示速度。
  3. <SCRIPT>标签阻塞渲染,因为无论是 DOM 或者 CSSOM 都可以被 JavaScript 所访问并修改,所以一旦在页面解析时遇到

布局中的瓶颈点

在布局阶段,浏览器会根据样式解析器给出的样式规则,来计算某个元素需要占据的空间大小和屏幕中的位置。

假设我们在页面渲染过程运行时修改了一个元素的属性,比如在电商的商品详情页加入一条广告数据。这时布局阶段受到了影响。浏览器必须检查所有其他区域的元素,然后自动重排页面,受到影响的元素需要重新绘制,最后还得合成,相当于整个渲染流程再来了一遍。

除此之外,因为浏览器每次布局计算都要作用于整个 DOM,如果元素量大,计算出所有元素的位置和尺寸会花很长的时间。所以布局阶段很容易成为性能瓶颈点。