[TOC]

性能优化体系具体有哪些内容呢?它主要包括三部分:

  • 性能优化流程
  • 性能指标采集及上报
  • 性能监控预警平台

image.png

性能指标

一个是关注什么样的指标,一个是关键指标的设定及标准。

什么叫白屏时间呢?它指的是从输入内容回车(包括刷新、跳转等方式)后,到页面开始出现第一个字符的时间。这个过程包括 DNS 查询,建立 TCP 连接,发送首个HTTP请求(如果使用HTTPS还要介入 TLS 的验证时间),返回HTML文档,HTML文档 Head 解析完毕。它的标准时间是 300ms。

如果白屏时间过长,用户会认为我们的页面不可用,或者可用性差。如果超过一定时间(如 1s),用户注意力就会转移到其他页面。

哪些因素会导致白屏时间过长?原因有很多,有可能是 DNS 查询时间长,建立 TCP 请求链接太慢,或者是服务器处理请求速度太慢,客户端下载、解析、渲染时长过长,没有做 Gzip 压缩,缺乏本地离线化处理,等等

首屏时间=白屏时间+渲染时间
它是指从浏览器输入地址并回车后,到首屏内容渲染完毕的时间。这期间不需要滚动鼠标或者下拉页面,否则无效。

怎么理解呢?我们来看,下面是网站速度和性能优化 GTmetrix 官网的一个首屏时间示意图。从开始加载到第二帧时,这段时间是白屏时间,到第三帧时,首屏才开始加载,到第四帧结束时,这段时间是首屏时间。
image.png
在加载性能指标方面,相比于白屏时间,首屏时间更重要。

如果一个站点对时间敏感,首屏时间在 1s 内,用户感觉会很快;如果首屏时间超过 2.5s,用户就会感觉很慢。但是在 1s 内打开页面,人们对这么短的时间并不敏感,体验不出 10ms 和 50ms 有什么差别。

首屏时间可以拆分为白屏时间、数据接口响应时间、图片加载资源等。 白屏时间前面已经提到了,数据接口响应时间可以直接从后端服务中获取,不需要前端再重复计算,我们只需取完放在性能平台即可。最后的图片资源需要我们单独采集。

以上就是前端性能体系中的关键指标,还有一些不太重要的指标,如卡顿、完全加载时间、资源加载时间等

从 URL 输入到页面加载整过程分析

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

客户端请求阶段的瓶颈点

客户端发起请求阶段,是指用户在浏览器输入 URL,经过本地缓存确认是否已经存在这个网站,如果没有,接着会由 DNS 查询从域名服务器获取这个 IP 地址,接下来就是客户端通过 TCP 的三次握手和TLS协商向服务器发起 HTTP 请求建立连接的过程。

在这个过程中,本地缓存、DNS查询、HTTP 请求很容易成为影响前端性能的瓶颈点。

本地缓存

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

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

协商缓存是指,浏览器会先发送一个请求到服务器,通过 last-modified 和 etag 验证资源是否命中客户端缓存。如果命中,服务器会将这个请求返回,但不会返回这个资源的数据,依然是从缓存中读取资源。 如果没有命中,无论是资源过期或者没有相关资源,都需要向服务器发起请求,等待服务器返回这个资源。

DNS 查询

DNS 之所以会成为前端性能瓶颈点,是因为每进行一次 DNS 查询,都要经历从手机到移动信号塔,再到认证 DNS 服务器的过程。这中间需要很长的时间。但用户是不想等待的。

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

HTTP 请求

浏览器同域名的连接数限制是多少呢?一般是 6 个。如果当前请求书多于 6 个,只能 6 个并发

所以我们在项目之初,做一些域名规划很重要。我们可以先看看当前页面需要用到哪些域名,最关键的首屏中需要用到哪些域名,规划一下这些域名发送的顺序。

除了域名规划,为了解决同域名下的阻塞问题,还可以做域名散列,通过不同的域名,增加请求并行连接数。常见做法是,将静态服务器地址 pic.google.com,做成支持 pic0-5 的 6 个域名,每次请求时随机选一个域名地址进行请求。因为有 6 个域名同时可用,最多可以并行 36 个连接。当然,这个域名个数不是越多越好,太分散的话,又会涉及多域名之间无法缓存的问题。

