🥳 欢送有趣味的小伙伴,一起做点有意义的事!本文译者: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 元素的新几何形态
绘制
为页面的不同区域绘制或填充新的像素点
合成
将所有独自绘制的图层组合在一起,筹备显示
须要留神的是,运行的阶段和实现帧渲染的工夫取决于正在更改的元素属性。通常一种视觉效果会有好几种不同的实现形式,然而有些形式的渲染老本是很高的。
属性能够分为模式,合成两种,顺便说一句,复合属性的渲染老本是最低的。
为什么合成属性要优于模式属性?
模式属性就是指会更改元素的形和式的属性(比方宽高,地位,色彩等),模式属性的应用往往会产生重绘或者回流。
合成属性就是指 transform
和opacity
之类的属性,这类属性在应用时会将元素晋升到合成层,在一些浏览器上不会产生重绘或回流。
当咱们应用式(色彩,背景图等)一类的属性时,不会对元素的形(宽高,地位等)产生影响,所以就不会走 Layout 阶段。
不同的式属性会占用不同的渲染工夫,但通常比形属性的渲染工夫要快。
咱们还能够通过最小化重绘区域来优化渲染速度,只是咱们之后要谈的。
当咱们应用合成属性时,会跳过 Layout 和 Paint 阶段,这也是合成属性占用最小渲染工夫的起因。
合成属性利用硬件加速来实现沉重的渲染工作,来帮忙咱们缩小一帧所占用的工夫,这对于动画和滚动相干的阻塞点十分有用。然而这里会产生一个问题,咱们之后谈判到。
合成属性包含:
-
Transfrom:
平移,缩放,旋转,歪斜元素
-
Opacity:
元素的透明度
-
Filter*:
含糊,对比度,灰度,色调和暗影成果
注:某些浏览器不会对 Filter 进行硬件加速
尽管每帧都应用合成属性简直不可能办到。
但通咱们能够用合成属性去代替模式属性做雷同的视觉效果,仅仅通过这三个属性的相互组合,就能够达到一个惊人的数量了。
还有最初一个重要的概念将会使你更理解合成属性:Layers(层)
饭后甜点
层,或者合成层,是在浏览器中能够被晋升到有本人独立绘制区域的 DOM 元素
一个独立的图层,在其自身的视觉效果发生变化时,只须要渲染其自身。
良好的图层应用能够最大限度地缩小绘画区域,而浏览器则通过一套外部规范来决定将 DOM 元素晋升到合成层还是降级到一般层。
如果 DOM 元素:
- 领有 3D 或透视变动的 CSS 属性
- 应用了视频减速解码的
<video>
元素 - 应用了 3D 环境或硬件加速 2D 环境的
<canvas>
元素 - 应用了合成插件
- 通过动画来转换元素的透明度
- 应用了硬件加速的 CSS Filter 属性
- 有一个层级较低的,领有合成层的兄弟元素
- 扩大 Chrome 中的硬件加速
上述将会导致 DOM 元素被晋升到合成层
只有晋升到合成层的元素能力应用硬件加速。如果在应用合成元素的时候,浏览器没有晋升元素,那么渲染周期中的 Paint 阶段就不会被跳过。
通常来讲,应用合成属性中的繁多属性(比方 transform,opacity)是不会引起浏览器晋升操作的。然而动画类的合成属性将会在动画开始时晋升层级,在动画完结时降级。层级的晋升和升高并非对所有合成属性都是毫无代价的。
然而 CSS 的一个新属性 will-change
,能够将一个 DOM 元素晋升层级。如果咱们想告诉浏览器行将产生一个transform
方面的变动,并须要将其晋升。那咱们能够写作will-change: transform
这将会使该元素放弃晋升,并不会在被其余规范降级。
通过合成属性和 will-change
的适当配合,很有可能会创立一个在加载过后,简直不须要再重绘或回流的页面。
物极必反
如果咱们想把页面上的每一个元素都晋升到合成层渲染,这样不仅不会使渲染速度变快,反而会使浏览器过载。
咱们还该当警觉合成层激增 —— 当咱们应用 will-change
来晋升元素时,可能会让被晋升元素的兄弟元素也被晋升,这也会导致浏览器过载。
所以咱们该当慎用will-change
,只把它用于没必要重绘的状况。
测试是测验后果的唯一标准
在改良渲染周期的过程中,咱们要留神以下两点:
- 确定能够改良的中央
- 剖析并验证更改后的渲染周期
性能分析器 Performance
开发者工具中的 Performance 选项卡容许录制一段时间内用户与网页的任何交互。实现录制后,这些信息以工夫线的模式出现,具体阐明每个帧的每个事件、渲染周期阶段、函数调用等。
点击单个帧将会看到其独自的渲染周期阶段耗时。
能够据此查找运行频率过高、运行工夫过长以及失落的帧,而后考察起因。
Summary 选项卡中的饼图将会展现渲染帧时各个阶段所耗费的工夫。
须知:
- 单击 Layout 或 Paint 将会展现更具体的信息
- Performance 占用的工夫是不会被计算在内的,Disable JavaScript sample 将会缩小总耗时,但同时也不会看到单个 JS 脚本耗时
- 能够通过限度 CPU 性能或网络速度来测试网页在坏状况下的体现,以便为用户做一个更具包容性的网页
- 启用 screenshots 能够应用可视化应用程序察看在特定帧中产生的状况
- Update Layer Tree 是浏览器治理所有层状态的事件 —— 如果这里耗时很长,那示意有太多的层或过于臃肿的 DOM 元素
渲染面板 Rendering
关上 Rendering 的一种办法是在开发者工具的更多选项中,找到 rendering
并点选上 Paint flashing
。rendering
中蕴含了大量有用的工具,在深入研究性能分析器以找出问题所在之前,它们十分有助于疾速查找问题。
Paint flashing
将显示页面的哪些区域在绘制过程中以及何时被从新绘制。
能够应用此工具来查看应用 will-change
晋升元素是否胜利缩小一些不必要的重绘。
Layout Shift Regions
将显示引起回流的区域。应用此工具来验证是否移除了不必要的回流景象,或确定产生回流的地位。
Layer borders
将展现页面上正在应用的合成层,这对于考察您的元素是否按预期晋升十分有用。点击此处查看更多边框色彩含意
最初,Frame Rendering Stats
和 Scrolling performance issues
也很有用,它们别离领有实时帧速率指示器和滚动性能剖析。
图层面板 Layers
能够在开发者工具的更多里关上图层面板。
图层面板会展现所有图层的交互式 3D 视图。
抉择指定图层将会展现以下信息:
- 指定图层为什么被晋升
- 该图层占用的内存
- 图层尺寸
- 图层被重绘的次数
全即是一
在这里,咱们将通过动画突变加载占位符的例子,来展现如何应用现有工具和渲染周期常识晋升性能
通常是通过在动画背景上叠加形态来实现的。
为不便起见,咱们将只思考背景。
通过形属性实现
在 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 flashing
或 Layout shift regions
都不会失效。
浏览器主动将元素晋升(因为动画合成属性),应用硬件加速跳过了渲染周期的两个阶段,在这里没必要应用 will-change
。
然而,如果您常常关上和敞开此动画,或者应用 JS 手动更改每帧动画,will-change
可能会很有用。
启用 Layer borders
后,能够看到橙色轮廓:
应用三种形式实现了同一种视觉效果,显著最初一种耗时更少,性能更好。
尽管只只是一个简略的示例,然而见微知著,这其中的办法也能够利用在大型的我的项目中。
相干链接
Frontend Web Performance: The Essentials
翻译打算原文