关于lighthouse的使用的一些总结:
Lighthouse 是一个开源的自动化工具,用于改进网络应用的质量。您可以将其作为一个 Chrome 扩展程序运行,或从命令行运行。您为 Lighthouse 提供一个您要审查的网址,它将针对此页面运行一连串的测试,然后生成一个有关页面性能的报告。
这张图显示了几组数据,我们比较关心的是performance,性能。
看到现在的性能是非常不好的。
再来看另外一个:
那重点来看下performance吧:
它有6个指标:
First Contentful Paint (FCP)
第一次内容丰富的绘画(FCP)指标衡量了从页面开始加载到页面内容的任何部分呈现在屏幕上的时间。对于该指标,"内容"指的是文本、图像(包括背景图像)、svg元素或非白色canvas元素。
在上面的负载时间线中,FCP发生在第六帧中,就像呈现给屏幕的第一文本和图像元素时一样。
你会注意到,虽然部分内容已经呈现,但并非所有内容都已呈现。这是First Contentful Paint (FCP)和Largest Contentful Paint (LCP)之间的一个重要区别–LCP的目的是衡量页面的主要内容何时完成加载。
知道了概念,如何衡量FCP呢,我们可以接触的有Field tools和Lab tools
要在JavaScript中测量FCP,你可以使用Paint Timing API。下面的例子展示了如何创建一个PerformanceObserver,该PerformanceObserver监听名称为first-contentful-paint的油漆条目,并将其记录到控制台。
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
console.log('FCP candidate:', entry.startTime, entry);
}
}).observe({type: 'paint', buffered: true});
Speed Index
速度指数是Lighthouse报告中性能部分跟踪的六个指标之一。每项指标都能反映出页面加载速度的某些方面。
那么它是如何检测的呢?
速度指数衡量的是内容在页面加载过程中的视觉显示速度。Lighthouse首先会在浏览器中捕获一段页面加载的视频,并计算出各帧之间的视觉进度。然后,Lighthouse使用Speedline
Node.js模块来生成速度指数得分。
那么我们有机会提升它的性能吗?
利用Lighthouse报告中的 "Opportunities "部分来确定哪些改进对你的页面最有价值。机会越重要,对性能评分的影响就越大。例如,下面的Lighthouse截图显示,消除渲染阻塞资源将带来最大的改善。
Largest Contentful Paint (LCP)
最大内容画(LCP)指标报告了在视口中可见的最大图像或文本块的渲染时间,相对于页面首次开始加载的时间。
umulative Layout Shift (CLS)
Cumulative Layout Shift (CLS)是一种视觉稳定性的测量方法,它量化了页面内容在视觉上的移动程度。它量化了一个页面的内容在视觉上移动的程度。
简单理解就是:
CLS测量的是整个页面生命周期内发生的每一次意外布局转变的所有单个布局转变得分的总和。
布局偏移发生在可见元素从一个渲染帧到下一个渲染帧改变其位置的任何时候。关于如何计算单个布局偏移分数,请参见下文)。
https://web.dev/cls/
Total Blocking Time (TBT)
总阻塞时间(Total Blocking Time,TBT)量化了负载响应能力,测量了主线程被阻塞的时间长到足以阻止输入响应的总时间。TBT衡量的是第一次有内容的绘画(FCP)和交互时间(TTI)之间的总时间。它是TTI的配套指标,它为量化主线程活动带来了更多的细微差别,这些活动阻碍了用户与您的页面进行交互的能力。
最新评分标准
Lighthouse中的性能得分是由多个指标加权混合计算出来的,总结出一个页面的速度。6.0的性能得分公式如下。
以下是一些可以提升性能的方法列举:
passive:不会对浏览器的默认行为说No
这个修订是为了扩展新的选项,从而自定义更多的行为,目前规范中 options 对象可用的属性有三个:
addEventListener(type, listener, {
capture: false,
passive: false,
once: false
})
三个属性都是布尔类型的开关,默认值都为 false。其中 capture 属性等价于以前的 useCapture 参数;once 属性就是表明该监听器是一次性的,执行一次后就被自动 removeEventListener 掉,还没有浏览器实现它;passive 属性是本文的主角,Firefox 和 Chrome 已经实现,
很多移动端的页面都会监听 touchstart 等 touch 事件,像这样:
document.addEventListener("touchstart", function(e){
... // 浏览器不知道这里会不会有 e.preventDefault()
})
由于 touchstart 事件对象的 cancelable 属性为 true,也就是说它的默认行为可以被监听器通过 preventDefault() 方法阻止,那它的默认行为是什么呢,通常来说就是滚动当前页面(还可能是缩放页面),如果它的默认行为被阻止了,页面就必须静止不动。但浏览器无法预先知道一个监听器会不会调用 preventDefault(),它能做的只有等监听器执行完后再去执行默认行为,而监听器执行是要耗时的,有些甚至耗时很明显,这样就会导致页面卡顿。视频里也说了,即便监听器是个空函数,也会产生一定的卡顿,毕竟空函数的执行也会耗时。
视频里还说了,有 80% 的滚动事件监听器是不会阻止默认行为的,也就是说大部分情况下,浏览器是白等了。所以,passive 监听器诞生了,passive 的意思是“顺从的”,表示它不会对事件的默认行为说 no,浏览器知道了一个监听器是 passive 的,它就可以在两个线程里同时执行监听器中的 JavaScript 代码和浏览器的默认行为了。
采用高效的缓存策略提供静态资源
TTP caching can speed up your page load time on repeat visits.
Configure your server to return the Cache-Control HTTP response header:
Cache-Control: max-age=31536000
怎么验证是否使用缓存呢?
避免网络负载过大
PRPL:
- Push (or preload) the most important resources.
- Render the initial
- route as soon as possible.
- Pre-cache remaining assets. Lazy load other routes and non-critical assets.
推送(或预加载)最重要的资源。
尽快渲染初始路线。
预缓存剩余资产。
延迟加载其他路由和非关键资产。
<link rel="preload" as="style" href="css/style.css">
避免使用 document.write()
对于连接速度较慢的用户,通过 document.write()
动态注入的外部脚本可将网页加载延迟数十秒。
可以使用异步加载事件,或者将js事件放在body闭合标签之前。
图片元素没有明确的width和height
给图片元素设置宽高,避免布局突然的移位
动态的插入图片、容器的时候
CLS:Cumulative Layout Shift (CLS)
最大限度地减少主线程工作
优化第三方JavaScript,合理使用cdn缓存策略
压缩代码
减少输入的程序
使用web worker
缩短 JavaScript 执行用时
在网页字体加载期间,所有文本都保持可见状态
使用font-display 或者预加载
@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
src: local('Pacifico Regular'), local('Pacifico-Regular'), url(https://fonts.gstatic.com/s/pacifico/v12/FwZY7-Qmy14u9lezJ-6H6MmBp0u-.woff2) format('woff2');
font-display: swap;
}
我们在@font-face指令中使用font-display来加载自定义字体。这个属性可以添加以下的值:
auto:默认值。典型的浏览器字体加载的行为会发生,也就是使用自定义字体的文本会先被隐藏,直到字体加载结束才会显示。
swap:后备文本立即显示直到自定义字体加载完成后再使用自定义字体渲染文本。在大多数情况下,这就是我们所追求的效果。之前提及到的JavaScript脚本实现的功能就基本和这个是一致的。
fallback:这个可以说是auto和swap的一种折中方式。需要使用自定义字体渲染的文本会在较短的时间(100ms according to Google )不可见,如果自定义字体还没有加载结束,那么就先加载无样式的文本。一旦自定义字体加载结束,那么文本就会被正确赋予样式。
optional:效果和fallback几乎一样,都是先在极短的时间内文本不可见,然后再加载无样式的文本。不过optional选项可以让浏览器自由决定是否使用自定义字体,而这个决定很大程度上取决于浏览器的连接速度。如果速度很慢,那你的自定义字体可能就不会被使用。
移除未使用的 JavaScript
移除未使用的 JavaScript 以减少网络活动消耗的字节数据
移除阻塞渲染的资源
资源阻止了系统对您网页的首次渲染。建议以内嵌方式提供关键的 JS/CSS,并推迟提供所有非关键的 JS/样式。
使用 HTTP/2
HTTP/2 提供了许多优于 HTTP/1.1的优点,包括二进制标头、多路复用和服务器推送等。
移除未使用的 CSS
从样式表中移除无效规则并延迟加载首屏内容未使用的 CSS 可减少网络活动的无谓消耗。
建议添加 preconnect
或 dns-prefetch
资源提示,以尽早与重要的第三方来源建立连接
资源预拉取(prefetch)Prerender Preload