前言
前端性能优化,一直是前端开发者绕不过的一个话题, 前端网页如果存在性能问题,对于企业业务来讲,影响很大。
一是加载慢,用户会很容易跳出。

二是搜索引擎会判断为低质网页,会进行降权处理。

本文会系统的聊一下性能优化的思路,具体的实践会专门写一篇文章来说明。
性能分析
性能指标
首屏
First Paint
FP代表浏览器第一次在页面上绘制的时间,这个时间仅仅是指开始绘制的时间,但是未必真的绘制了什么有效的内容。
First Contentful Paint
FCP代表浏览器第一次绘制出DOM元素(如文字、input标签等)的时间。FP可能和FCP是同一个时间,也可能早于FCP,但一般来说两者的差距不会太大。
First Meaningful Paint
FMP,第一次有意义的绘制是一个主观的指标,在一般情况下,首屏指的主要是FMP。FP和FCP虽然都可以根据一个确定的规则测算出一个客观的指标值,但开始渲染和渲染第一个元素对于用户来说未必有意义。更主要的是,仅仅依靠这些指标往往容易导致度量的结果失真。
最简单的方案就是记录关键逻辑的时间点。关键逻辑的时间点包括页面关键组件渲染完成的时间、API加载等逻辑完成的时间。可以手动使用JavaScript记录时间点,从而将其作为FMP的时间。
Time to Interactive(TTI,可交互时间)
流畅度
Frames Per Second
FPS是打游戏的同学应该很熟悉的一个概念帧率, 既 “是每秒渲染的帧数”。
每秒60帧是人眼感觉比较流畅的的帧数。同时也是目前显示器最常见的帧率。因此1000ms / 60 = 16.7ms, 60Hz刷新率的情况下,每一帧不于16ms就不会感觉到卡顿。
根据wikipedia
人类视觉的时间敏感性和分辨率根据视觉刺激的类型和特征而变化,并且在个体之间是不同的。由于人类眼睛的特殊生理结构,如果所看画面之帧率高于每秒约10至12张的时候,就会认为是连贯的,此现象称之为视觉暂留。这也就是为什么电影胶片是一格一格拍摄出来,但是借由快速播放,能让画面看起来是连续的。
当调制光(如计算机显示器)闪烁的频率高于约50Hz至60Hz时,主流研究把在此状态下的调制光认定为稳定状态。这种对调制光稳定感知,被称为闪烁融合阈值。然而,当调制光不均匀且包含图像时,所需要的闪烁融合阈值要高得多。如果人需要在一连串不同图像中识别指定图像,图像出现时间仅需13毫秒。视觉残留有时会导致非常短暂的单毫秒视觉刺激,其感知持续时间在100毫秒至400毫秒之间。多个短暂刺激有时也能合成单个刺激,例如在10毫秒的绿色闪光后出现10毫秒的红色闪光,会被感知为单一的黄色闪光。
--- wikipedia
核心Web指标
首屏和流畅度对于大部分场景来说,可能并没有一个明确要优化的对象,google 官方给出了 核心Web指标(Core Web Vitals)
Largest Contentful Paint
首屏视图中最大的元素的渲染时间, 跟FCP区别,举一个特殊的场景,比如页面有全局的loading,loading文字已经绘制了内容。在FCP指标下是达成的,但这对于用户来说,并不是首屏。这种场景来说LCP才是更复合用户体验的首屏时间。
First Input Delay (2024.3被INP替代)
首次交互延迟,是从用户首次和网站进行交互到响应该事件的实际延时的时间。
Cumulative Layout Shift
页面产生的连续累计布局偏移分数, 主要是指异步数据加载导致的整体布局的变化。
Interaction to Next Paint
与下一次绘制的交互, 用户交互(如点击或按键)后到下次在页面上看到视觉更新之间经过的时间
FID仅考虑用户与页面的首次交互,而且是仅计算Input Delay, 也就是上图的灰色部分。INP 是计算所有的交互事件直到浏览器绘制下一帧(这也是名称由来)。这样的计算方式更符合用户的交互操作。所以chrome 最终用INP代替FID
分析工具
Chrome Devtools
Devtools是前端开发中使用频率最多的调试工具
Network
Network面板是DevTools最常用的面板之一, 平时开发中可能看xhr接口请求,响应比较多。在性能分析的时候可以用来分析资源加载情况, 排队队列等情况。
Performance
Performance面板是我们最常用的性能分析工具。Performance基本能查看到性能指标的各项数据。
Netwwork (网络) 对应流畅度数据,
Frames(帧) 对应流畅度数据,
Timings(计时) 对应FP、FCP、DCL、LCP、onLoad
Layout Shifts 对应CLS
Main
Lighthouse
Lighthouse 是一种可帮助你提高网页质量的开源自动化工具, 他不仅包含了性能,还会从更多维度来评估网页质量(无障碍, 最佳实践, SEO, PWA)。
其中性能模块,也提供了上述性能指标的测试结果, 同时诊断结果也会提供优化建议。

