原副标题:谈谈后端测试方法这些事
译者:天猫信息技术 郝梁
序言:做为 C 端后端研制,除攻下销售业务症结之外,也要有更微细的人格最终目标,那是操控性强化。这事说叶黄杨,说小也非常大,但技术难度当然不通常,所牵涉的覆盖范围强化点深入细致工程建设每一细胞核。搞好后端操控性强化绝非单纯之事!该文主要就文档如是说后端操控性考评分项及强化计划。
一、后端测试方法有甚么样?
依照 chrome Lighthouse 新一代准则,后端测试方法权衡主要就有 FCP(First Contenful Paint)、SI(Speed Index)、LCP(Largest Contentful Paint)、TBT(Total Blocking Time)、CLS(Cumulative Layout Shift) ,占比依次如下表所示。
二、甚么是 FCP ?
FCP: First Contentful Paint 首度文档绘出是指量测网页从早已开始读取到网页文档(文档、图片、左上方、svg 原素及非紫色 canvas 原素)的任何人部份在萤幕上顺利完成图形的天数,是量测读取速率交互的关键分项众所周知。
实例:
从上图能检视到,网页读取早已开始到网页图形顺利完成的本篇中,FCP 出现在第二帧,第一批文档和相片在萤幕上早已图形顺利完成。
尽管网页一小部份文档已顺利完成图形,但这绝非网页大部份文档全数顺利完成图形;这是首度文档绘出(FCP)与最小文档绘出(LCP)最关键的差别。
FCP 操控性值:首度文档绘出顺利完成图形天数应掌控在 1.8s 以上。
我们能从以下方向点强化 FCP :
• 消除阻塞图形的资源:
◦ <script> 标签:在 <head> 标签内的,并且没有 defer/async 属性
◦ <link rel=”stylesheet”> 标签:没有 disabled 属性,有 media=”all” 属性被认为是图形阻塞
• 缩小 CSS 体积:写法,压缩 CSS
• 移除未使用的 CSS
• 预
• 减少服务器响应天数(TTFB)
• 避免多个网页重定向:浏览器请求已定向的资源时,服务器会返回一个 HTTP 响应,然后浏览器必须在新位置发出另一个 HTTP 请求来检索资源。这种额外的网络传输会使资源读取延迟数百毫秒。
• 预读取关键请求:<link rel=”preload” href=”styles,css” as=”style” />
• 避免巨大的网络负载:网络负载的中位数在 1700 到 1900 KiB 之间。 Lighthouse 会标记总网络请求超过 5000 KiB 的网页。将总字节大小保持在 1600 KiB 以下。
◦ 缩小和压缩网络有效负载:缩小(代码),数据压缩(Gzip,Brotli)
◦ 相片使用 Webp
◦ JPEG 相片压缩级别设置为 85
• 对静态资源使用高效的缓存策略:可缓存资源
◦ 字体、图像、媒体文件、脚本或样式表
◦ 资源具有 200 、 203 、 206 HTTP 状态码
◦ 资源没有明确的无缓存策略
• 避免 DOM 过大:
◦ 会造成网络效率和负载操控性差
◦ 网页交互时,会导致重新计算节点的位置和样式,降低图形速率
◦ 可能会不知不觉存储大量节点的引用,造成内存过大
• 最小化关键请求深度:链的长度越长,下载量越大,对网页读取操控性的影响就越大
◦ 减少关键资源数量(删除,推迟下载,标记 async 等)
◦ 强化关键字节数减少下载天数
◦ 强化剩余关键资源的读取顺序,尽早下载大部份关键资源,缩短关键路径长度
• 确保文档在网页字体读取期间保持可见:预读取网络字体
• 保持较低的请求数和较小的传输大小: CSS 和 JavaScript ,相片,字体,文件,媒体
三、甚么是 Speed Index ?
SI:Speed Index 衡量网页读取期间文档以视觉方式显示的速率。 Lighthouse 首先捕获浏览器中网页读取的视频,并计算帧之间的视觉速率。通俗的讲,是网页从有东西到完全显示文档的可见填充速率。
Speed Index 分项值:
我们能从以下方向点强化 Speed Index 的方法:
• 减少主线程工作
• 减少 JavaScript 执行天数
• 确保文档在 webfont 读取期间保持可见
四、甚么是 LCP ?(重点)
LCP: Largest Contentful Paint 最小(最有意义)文档绘出,是指依照网页首度早已开始读取的天数点来报告可视区域内可见的最小图像或者文档块顺利完成图形的相对天数。
LCP 分项值:
• LCP <= 2.5s 合格
• 2.5s < LCP <= 4s 需要强化
• LCP > 4s 劣质
1. LCP 权衡的原素有甚么样?
主要就权衡以下几种相关原素:
• <img> 原素
• 内嵌在 <svg> 原素内的 <image> 原素
• video 原素(使用封面相片)
• 通过 url()函数读取的带有左上方像的原素
• 带有文档或其他行内原素文档的块级原素
2. LCP 原素大小是如何定义的?
最小文档绘出(LCP)的原素大小是指用户在可视区域内可见的大小,所以权衡都是基于可视区域为准,如果原素有延伸到可视区域外,或者原素被裁剪或包含不可见的溢出,这些部份不计入原素大小;
对于图像原素的大小,分项会对比可见尺寸与原始尺寸,取尺寸小者为准;例如双倍图以可见尺寸为准,拉伸放大图则以原始尺寸为准;
对于文档原素,原素的大小为文档节点的大小(包含大部份文档节点的最小矩形);
WARNING: 大部份原素通过 CSS 设置的任何人边距、填充或边框都不在权衡覆盖范围内。另外如果设置了满屏背景图,但萤幕可视区域内有占比较大的原素(浮在左上方上的原素),导致左上方暴漏可视覆盖范围较小,那么最小文档会选择可视区域内最小原素。
并且,一个原素只有在图形顺利完成后对用户可见后才能视为最小文档原素。
3. LCP 绘出天数上报
因为网络或技术原因,网页的读取通常是分段进行的, 所以最小原素也在出现变化。
为了应对这种变化,浏览器在绘出第一帧后立即分发一个 largest-contentful-paint 类型图形后续帧之后,浏览器会在最小文档原素出现变化时分发另一个 PerformanceEntry 。
网页的原素(某一个原素)只有在图形顺利完成后并且对用户可见后才能视为最小文档原素。未读取的图像不会视为图形完成,也就不能视为最小文档原素。字体阻塞期使用字体的文档也是如此。这些情况下,较小的原素会被报告为最小的原素,但一旦更大的原素图形顺利完成,则会上报另一个 PerformanceEntry 对象。
除延迟加载的图像与字体外,网页可能会在新文档(接口请求等)可用时向 DOM 添加新原素文档。如果有一个新原素大于先前的最小文档原素,则浏览器还会上报一个新的 PerformanceEntry 对象。
如果当前的最小文档原素从可视区域被移除(甚至从 DOM 中被移除),那么除非有一个更大的原素顺利完成图形,否则该原素将持续做为最小文档原素,不会更改 performanceEntry 对象。
当用户与网页进行交互(通过轻触、滚动或按键)时,浏览器将立即停止上报 PerformanceEntry 对象,因为用户交互通常会改变网页原有文档。
浏览器出于安全考虑,对于缺少 Timing-Allow-Origin 标头的跨
4. 当原素布局和原素大小更改时,甚么样情况会影响 LCP
情况1:对原素大小或位置修改不会生成新的 LCP 候选对象,只有原素在可视区域内的初始大小和位置会被纳入权衡覆盖范围;
情况2:最初在可视覆盖范围内图形,然后被移除可视区域外的原素仍将报告他在可视区域内的初始大小;
情况3:而在萤幕可视覆盖范围外图形顺利完成,过度到萤幕上的原素则不做报告。
实例:最小原素随着文档读取顺利完成而出现改变
第一个实例中,新文档图形顺利完成,因此使最小原素出现了改变。
第三个实例中,由于布局的改变,先前的最小文档从可视区域中被移除。
如果延迟文档没有初始最小原素大,则 LCP 取初始值。
5. 最小原素绝非关键原素
网页上最关键原素绝非最小原素,这个时候开发者考评分项是最关键原素。
6. 更快的图形主要就文档,降低 LCP 值
影响网页图形操控性主要就原因有以下几点,通过强化它们能降低 LCP 分项值
(1) 服务器响应速率:
是指浏览器从服务器接收文档所需的天数越长,用户在萤幕上所图形文档的天数就越长。更快的服务器将直接影响包括 LCP 各项分项的读取值。
可强化方向:
• 强化服务器操控性
• 将用户路由到附近的 CDN
• 缓存资源
• 优先使用缓存提供 HTML 网页
• 尽早建立第三方链接
• 使用签名交换
(2) 阻塞图形的 JS 和 CSS :
浏览器图形文档之前需要先解析 DOM 树,解析过程中,如果遇到任何人外部样式表(<link rel=”stylesheet”>)或同步 JavaScript 标签(<script src=”main.js”>),则会暂停解析。
所以脚本跟样式都是阻塞图形的资源,这些资源都会导致 FCP 延迟,从而导致 LCP 延迟。所以延迟读取非必要的 JS 和 CSS ,从而提高网页主要就文档读取速率。
减少 CSS 阻塞天数的方法:
• 消减 CSS : 删除 CSS 中的空格、换行、缩进、注释等字符
• 延迟读取非关键 CSS : 将初始图形时不需要的 CSS 提取到一个文件,进行异步读取
• 内联关键 CSS : 把首屏文档的关键 CSS 直接包在 <head> 中,将 CSS 内联; Critters 是一个 webpack 插件,能够内联关键 CSS 并对其余部份进行懒读取
减少阻塞图形的 JavaScript 数量能够让图形速率更快,降低 LCP 值
减少 JS 阻塞天数的方法:
• 消减压缩 JavaScript 文件
• 延迟读取未使用的 JavaScript 文件
• 最小限度的减少未使用的 polyfill
(3) 缓慢的资源读取速率 :
尽管 CSS 或 JavaScript 阻塞天数的增加会直接导致操控性下降,但读取许多其他类型资源所需的天数也会影响绘出天数。
影响 LCP 的原素有以下几种:
• <img> 标签
• 内嵌 <svg> 的 <image> 标签
• <video> 原素的封面图
• 通过 url() 函数读取的带有左上方的原素
• 包含文档节点或其他行内级文档原素的块级原素
强化方法:
• 强化相片: 压缩相片,使用 webp 格式,相片资源上传 CDN ;当然能用代码实现尽量不使用相片;、
• 预读取关键资源: 使用 <link rel=”preload”> 提高优先级进行下载和缓存;
• 压缩文档文件: Gzip、Brotli (google 出版)
• 基于网络连接交付不同资产(自适应服务): navigator.connection.effectiveType (有效连接类型 4G), navigator.connection.saveData (启用/禁用数据保护程序), navigator.hardwareConcurrency (cpu 核心数), navigator.deviceMemory (设备内存)
• 缓存资源: service woker 在 worker 上下文中运行: 因此它没有 DOM 访问权限,并且是运行在不同线程上,因此它是非阻塞的。
(4) 客户端图形:
如 React 、 Vue 、 Angular 这类框架所搭建的单网页应用,是完全在客户端中处理逻辑的。
强化方法:
• 最小化关键 JavaScript : 精简 JavaScript , 延迟读取未使用的 JavaScript , 最小限度减少未使用的 polyfill
• 使用服务端图形: 用服务器将主要就文档首先在服务器图形为 HTML , 客户端将大部份 JavaScript 及所需数据”水合”到相同的 DOM 文档中
• 使用预图形: 使用无头浏览器,提前搭建每一路由的静态 HTML 文件,然后将这些文件与应用程序所需的 JavaScript 包一起运送
五、什么是 TBT ?
TBT: Total Blocking Time 总阻塞天数,是网页被阻塞响应用户交互的总天数。 TBT = LCP (首度最小文档绘出)和可交互天数之间大部份长天数任务的阻塞部份之和。是量测网页读取响应的关键分项。
超过 50 毫秒的任务即为长任务。 超出 50 毫秒的天数量为阻塞部份。
例如:检测到一个 90 毫秒的任务,则阻塞部份为 40 毫秒(90 – 50 = 40)
TBT 指标:
强化方法:
• 减少不必要的 JavaScript 读取、解析或执行。减少 JavaScript 负载、删除未使用的代码或有效读取第三方 JavaScript 能提高 TBT 分数。
• 减少低效的 JavaScript 语句。例如: document.querySelectorAll(a) 会返回大部份符合的节点
六、甚么是 CLS ?
CLS: 累计布局偏移(CLS)是量测视觉稳定性的关键分项。是整个网页声明周期内出现的大部份意外布局偏移中最小一连串的布局偏移分数。
网页文档的意外偏移大多是由于异步资源读取,或者动态添加 DOM 原素到网页现有文档上方导致的。罪魁祸首可能是未知尺寸的图像或视频、实际图形后比后备字体更大或更小的字体等。
CLS 分项:
注意: 只有当现有原素的起始位置出现变更时才算做布局偏移。如果将新原素添加到 DOM 或是现有原素更改大小,则不算做布局偏移。只有当原素的变更会导致其他可见原素的起始位置出现变化,才叫偏移。
计算公式: 布局偏移分数 = 影响分数 x 距离分数
影响分数: 前一帧和当前帧的大部份不稳定原素的课件区域集合(占总可视区域的部份)是当前帧的影响分数。
距离分数: 指的是任何人不稳定原素在一帧中位移的最小距离(水平或垂直)除以可视区域的最小尺寸维度(宽度或高度,以较大者为准)。
产生 CLS 的常见原因:
• 无尺寸的相片
• 无尺寸的广告,嵌入和 iframe
• 动态注入的文档
• 导致不可见文档闪烁(FOIT)、无样式文档闪烁(FOUT)的网络字体
• 在更新 DOM 之前等待网络响应的操作
强化方法:
• 在相片和视频原素上包含尺寸属性
• 非用户交互响应的情况下,都不要在现有的文档上方插入其他文档
• 首选转换动画,而不是触发布局偏移的属性动画
以上五个分项是目前后端测试方法权衡点,以及产生问题原因,强化方法等。每一强化点都能扩展出很多知识以及学习点,所以前端强化这个工作链路依然很长;单一点的强化效果可能并不明显,但五个点全数强化,定然会有质的飞跃。
在实际项目中,优先从后端自身出发,强化完自身后,再去强化协同项。
另外后端强化是一件可持续,并长久的事情,工具技术升级的迭代也会提升项目操控性,针对强化这样的工作一定要持续下去,而不是做一次就OK了。
后端操控性强化这条路,道阻且长,行则将至,专研就会有进步,最终定然会成功达到最终目标。
该文参考: https://web.dev/ https://developer.chrome.com/