关于前端:Frontend-Focus-532前端性能优化

32次阅读

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

🥳 欢送有趣味的小伙伴,一起做点有意义的事!本文译者:Rick Ma

我发动了一个 周刊翻译打算,仓库地址,拜访地址

当初还很缺气味相投的小伙伴,纯属个人兴趣,当然对于晋升英语和前端技能也会有帮忙,要求:英语不要差的离谱、github 纯熟应用、有恒心、虚心、对本人做的事负责。

想参加的小伙伴,能够 wx 私信,也能够给仓库发 issue 留言,我博客也有具体的集体联系方式:daodaolee.cn

一即是全 — 浏览器渲染周期,硬件加速和排版布局

每一台电子设备的显示器每秒依照肯定的帧数刷新,浏览器必须尝试匹配刷新率以使用户取得晦涩的体验。而要将新的一帧输入到显示器上,浏览器首先要实现“渲染周期”和“像素管道”

大多数的设施是以 60FPS 的速度运行的,这示意每 16ms 就要输入一帧。FPS 示意每秒钟帧的速率,更高的 FPS 就意味着每一帧有更高的速率。比方 120FPS,每帧破费的工夫就不能超过 8ms。

更蹩脚的是,浏览器往往会减少一些额定的开销,并且可能会占用每帧长达 4ms 的工夫;所以在生产中,咱们大略须要用每一帧 12ms 的速率来达到 60FPS。而在 120FPS 下,每帧仅有 4ms 的工夫。

如果浏览器无奈给足每一帧要领有的工夫,就会产生掉帧。这将会使画面不晦涩,也会使用户有一个蹩脚的体验。

对渲染周期的深刻理解,以及如何应用现有工具对其进行剖析,使咱们可能最大限度的每一帧所须要占用的工夫 ———— 这是对于浏览器中前端性能至关重要的一点

渲染周期

以上是在渲染帧时渲染周期的五个阶段

JS/CSS 动画

某些 JS 或者 CSS 动画会导致视觉变动,从而引起渲染

款式

匹配信息而后将新的 CSS 选择器或规定利用于指定 DOM 元素

布局

计算 DOM 元素的新几何形态

绘制

为页面的不同区域绘制或填充新的像素点

合成

将所有独自绘制的图层组合在一起,筹备显示

须要留神的是,运行的阶段和实现帧渲染的工夫取决于正在更改的元素属性。通常一种视觉效果会有好几种不同的实现形式,然而有些形式的渲染老本是很高的。

属性能够分为模式,合成两种,顺便说一句,复合属性的渲染老本是最低的。

为什么合成属性要优于模式属性?

模式属性就是指会更改元素的形和式的属性(比方宽高,地位,色彩等),模式属性的应用往往会产生重绘或者回流。
合成属性就是指 transformopacity之类的属性,这类属性在应用时会将元素晋升到合成层,在一些浏览器上不会产生重绘或回流。


当咱们应用式(色彩,背景图等)一类的属性时,不会对元素的形(宽高,地位等)产生影响,所以就不会走 Layout 阶段。
不同的式属性会占用不同的渲染工夫,但通常比形属性的渲染工夫要快。
咱们还能够通过最小化重绘区域来优化渲染速度,只是咱们之后要谈的。


当咱们应用合成属性时,会跳过 Layout 和 Paint 阶段,这也是合成属性占用最小渲染工夫的起因。
合成属性利用硬件加速来实现沉重的渲染工作,来帮忙咱们缩小一帧所占用的工夫,这对于动画和滚动相干的阻塞点十分有用。然而这里会产生一个问题,咱们之后谈判到。

合成属性包含:

  1. Transfrom:

    平移,缩放,旋转,歪斜元素

  2. Opacity:

    元素的透明度

  3. Filter*:

    含糊,对比度,灰度,色调和暗影成果

注:某些浏览器不会对 Filter 进行硬件加速

尽管每帧都应用合成属性简直不可能办到。
但通咱们能够用合成属性去代替模式属性做雷同的视觉效果,仅仅通过这三个属性的相互组合,就能够达到一个惊人的数量了。