服务端数据处理阶段的瓶颈点
这个过程中的瓶颈点,就在于是否做了数据缓存处理、是否做了 Gip 压缩,以及是否有重定向。
其中,Gzip 压缩是一种压缩技术,服务器端通过使用 Gzip,传输到浏览器端的文本类资源(有别于图片等二进制等资源)的大小可以变为原来的 1/3 左右。因此通过 Gzip 压缩,资源的下载速度会快很多,能大大提升页面的展示速度。

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

其中 Service Worker 是浏览器的一个高级属性,本质上是一个请求代理层,它存在的目的就是拦截和处理网络数据请求。如果没有 Service Worker,请求每次直接落到 WebServer 上,需要走一次后端数据存取链路的流程,这会延长页面打开时间。

借助本次存储的接口缓存是指,在一些对数据时效性要求不高的页面,第一次请求到数据后,程序将数据存储到本地存储(store 或者 localStorage、甚至客户端本身的存储),下一次请求的时候,先去缓存里面取将取数据,如果没有的话,再向服务器发起请求。

所谓 CDN,它的基本思路是,通过在网络各处放置节点服务器,构造一个智能虚拟网络,将用户的请求导向离用户最近的服务节点上。

为什么数据缓存会成为性能瓶颈点呢?这是因为每请求一次数据接口,需要从客户端到后端服务器,再到更后端的数据存储层,一层一层返回数据,最后再给到客户端,耗时很长,如果能够减少一次这个请求,为首屏时间争取了宝贵的时间。

重定向
所谓重定向,是指网站资源(如表单,整个站点等)迁移到其他位置后,用户访问站点时,程序自动将用户请求从一个页面转移到另外一个页面的过程。

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

它们都会引发新的 DNS 查询,导致新的 TCP 三次握手和 TLS 协商,以及产生新的 HTTP 请求。而这些都会导致请求过程中更多的时间,进而影响前端性能。所以重定向也是一个需要注意的性能瓶颈点,在优化的时候需要注意。

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

在页面加载过程中,当前服务端对数据加工聚合处理后,客户端拿到数据,接下来就会进入解析和渲染阶段。

所谓解析,就是 HTML 解析器把页面内容转换为 DOM 树和 CSSOM树的过程。

什么叫 DOM 树呢?DOM 树全称为 Document Object Model 即文档对象模型,它描述了标签之间的层次和结构。HTML 解析器通过词法分析获得开始和结束标签,生成相应的节点和创建节点之间的父子关系结构,直到完成 DOM 树的创建。

而 CSSOM 树,即 CSS 对象模型。主要描述样式集的层次和结构,HTML 解析器遇到内联的 style 标签时,会触发 CSS 解析器对样式内容进行解析,与上面解析器解析 HTML 过程类似,CSS 解析器遍历其中每个规则,将 CSS 规则解析浏览器可解析和处理的样式集合,最终结合浏览器里面的默认样式,汇总形成具有父子关系的 CSSOM 树。

解析完后就是渲染。主线程会计算 DOM 节点的最终样式,生成布局树。布局树会记录参与页面布局的节点和样式。完成布局后,紧跟着就是绘制。

绘制就是把各个节点绘制到屏幕上的过程,绘制结果以层的方式保存。当文档中各个部分以不同的层绘制时,相互重叠时,就必须进行合成,以确保他们可以以正确的顺序绘制和展示。

以上就是解析和渲染阶段,这个阶段流程环节多,逻辑复杂,瓶颈点也多,比如,DOM 树构建过程,CSSOM 树生成阶段,重排和重绘过程等。

构建 DOM 树的瓶颈点

解析器构建 DOM 树的过程中,有三点会严重影响前端性能。
一个是当 HTML 标签不满足 Web 语义化时,浏览器就需要更多时间去解析 DOM 标签的含义。特别解析器是对标签的容错,比如将
写成了
,又或者表格嵌套不标准,标签层次结构复杂等。遇到这些情况时,浏览器会进行语法纠错。这就会导致页面总的解析和渲染阶段需要更长的时间,严重影响页面展示性能。

另一个是 DOM 节点的数量越多,构建 DOM 树的时间就会变长,进而延长解析时间,拖慢页面展示速度。

最后一个是文档中包含