Navigation Timing API
可以使用 window.performance.timing 的各种字段来看看到底哪个环节花的时间最长。
<script>
javascript:(() => {
var perfData = window.performance.timing;
var pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;
console.log('当前页面加载耗时:', pageLoadTime);
})();
</script>
问:有两位同学,分别使用SVG和canvas进行绘图,怎么证明他们俩的性能谁更高呢?
canvas的核心是降低DOM数量,它就1个,肯定比SVG少的。那只要计算一下 domComplete 和 domLoading之间的时间,即可看出差距。
那么现在我得到了一组数据,那我应该如何优化,或者如何评判我的网页是否需要优化呢?
Core Web Vitals 网页性能核心指标
Google提出 => 可衡量的、能够反映真实用户体验的:加载、交互、视觉稳定性
LCP - Largest Contentful Paint 衡量装载性能
前2.5s内进行最大内容的渲染
a. 最大内容包含了哪些?
- <img>元素
- <video>元素
- <svg>元素
- 通过url()函数加载的背景图片
- 包含了文本整体节点的块级元素
b. LCP值低下的原因
- 服务器响应慢:源头慢。
- 阻断渲染的JS:JS线程和渲染线程是会相互阻塞的,JS如果跑太久了,是会阻断渲染的。
- 资源加载慢:CDN慢,看是不是文件体积,CDN位置等问题。
- 客户端渲染机器性能影响:如果是ToB or ToG 的服务,可能需要写一个说明书,告知对方最小的机器性能应该是多少,如果是开发游戏,也应该写上最低支持的处理器是多少。
c. 针对性地改造
- 服务器优化:缓存代理,强缓存和协商缓存。
- JS进行拆分 or 后置:添加loading或骨架屏;大数据量,计算密集型的地方可以用 webassembly 用编译型语言去弥补js的遗憾。
- 对资源进行优化 JPG WEBP: 降低资源大小(提供了这么多种图片格式,就是为了应对不同的场景,主图用高清,图标用有损,选对资源);CDN。
- 利用工程化方式
- HTML进行动态组装:使用webpack动态生成HTML
- 代码压缩
- 首屏优化:按需加载对应页面的组件,设置不同的chunk。
- worker:闲置过程中,调用worker偷偷运算。
- 服务端渲染:其实就是把压力给到服务端,需要衡量,一部分在前端渲染,一部分在后端渲染,也叫同构。
FID - First Input Delay 衡量交互性
页面渲染完成后,首次输入的延迟应该小于100ms
a. 减少后置任务对交互行为的阻塞影响
- 延迟不需要紧急处理的JS逻辑。
- 减少不必要的 polyfill(减少兼容性校验)
b. 分解耗时的任务
- 任何阻塞主线程超过50ms:长任务。比如为啥你会用到 $nexttick?
- 长任务优选拆分成较小的异步任务、微任务。就像之前的时间管理器,同一帧只处理10个回调,再多就等到下一秒再说。
c. worker
CLS - cumulative layout shift 衡量视觉稳定性
页面应当保持在小于0.1,布局的移动可能发生在元素的前一帧到下一帧的改变位置,比如CSS没加载完,只能看到单纯的标签,等CSS加载完了,样式就出来了,但也很跳,给用户不稳定的感觉。
- 不要去使用无尺寸元素,默认宽高与最终一致:如图片即使没加载出来,也要给个限定宽高,一定程度上避免了重排。
- 减少页面内容的插入,改为替换
- 字体控制,比如微软雅黑,苹果的字体,其一个字的大小宽度都不太一样,造成的整体宽度不太一样,所以最好就是统一一个字体,切身体会。
CWV插件:Core Web Vitals Annotations
这是Google开发的官方插件。
优化的另一种可能 bigpipe,将页面分解成若干的pagelet
服务前端接收来自客户端的http请求,然后服务器去获取数据,并在一个中间层(如Node)组装HTML,把页面直接响应给客户端。像SSR,也不像SSR。像微前端,也不像微前端。