关于前端:前端性能指标Cumulative-Layout-Shift

57次阅读

共计 3288 个字符,预计需要花费 9 分钟才能阅读完成。

本文是译文,关注 Web Vitals Metrics,翻译系列文章中的 03 篇
原文链接:Cumulative Layout Shift (CLS)

前言

浏览网页时你是否遇到过页面上的内容忽然扭转的状况?没有任何征兆地文本挪动了地位,导致你都不晓得读到哪了。或者更有甚者:当你要点击按钮、链接的时候,忽然链接地位变了,让你点击到了别的链接上!产生这种状况让人体验十分不好,在另外的场景下会造成灾难性结果。

因为网站中的资源是异步下载的,页面内容也能够动静地增加到已有内容上,所以内容产生非预期变动的场景比拟常见。未设置宽高的 <image><video> 元素,理论应用的字体与备用大小不统一,能够动静变更大小的第三方广告或者组件都有可能是导致页面产生非预期偏移的“罪魁祸首”。

站点在开发环境的体现与理论用户感触到的有很大差别。开发、生产环境中个性化、第三方内容通常体现也有不统一的状况,比方:测试图片缓存在开发者浏览器缓存之中;本地的 API 运行得很快,其提早都无奈观测到。CLS 通过帮忙咱们掂量用户理论拜访页面时布局偏移产生的概率,来解决开发、生产环境中页面体现不统一的问题。

1.CLS 定义

掂量的是页面整个生命周期中每次元素产生的非预期布局偏移得分的总和。每次可视元素在两次渲染帧中的起始地位不同时,就说是产生了 LS(Layout Shift)。

1.1CLS 得分多少才算良好

CLS<0.1,同样规范须要笼罩站点 75% 的用户

1.2 深刻 LS 的细节

LS 的由 Layout Instability API 定义,每当视口中两次渲染帧之间的可视元素扭转了其起始地位时都会触发 layout-shift entries,扭转了起始地位的元素被认为是不稳固元素。因为 LS 只会产生在扭转了初始地位的已有元素上,只有新退出的元素并不会造成其余可见元素扭转地位,它将不会被当成是 LS 元素。

(1)LS 得分算法

为了计算出 LS 分数,浏览器关注视口大小和视口中两个渲染帧之间不稳固元素的挪动状况。LS 得分等于 影响小数与 间隔小数的乘积。咱们别离来看看这两个因数是如何算进去的。

layout shift score = impact fraction × distance fraction

影响小数

掂量的是不稳固元素渲染帧前后对视口的影响大小

不稳固元素在之前渲染帧中的可视区域 和 以后帧可视区域的并集,即为影响小数。举个例子:在图 1 中展现的页面渲染帧中, 元素占据了一半的视口。之后,在下一个渲染帧,元素往下偏移了视口高度的 25%。红色虚线示意的即为两帧不稳固元素可视区域的并集。在这里例子里,占据了视口大小的 75%,因而影响小数值为 0.75。

间隔小数

掂量的是不稳固元素绝对于视口挪动的间隔。

间隔小数等于不稳固元素在渲染帧中挪动的最大间隔(程度或者垂直方向上)除以视口宽或者高(谁大取谁)。在上述例子中,挪动间隔是垂直方向上,挪动了 25% 视口高,如图 1 中蓝色箭头,因而间隔小数为 0.25。因而,在图 1 给定的例子外面,LS 得分为 0.75*0.25 = 0.1875。如图 1:

接下来的例子演示给已有元素新增内容是如何影响 LS 得分的。如图 2:

Click me 按钮挂载在含有彩色文本的灰色盒子里,它将含有红色文本的绿色盒子往下推(局部被推出视口)。图 2 例子中,灰色盒子尽管扭转了大小,但其起始地位没有变动,所以他不是一个不稳固元素。按钮之前不存在,它的起始地位没变,也不是不稳固元素。绿色盒子的起始地位产生了变动,它是一个不稳固元素。另外,因为它局部被推出了视口之外,不可见局部不会参加计算影响小数。绿色盒子在 2 个渲染帧中呈现的可视局部的并集占据了视口的 50%。因而影响小数为 0.5。图中的紫色箭头阐明的是间隔小数,绿色盒子大略挪动了视口的 14%,因而间隔小数值为:0.14。共计 LS 得分为 0.5*0.14=0.07。