还有最初一个重要的概念将会使你更理解合成属性:Layers(层)

饭后甜点

层,或者合成层,是在浏览器中能够被晋升到有本人独立绘制区域的 DOM 元素
一个独立的图层,在其自身的视觉效果发生变化时,只须要渲染其自身。
良好的图层应用能够最大限度地缩小绘画区域,而浏览器则通过一套外部规范来决定将 DOM 元素晋升到合成层还是降级到一般层。

如果 DOM 元素:

  1. 领有 3D 或透视变动的 CSS 属性
  2. 应用了视频减速解码的 <video> 元素
  3. 应用了 3D 环境或硬件加速 2D 环境的 <canvas> 元素
  4. 应用了合成插件
  5. 通过动画来转换元素的透明度
  6. 应用了硬件加速的 CSS Filter 属性
  7. 有一个层级较低的,领有合成层的兄弟元素
  8. 扩大 Chrome 中的硬件加速
    上述将会导致 DOM 元素被晋升到合成层

只有晋升到合成层的元素能力应用硬件加速。如果在应用合成元素的时候,浏览器没有晋升元素,那么渲染周期中的 Paint 阶段就不会被跳过。

通常来讲,应用合成属性中的繁多属性(比方 transform,opacity)是不会引起浏览器晋升操作的。然而动画类的合成属性将会在动画开始时晋升层级,在动画完结时降级。层级的晋升和升高并非对所有合成属性都是毫无代价的。

然而 CSS 的一个新属性 will-change,能够将一个 DOM 元素晋升层级。如果咱们想告诉浏览器行将产生一个transform 方面的变动,并须要将其晋升。那咱们能够写作will-change: transform

这将会使该元素放弃晋升,并不会在被其余规范降级。

通过合成属性和 will-change 的适当配合,很有可能会创立一个在加载过后,简直不须要再重绘或回流的页面。

物极必反

如果咱们想把页面上的每一个元素都晋升到合成层渲染,这样不仅不会使渲染速度变快,反而会使浏览器过载。
咱们还该当警觉合成层激增 —— 当咱们应用 will-change 来晋升元素时,可能会让被晋升元素的兄弟元素也被晋升,这也会导致浏览器过载。
所以咱们该当慎用will-change,只把它用于没必要重绘的状况。

测试是测验后果的唯一标准

在改良渲染周期的过程中,咱们要留神以下两点:

  1. 确定能够改良的中央
  2. 剖析并验证更改后的渲染周期

性能分析器 Performance

开发者工具中的 Performance 选项卡容许录制一段时间内用户与网页的任何交互。实现录制后,这些信息以工夫线的模式出现,具体阐明每个帧的每个事件、渲染周期阶段、函数调用等。

点击单个帧将会看到其独自的渲染周期阶段耗时。
能够据此查找运行频率过高、运行工夫过长以及失落的帧,而后考察起因。

Summary 选项卡中的饼图将会展现渲染帧时各个阶段所耗费的工夫。

须知:

  1. 单击 Layout 或 Paint 将会展现更具体的信息
  2. Performance 占用的工夫是不会被计算在内的,Disable JavaScript sample 将会缩小总耗时,但同时也不会看到单个 JS 脚本耗时
  3. 能够通过限度 CPU 性能或网络速度来测试网页在坏状况下的体现,以便为用户做一个更具包容性的网页
  4. 启用 screenshots 能够应用可视化应用程序察看在特定帧中产生的状况
  5. Update Layer Tree 是浏览器治理所有层状态的事件 —— 如果这里耗时很长,那示意有太多的层或过于臃肿的 DOM 元素

渲染面板 Rendering

关上 Rendering 的一种办法是在开发者工具的更多选项中,找到 rendering 并点选上 Paint flashing
rendering 中蕴含了大量有用的工具,在深入研究性能分析器以找出问题所在之前,它们十分有助于疾速查找问题。