Performance API
Devtools 更适用于开发环境,在开发机上进行调试,但是开发机往往具有较高的硬件配置,以及稳定的软件运行环境,无法全面的反应网页在用户设备上性能状况。因此Performance API 有更广泛的适用 场景,受限于用户设备的限制,无法适用Devtools来测试性能。Performance API 就可以很方便的帮我们记录并收集性能指标数据,为我们分析不同用户不同设备性能瓶颈提供数据支撑。
Performance API 主要包含以下模块检测
- 页面导航:记录页面加载重定向、连接、握手、DOM事件等等
- 资源加载:记录资源加载,比如图像、CSS、脚本以及Ajax调用
- 绘制指标:记录浏览器渲染信息
- 自定义:记录任意的应用处理时间,来找到运行慢的函数。
性能优化
网络资源优化
网络资源优化是一个比较常见,最容易见效的一个优化手段。
资源压缩
资源的压缩想在每个项目里面应该都有做,依托现代化的打包工具webpack,esbuild,rollup等,都支持资源压缩。资源经过压缩后以及开启GZIP后,在网络传输中,传输时间会变短,从而加快页面加载速度。
最终的目的是减少资源体积。
减少请求数量
减少请求数量和按需加载是一个平衡的过程。以webpack为例,如果不进行配置,会将所有的静态资源都通过一个请求来获取,这样似乎满足了我们的要求,但是实际上,对于用户来说,这些资源之间是相互独立的,如果这些资源之间有依赖,那么就无法同时加载,从而导 致页面加载时间变长。
因此,我们可以通过按需加载的方式,将一些依赖的资源,比如图片、css、js等,在用户需要时才进行加载,从而减少请求数量。
HTTP协议与请求数量
HTTP协议的历史就不在赘述,从我的视角来看,从业后基本就是HTTP 1.1的天下了。
HTTP/1.1对于并发有一定的限制,一个连接只能发起一个请求,然后不同的浏览器对于并发的连接数有一定限制,比如我们常见的chrome是6个并发。因此我们单个资源的体积很小但是数量很大,加载资源时一定会排队造成阻塞。远古时代的雪碧图, iconfont,新时期的小图标base64编码,symbol等都一定程度上是解决这个问题的, 另外并发是针对域名的,所以还有一些开发者会使用讲资源部署到不同的域名下,从而规避这个问题。
SPDY是Google 2010 年发布的,为了解决这个问题SPDY支持了多路复用,即单一的TCP连接可以同时发送多个请求(理论上无限制),从而解决了排队问题。除此外还有请求优先级,压缩HTTP请求头,服务器推送等,Google 提出的目标是提升50%的web加载速度
HTTP/2于2015.5正式发布,吸收了SPDY, 主流浏览器于2015年底支持了该协议,所以有条件的建议大家升级为HTTP/2
HTTP/3 于2022/6 发布,优化了多路复用的队头阻塞问题,对于稳定性要求较高的可以再观望观望。
