一、性能指标
聊聊前端性能指标那些事儿 - 掘金 (juejin.cn)
1、首次内容绘制 FCP(First Contenful Paint) 占比10%
1.1、概念
测量页面从开始加载到页面内容(文本、图片、背景图、svg 元素或非白色 canvas 元素)的任何部分在屏幕上完成渲染的时间
1.2、性能值
首次内容绘制完成渲染时间应控制在 **1.8s **以内
1.3、优化方法
(1)消除阻塞渲染的资源。有 media="all" 属性被认为是渲染阻塞
(2)缩小 CSS 体积,从写法上压缩CSS,移除未使用的 CSS
(3)
(4)
(5)
(6)
(7)
2、SI(Speed Index) 占比10%
2.1、概念
页面加载期间内容以视觉方式显示的速度,也就是就是网页从有东西到完全显示内容的可见填充速度
2.2、性能值
2.3、优化方法
(1)减少主线程工作
(2)减少 JavaScript 执行时间
(3)确保文本在 webfont 加载期间保持可见
3、最大(最有意义)内容绘制 LCP(Largest Contentful Paint) 占比25%
3.1、概念
根据页面首次开始加载的时间点来报告可视区域内可见的最大图像或者文本块完成渲染的相对时间。
元素大小是指用户在可视区域内可见的大小,如果元素有延伸到可视区域外,或者元素被裁剪或包含不可见的溢出,这些部分不计入元素大小。一个元素只有在渲染完成后对用户可见后才能视为最大内容元素
对于图像元素的大小,指标会对比可见尺寸与原始尺寸,取尺寸小者为准;例如双倍图以可见尺寸为准,拉伸放大图则以原始尺寸为准;
对于文本元素,元素的大小为文本节点的大小(包含所有文本节点的最小矩形)
所有元素通过 CSS 设置的任何边距、填充或边框都不在考量范围内。另外如果设置了满屏背景图,但屏幕可视区域内有占比较大的元素(浮在背景图上的元素),导致背景图暴漏可视范围较小,那么最大内容会选择可视区域内最大元素
3.2、性能值
LCP <= 2.5s 合格 2.5s < LCP <= 4s 需要优化 LCP > 4s 劣质
3.3、考量元素
内嵌在元素内的元素
video 元素
通过 url()函数加载的带有背景图像的元素
带有文本或其他行内元素文本的块级元素
3.4、影响因素
(1)对元素大小或位置修改不会生成新的 LCP 候选对象,只有元素在可视区域内的初始大小和位置会被纳入考量范围
(2)最初在可视范围内渲染,然后被移除可视区域外的元素仍将报告他在可视区域内的初始大小
(3)而在屏幕可视范围外渲染完成,过度到屏幕上的元素则不做报告
3.5、优化方法
(1)服务器影响速度
- 优化服务器性能
- 将用户路由到附近的 CDN
- 缓存资源
- 优先使用缓存提供 HTML 页面
- 尽早建立第三方链接
- 使用签名交换
(2)阻塞渲染的js和css
脚本跟样式都是阻塞渲染的资源,这些资源都会导致 FCP 延迟,从而导致 LCP 延迟。所以延迟加载非必要的 JS 和 CSS ,从而提高网页主要内容加载速度。
对于css:
- 消减 CSS : 删除 CSS 中的空格、换行、缩进、注释等字符
- 延迟加载非关键 CSS : 将初始渲染时不需要的 CSS 提取到一个文件,进行异步加载
- 内联关键 CSS : 把首屏内容的关键 CSS 直接包在 中,将 CSS 内联; Critters 是一个 webpack 插件,能够内联关键 CSS 并对其余部分进行懒加载
对于js:
- 消减压缩 JavaScript 文件
- 延迟加载未使用的 JavaScript 文件
- 最大限度的减少未使用的 polyfill
(3)缓慢的资源加载速度
- 优化图片: 压缩图片,使用 webp 格式,图片资源上传 CDN ;能用代码实现尽量不使用图片
- 预加载重要资源: 使用 提高优先级进行下载和缓存
- 压缩文本文件: Gzip、Brotli (google 出版)
- 基于网络连接交付不同资产(自适应服务): navigator.connection.effectiveType (有效连接类型 4G), navigator.connection.saveData (启用/禁用数据保护程序), navigator.hardwareConcurrency (cpu 核心数), navigator.deviceMemory (设备内存)
- 缓存资源: service woker 在 worker 上下文中运行: 因此它没有 DOM 访问权限,并且是运行在不同线程上,因此它是非阻塞的
(4)客户端渲染
- 最小化关键 JavaScript : 精简 JavaScript , 延迟加载未使用的 JavaScript , 最大限度减少未使用的 polyfill
- 使用服务端渲染: 用服务器将主要内容首先在服务器渲染为 HTML , 客户端将所有 JavaScript 及所需数据"水合"到相同的 DOM 内容中
- 使用预渲染: 使用无头浏览器,提前搭建每个路由的静态 HTML 文件,然后将这些文件与应用程序所需的 JavaScript 包一起运送
4、总阻塞时间 TBT(Total Blocking Time) 占比30%
4.1、概念
页面被阻塞响应用户交互的总时间。
TBT = LCP (首次最大内容绘制)和可交互时间之间所有长时间任务的阻塞部分之和。
超过 50 毫秒的任务即为长任务。 超出 50 毫秒的时间量为阻塞部分。
4.2、性能值
4.3、优化方法
- 减少不必要的 JavaScript 加载、解析或执行。减少 JavaScript 负载、删除未使用的代码或有效加载第三方 JavaScript
- 减少低效的 JavaScript 语句,如直接操作dom的语句document.querySelectorAll('a')
5、累计布局偏移 CLS(Cumulative Layout Shift) 占比25%
5.1、概念
整个页面声明周期内发生的所有意外布局偏移中最大一连串的布局偏移分数。
页面内容的意外偏移大多是由于异步资源加载,或者动态添加 DOM 元素到页面现有内容上方导致的。罪魁祸首可能是未知尺寸的图像或视频、实际渲染后比后备字体更大或更小的字体等。
只有当现有元素的起始位置发生变更时才算做布局偏移。如果将新元素添加到 DOM 或是现有元素更改大小,则不算做布局偏移。只有当元素的变更会导致其他可见元素的起始位置发生变化,才叫偏移。
5.2、性能值
布局偏移分数 = 影响分数 x 距离分数
5.3、产生原因
- 无尺寸的图片
- 无尺寸的广告,嵌入和 iframe
- 动态注入的内容
- 导致不可见文本闪烁(FOIT)、无样式文本闪烁(FOUT)的网络字体
- 在更新 DOM 之前等待网络响应的操作
5.4、优化方法
- 在图片和视频元素上包含尺寸属性
- 非用户交互响应的情况下,都不要在现有的内容上方插入其他内容
- 首选转换动画,而不是触发布局偏移的属性动画
二、优化方式分类
前端性能优化之雅虎35条军规 - 掘金 (juejin.cn)
1、页面内容
1.1、减少http请求次数
(1)服务器端cdn自动合并js/css文件,把所有脚本放在一个文件
(2)用雪碧图展示图片
(3)
1.2、减少dns查询
减少不同的主机名可减少DNS查找
1.3、避免重定向
URL 末尾应该添加
/
1.4、缓存Ajax请求
给资源的Ajax URL里添加一个表明用户资源最后修改时间的时间戳,之前的资源就可以从缓存中读出
1.5、延迟加载
1.6、预加载
无条件预先加载:页面加载完成(load)后,马上获取其他资源。
有条件预先加载:根据用户行为预判用户去向,预载相关资源。
有「阴谋」的预先加载:页面即将上线新版前预先加载新版内容。
1.7、减少dom元素数量
少用表格布局
少用div包裹
能通过伪元素实现的功能,就没必要添加额外元素,如清除浮动
1.8、划分内容到不同域名
浏览器一般会限制每个域的并行线程(一般为6个,甚至更少),使用不同的域名可以最大化下载线程,但注意保持在2-4个域名内,以避免DNS查询损耗
1.9、减少iframe的使用
<iframe>
的优点:
- 可以用来加载速度较慢的第三方资源,如广告、徽章;
- 可用作安全沙箱;
- 可以并行下载脚本。
<iframe>
的缺点:
- 加载代价昂贵,即使是空的页面;
- 阻塞页面 load 事件触发;
- 缺乏语义
1.10、避免404错误
1.11、组件异步加载
方式1. import懒加载
() => import('@/pages/xxx.vue')
方式2. 使用require
resolve => require(['@/pages/xxx.vue'], resolve),
1.12、路由懒加载
//routes
{
path: '/index',
name: 'index',
component: () => import('@view/xxx.vue'),
//或者 component: require(['@/view/xxx.vue'], resolve),
meta: { title: '首页' }
}
1.13、web worker
为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程
2、图片
2.1、优化图片
把gif转换到png,在png上运行pngcrush
2.2、优化雪碧图
水平排列雪碧图
2.3、不在html中缩放图片
不使用width、height缩放图片
2.4、使用体积小、可缓存的favicon.ico
确保图标存在、尺寸尽量小、设置较长过期时间
2.5、懒加载
前端图片渲染性能优化与实践 — 图片懒加载 - 掘金 (juejin.cn)
- 给所有需要展示的 img 标签添加自定义属性: data-src ,同时不要设置 src 属性,data-src的值为图片url。
- 当页面加载完后,我们需要获取所有需要懒加载的图片的元素集合,判断是否在可视区域,如果是在可视区域的话,再重新设置元素的src属性值为真正图片的地址。
- 可视化区域的判断:是通过获取元素的getBoundingClientRect属性的top值和页面的clientHeight进行对比,如果top值小于clientHeight,则说明元素出现在可视区域之内。
- 当用户滚动窗口的时候,此时应该通过每个元素的BoundingClientRect属性来判断元素是否出现在可视区域内,如果在可视区域内,就渲染图片展示在可是区域内
3、css
3.1、style放在head里
3.2、不用css表达式
3.3、用<link>代替@import
对于IE某些版本,@import的行为和放在页面底部一样
4、js
4.1、script放在页面底部
可以考虑使用defer、async属性
4.2、使用外部js和css
外部JavaScript和CSS文件可以被浏览器缓存,在不同页面间重复使用
4.3、压缩js和css
4.4、移除重复脚本
4.5、减少dom操作
4.6、使用高效的时间处理
减少绑定事件监听的节点
5、服务端
5.1、使用cdn
5.2、静态内容添加expires响应头,设置为将来很远的时间
5.3、动态内容添加cache-control响应头,让浏览器有条件地发起请求
5.4、启动gzip4
可以压缩响应大小,可以压缩文件
请求头为Accept-Encoding
5.5、配置etag
ETags可以提供一种实体验证机制
5.6、尽早输出缓冲
使用PHP中的flush()函数,可以发送部分已经准备好的 HTML到浏览器,以便服务器还在忙于处理剩余页面时,浏览器可以提前开始获取资源
可以考虑在
</head>
之后输出一次缓冲
5.7、Ajax请求使用get方法
因为get只用一个tcp数据包
5.8、避免图片src为空
src即使为空,浏览器还是会向服务器发http请求
6、cookie
6.1、减少cookie大小
去除不必要的 Cookie
尽量压缩 Cookie 大小
注意设置 Cookie 的 domain 级别,如无必要,不要影响到 sub-domain
设置合适的过期时间
6.2、静态资源使用无cookie域名
把它们放在使用二级域名或者专门域名的无Cookie服务器
7、移动端
7.1、保证组件大小小于25k
7.2、打包内容为分段文档
8、webpack打包优化
2023 前端性能优化清单 - 掘金 (juejin.cn)
8.1、resolve.alias
通过别名来将原导入路径映射成一个新的导入路径,可以减少查找过程
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
8.2、resolve.extensions
尽可能的带上后缀,从而可以避免寻找过程
resolve: {
extensions: ['.js', '.vue', '.json'],
}
8.3、缩小loader范围
使用include和except来缩小loader执行范围
8.4、代码分包 split chunks
8.5、tree shaking
9、vite打包优化
2023 前端性能优化清单 - 掘金 (juejin.cn)
9.1、9.2同8.1、8.2
9.3、关闭一些配置项
build: {
terserOptions: {
compress: {
//生产环境时移除console
drop_console: true,
drop_debugger: true,
},
},
//关闭文件计算
reportCompressedSize: false,
//关闭生成map文件 可以达到缩小打包体积
sourcemap: false, // 这个生产环境一定要关闭,不然打包的产物会很大
}
版权归原作者 Kw_Chng 所有, 如有侵权,请联系我们删除。