Paint flashing将显示页面的哪些区域在绘制过程中以及何时被从新绘制。
能够应用此工具来查看应用 will-change 晋升元素是否胜利缩小一些不必要的重绘。

Layout Shift Regions将显示引起回流的区域。应用此工具来验证是否移除了不必要的回流景象,或确定产生回流的地位。

Layer borders 将展现页面上正在应用的合成层,这对于考察您的元素是否按预期晋升十分有用。点击此处查看更多边框色彩含意

最初,Frame Rendering StatsScrolling performance issues 也很有用,它们别离领有实时帧速率指示器和滚动性能剖析。

图层面板 Layers

能够在开发者工具的更多里关上图层面板。
图层面板会展现所有图层的交互式 3D 视图。

抉择指定图层将会展现以下信息:

  1. 指定图层为什么被晋升
  2. 该图层占用的内存
  3. 图层尺寸
  4. 图层被重绘的次数

全即是一

在这里,咱们将通过动画突变加载占位符的例子,来展现如何应用现有工具和渲染周期常识晋升性能

通常是通过在动画背景上叠加形态来实现的。
为不便起见,咱们将只思考背景。

通过形属性实现

在 Codepen 上查看代码和预览

因为 CodePen 是在 iframe 中运行代码,所以开发者工具中的性能检测工具并不对其失效。如果想进行测试,须要把代码 Down 到本地

这种实现形式将会带给用户最蹩脚的体验

@keyframes gradientAnimation{ 
  0%{left: -30%;} 
  100%{left: 130%;} 
}

这里应用了一个突变 div, 增加了 left 位移动画,left 就是一个形属性,这将导致每一帧都会走一遍渲染周期的全副阶段。

以下是性能分析器中每一帧的渲染周期的外在显示:

请留神,下面的红线示意正在产生布局偏移。启用“Layout Shift Regions”后,请留神突变始终以紫色突出显示 – 它会导致每帧布局偏移:

最初,这是整个渲染周期所破费的总工夫——这将有助于与下一个版本进行比拟。

只管每帧都触发了回流,但它实际上不太可能升高浏览器的速度以影响您的帧速率。我曾经限度了我的 CPU 以使其更加引人注目。请记住,这是一个十分小的示例;基本上没有多少货色须要计算。对于简单的应用程序,就会看到切实的影响——尤其是低端设施。

通过式属性实现

在 Codepen 上查看代码和预览

这种形式通过更改背景地位来达成款式成果,这仅仅会引起重绘。

@keyframes gradientAnimation{
  0%{background-position: -45% 0;}
  100%{background-position: 145% 0;}
}

请留神,当初性能分析器没有显示渲染周期的 Layout 阶段,并且不再显示示意布局偏移的红色:

‘Layout Shift Regions’ 不在失效,而 ’Paint flashing enabled’ 使整个页面都变成了绿色,它在从新绘制每一帧:

当初仅通过式属性(之所以耗时比形属性要多,是因为这里包含了 Recalculate Style 从新计算的工夫)来改善渲染工夫,式属性的前三者都要小于形属性:

通过合成属性实现

在 Codepen 上查看代码和预览

在这个实现中,咱们不会应用任何模式属性。

@keyframes gradientAnimation{
  0%{transform: translateX(-100%);
  }
  100%{transform: translateX(333%);
  }
}

性能分析器当初是空的!

paint flashingLayout shift regions 都不会失效。
浏览器主动将元素晋升(因为动画合成属性),应用硬件加速跳过了渲染周期的两个阶段,在这里没必要应用 will-change
然而,如果您常常关上和敞开此动画,或者应用 JS 手动更改每帧动画,will-change可能会很有用。

启用 Layer borders 后,能够看到橙色轮廓:

应用三种形式实现了同一种视觉效果,显著最初一种耗时更少,性能更好。
尽管只只是一个简略的示例,然而见微知著,这其中的办法也能够利用在大型的我的项目中。

相干链接

Frontend Web Performance: The Essentials

翻译打算原文

正文完
 0