这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战
前言
性能优化问题是区分一个前端工程师能力的重要指标,一个不会性能优化的工程师注定不会做出一个优秀的产品,因为任何一款优秀的产品必然是经过精细打磨的产品,而性能优化就是这打磨的过程,无论是在实际工作中还是面试中性能优化问题都是面试必考的问题,下面让我们来一起解决这个问题吧~
优化思路
当我们在浏览器地址栏上输入URL到页面显示出结果的时候,我们都知道时间主要消耗在了网络传输和页面渲染上,因此我们主要从这两个方面出发进行性能优化。
网络传输性能优化
1. 使用HTTP2
HTTP2相对于HTTP1进行了下面的优化:
- 二进制分帧层
- 多路复用
- 首部压缩
- 请求优先级
- 服务器推送
- 流量控制
2. 资源打包压缩
资源打包压缩主要是通过webpack压缩以下内容:
- 压缩JS代码:通过webpack的production模式压缩JS代码。
- 压缩HTML代码:使用html-webpack-plugin的minify进行压缩。
- 压缩CSS代码:使用cssnano压缩css,在postcss.config.js中进行配置。
3. 图片资源优化
在网络传输中真正占用大量网络资源的不是文件而是图片,如果对图片进行了优化,可以看到立竿见影的效果。主要优化措施如下:
- 在html中尽量不要放图片。
- 使用雪碧图:雪碧图可以减少请求的次数。
- 使用字体图标:字体图片能够像图片一样工作,但是资源占用和图片请求比起来小很多。
- 使用webp:webp格式的图片相对根据国家节省网络带宽。
4. 使用CDN
CDN指的是在网络不同地点部署节点服务器,将源站内容分发至所有CDN节点,使得用户可以就近获得所需内容。CDN提高了网站的响应速度、降低了延迟。
5. 使用预加载
当一个页面加载时,可能会加载很多第三方资源,但是这些资源的优先级是不同的,一些重要资源需要提前进行获取,因此我们可以使用link标签来进行DNS预解析、预加载、预渲染来管理页面资源的加载。
6. 减少DNS查找
尽量将资源放在同一域名下面,因为域名越少,DNS查询就会越少。
7. 发送请求时使用防抖和节流策略
防抖节流可以避免短时间内发送过多的重复请求。
页面渲染性能优化
1. 减少重排和重绘的发生
- 重排:指的是元素布局发生修改,导致页面重新排列。
- 重绘:所有对元素的视觉表现属性的修改,都会引发重绘。
重排和重绘都会影响性能,要想提高网页性能尽可能降低重排和重绘的频率。重排是由CPU处理的,而重绘是由GPU处理的,GPU的处理效率要相对更高,重排一定发生重绘,但是重绘不一定引起重排,所以要尽可能的降低重排和重绘的发生。
2. DOM元素离线更新
当对DOM元素进行操作的时候,尽量使用documentFragment对象进行离线操作,待元素组装完成之后再一次插入页面。
3. 避免CSS、JS阻塞
CSS资源优于JS资源的引入,JS应当尽量少影响DOM的构建。
性能优化指标
1. 三大核心指标 (Core Web Vitals) —— 必考点
-
LCP (Largest Contentful Paint) - 加载体验
- 含义:视口内最大内容(图或文)渲染的时间。
- 标准:2.5秒 以内为优秀。
- 优化:压缩图片、CDN 加速、预加载关键资源、优化服务端响应。
-
INP (Interaction to Next Paint) - 交互体验 (重点!新指标)
- 含义:用户操作(点击/按键)到页面下一帧绘制的整体耗时。
- 变化:已取代 FID。FID 只看“延迟”,INP 看“全过程”(输入延迟+处理耗时+渲染耗时)。
- 标准:200毫秒 以内为优秀。
- 优化:减少主线程阻塞(Long Task),拆分复杂 JS 任务。
-
CLS (Cumulative Layout Shift) - 视觉稳定性
- 含义:页面加载时元素意外位移的程度(防止误触)。
- 标准:0.1 以下为优秀。
- 优化:给图片/视频设置固定宽高 (
width/height或aspect-ratio),避免动态插入内容顶开布局。
2. 辅助指标 —— 加分项
- FCP (First Contentful Paint) :首屏任何内容渲染的时间(告诉用户页面“活着”)。
- TTFB (Time to First Byte) :网络/后端响应时间(如果这个慢,前端再快也没用)。
3. 数据采集方式 —— 展示专业度
-
实验室数据 (Lab Data) :
- 工具:Lighthouse / Chrome DevTools。
- 作用:开发环境调试,环境稳定但不代表真实用户。
-
真实用户数据 (RUM / Field Data) :
- 工具:
web-vitals库 /PerformanceObserverAPI。 - 作用:收集线上真实用户的体验,受设备和网络影响,更有参考价值。
- 工具:
面试“万金油”话术总结:
“我现在主要关注 Google 的 Core Web Vitals。
LCP 看加载快不快(目标 2.5s);
INP 看交互卡不卡(目标 200ms,它比旧的 FID 更全面);
CLS 看页面抖不抖(目标 0.1)。
另外,我会结合 Lighthouse 做本地调试,上线后通过 埋点 监控真实用户的性能数据。”
1. 首次绘制时间FP(First Paint,也叫白屏时间)
这个指标用于记录页面第一次绘制像素的时间,例如页面的背景色,这个时间的标准时间是300毫秒,如果白屏时间过长,可能导致用户没有耐心,将注意力转移到其他页面。
2. 首次内容绘制时间(FCP: First contentful paint,也叫首屏时间)
它指的是从浏览器输入地址并回车后,到首屏内容渲染完毕的时间。
3. 最大内容绘制时间(LCP)
用于记录视窗内最大的元素绘制时间。
4. 首次输入延迟时间(FID)
首次输入延迟,记录了首次内容绘制时间到可以完全交互时间之间响应的一个延迟时间。
5. 可交互时间(TTI)
用户第一次完全达到可交互状态的时间点,此时的浏览器已经可以持续的响应用户的输入。
6. 总阻塞时间(TBT)
这个时间记录了首次内容绘制的时间到可完全交互时间之间的阻塞时间的总和。
7. 累积布局偏移时间(CLS)
这个时间记录了页面上的非预期的位移波动时间。
测量各种指标的工具
- 浏览器端的web vitals插件,打开网页的时候可以在插件上显示出上面的一些时间。
- chrome自带的lighthouse进行统计。
- 还可以使用PageSpeed Insights去看下线上的性能情况。
经典问题
RQ1:首屏加载如何优化?
主要方法包括以下步骤:
- 动态加载路由
配置路由的时候,以函数的形式加载路由,只有在解析给定的路由时,才会加载路由。
- 合理使用缓存
设置强缓存、协商缓存、localstorage等。
- UI框架按需加载
不要引入整个UI库,尽量进行按需加载。
- 避免重复加载组件
可以使用webpack将多次使用的包抽离出来,放入公共依赖文件,避免重复加载组件。
- 压缩图片资源
雪碧图、字体图标、webp等。
-
开启Gzip压缩
-
使用SSR服务端渲染
组件或页面通过服务器生成html字符串,再发送到浏览器。