最初这个例子演示了视口中呈现多个不稳固元素的状况。如图 3:

第一帧展现的是申请 API 后 4 种动物数据,以字母顺序排列。第二帧图加了更多元素。Cat 所在的元素起始地位没变,它是稳固的。相似的,新加的元素起始地位也没有变动。标记为 Dog、Horse 和 Zebra 的元素都偏移了他们的起始地位,它们都是不稳固元素。红色虚线框代表的是这 3 个不稳固元素偏移前后占据视口的并集,大略占据了视口区域的 38%(影响小数为 0.38)。箭头示意着不稳固元素偏离其初始地位的间隔。蓝色箭头的 Zebra 元素,绝对视口高度约扭转了 30%(因而间隔小数为:0.3)。最终 Zebra 元素的 LS 得分为:0.38*0.3。

(2)预期 LS 与非预期 LS 的比照

用户发动的 LS

也不是所有的 LS 都是个问题,非预期的 LS 才是。像基于用户操作响应导致的 LS 是能够承受的,只有偏移产生的机会跟响应用户的操作之间分割足够严密。举个例子:用户发动的网络申请须要期待肯定工夫能力实现,最好立刻创立布局空间,展现 loading 正在加载的批示组件来防止申请实现后产生 LS。如果用户看不到加载正在进行,或者申请实现之后无从得悉,用户在期待期间就会去点击别的中央。产生在用户输出之后 500ms 以内的 LS 将会被打上标记,不会参加 LS 计算。

动画和突变

动画、突变如果应用切当的话是一个较好的更新页面内容的方法,不会让用户感觉突兀。页面上内容粗犷的、意外的偏移会带来蹩脚的用户体验。内容如果渐进、天然地从一处挪动到另外一处有助于用户了解页面上产生的事,也能为用户提供指引。
CSS 的 transform 属性能够做到不引发 LS 的状况下实现动画成果:

a. 用 transform:scale()代替 height、width 属性的变动;
b. 用 translate()代替 top、right、bottom、left 属性的变动。

2. 如何掂量 CLS

2.1 现场工具:

Chrome User Experience Report
PageSpeed Insights
Search Console (Core Web Vitals report)
web-vitals JavaScript library

2.2 开发工具:

Chrome DevTools
Lighthouse
WebPageTest

2.3JavaScript 代码

(1) API

Layout Instability API + PerformanceObserver

let cls = 0;
new PerformanceObserver((entryList) => {for (const entry of entryList.getEntries()) {if (!entry.hadRecentInput) {
      cls += entry.value;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

阐明:所有具备 hadRecentInput 标记的 layout-shift entries 累加值即为 CLS 值,大部分时候,最终的 CLS 会在页面 unload,但也存在如下例外情况:页面在后盾的不参加、缓存中的和 iframe 中页面也不参加。除了例外情况,因为 CLS 贯通整个页面的生命周期的个性也减少了其计算的复杂性。比方用户关上 tab 页面很久都不关掉、挪动端浏览器不会为后盾运行的 tab 执行页面 unload 回调。同样,细节较多,咱们倡议应用开发好的工具库来测量 CLS。

(2) JavaScript 库

import {getCLS} from 'web-vitals';
getCLS(console.log);

3. 晋升 CLS 的方法

严格遵循以下准则,就能够防止站点中大部分非预期 CLS 问题,内容有:
(1)给 imagevide 元素设置 size 属性,或者预留之后须要的布局空间。这个做法确保让浏览器在图片正在加载时就调配好正确的文档空间。
(2)除非为了响应用户,不要在已有内容上插入内容
(3)把触发布局扭转的属性改用 transform 动画的形式
更多对于优化 CLS 的办法,请参考:优化 CLS 章节(待补充)

其它参考:
1. 缩小 layout-shift
2. 了解 CLS

正文完
 0