Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[译]渲染性能优化之渲染的5个阶段(JS->Style->Layout->Paint->Composite) #195

Open
FrankKai opened this issue Apr 1, 2020 · 0 comments

Comments

@FrankKai
Copy link
Owner

FrankKai commented Apr 1, 2020

原文链接:https://developers.google.com/web/fundamentals/performance/rendering

  • 60fps和设备刷新率
  • 像素管道
    • 5个关键阶段(核心知识点)
    • pipeline处理可视改变的3种方式
      • JS/CSS > Style > Layout > Paint > Composite
      • JS/CSS > Style >Paint > Composite
      • JS/CSS > Style > Composite
  • 浏览器渲染优化

对于现如今的web,用户希望他们访问的页面是可交互的和平滑的,因此在交互和平滑方面我们需要花费更多的时间和努力。页面不仅仅需要快速加载,也需要运行良好;滑动不仅仅要跟随手指快速定位,动画和交互也需要同样平滑。

为了写出高性能的网站和app,你需要理解被浏览器处理的HTML,JavaScript,CSS,并且确保你写的代码(包括其他第三方库的)尽可能高效的运行。

60fps和设备刷新率

现如今绝大多数的设备每秒刷新60次。如果有animation或者transition运行时,或者用户在页面上滚动时,浏览器需要匹配设备的刷新率,并且在每次屏幕刷新时放一张新照片,或者一个frame。

每一帧大概有16ms的预算,因为(1second/60=16.66ms)。事实上,因为浏览器有内务工作要做,所以我们所有的工作都需要在10ms内完成。当你不能满足这个预算时,帧率就会下降,达不到60fps,屏幕上会明显感觉到卡顿。这通常叫做jank,很影响用户的体验。

jank是什么?

Google also found that this independence of processes resulted in less "jank", which is Google's term for unresponsiveness in the browser.
Google也发现独立进程也减少了jank,这是Google团队对浏览器无反应性的称谓。

像素管道

5个关键阶段(核心知识点)

你需要知道5个主要区域,并且在工作中要时刻保持对代码运行在那个区域心里有数。
这5个区域是你可以控制的,也是像素到屏幕的管道中的关键点:
image

  • JavaScript
    js可以用来进行一些可见的修改。 无论是jquery的animate函数,排序一个数据集合,还是向页面增加一个DOM元素。其实用必须使用js去触发这些可视改变,可以通过CSS Animations,Transition和Web Animations API这些通常使用的api。

  • 样式计算(Style Calculations)
    元素选择器选中元素。
    这个阶段主要用于基于匹配的选择器,指明什么元素应用什么CSS规则。 比如.headline或者.nav>.nav__item。从这里开始,一旦规则已知,它们被应用并且每个元素的最终样式规则也会计算出。

  • 布局(Layout)
    计算元素占据空间和位置。
    一旦浏览器知道了每个元素该如何应用规则以后,它开始计算每一个元素需要在屏幕上占据多少空间。web的layout 模型意味着一个元素可以影响到其它的元素,例如<body>元素的宽度可以影响到它的子元素的宽度和沿着树上下移动,所以这个过程对于浏览器来说是非常复杂的。

  • 绘制(Paint)
    填充内容,一像素一像素去填充。
    Painting指的是用像素去填充的阶段。它包括画出文本,颜色,图像,边框和阴影,基本上元素上的每个可视部分都在这个阶段完成。绘制一般需要在多个界面进行,一般叫做layer。

  • 合成(Compositing)
    多个layer按照层级合成在一起。
    一旦页面的这些部分被明显的绘制在不同的layer上后,它们需要按照顺序最终渲染到屏幕上,这样页面才能保证正常渲染。对于元素而言,这个阶段非常重要,因为影响到了元素的重叠,因为一个失误可能导致一个元素出现在另一个元素之上。

流水线的每一个步都是一个减少jank的机会,所以你的代码触发了流水线的哪一个部分是必需要理解的。
有时你可能听到过“栅格化”与paint一起出现。这是因为paint一般需要做两项事情:1)创建需要绘制的列表 2)使用像素填充(这一步叫做栅格化)

每当我们在Devtools中看到paint时,应该将其视为栅格化。(在一些架构中创建待渲染的列表和栅格化是在不同的线程中进行的,但这并不是开发者可以控制的。)

pipeline处理可视改变的3种方式

不比每一帧都去触发流水线的每一部分。事实上,当你创建了一个可视的变化时,pipeline有3种方式去处理给定的一个frame,可以使用JavaScript,CSS和Web动画:

JS/CSS > Style > Layout > Paint > Composite

image

如果你改变了一个”layout“属性,也就是改变一个可以影响元素几何形状的属性,比如width,height,或者是left,top位置,浏览器会检查所有的其他元素然后”reflow“页面。所有影响到的区域需要被重新绘制,最后绘制出的元素需要重新组合在一起。

JS/CSS > Style > Paint >Composite

image

如果你**改变了一个”paint only“属性,比如background image,text color,或者shadows,换句话说就是不影响网页的layout的那些属性,浏览器会跳过layout的过程,**但是它最终还是会paint的。

JS/CSS > Style > Composite

image

如果改变了一个既不需要layout也不需要paint的属性,浏览器会跳过Layout和Paint两个阶段,直接进行Compositing阶段,进行合成。
在一个app生命周期中的高压点来说,最终版本是最便宜的而且最理想的,比如animation或scrolling。

提醒:如果想辨识”layout property“,”paint-only property“和”compositor-only property“,可以查阅CSS Triggers这个网站,https://csstriggers.com/。如果想实现高性能的动画,建议查看改变compositor-only属性。

性能是避免工作的艺术,并且可以使得你的工作尽可能的高效。在许多场景下,是与浏览器一起工作的,而不是与它对抗。值得注意的是,在管道中列出的工作在计算成本方面有所不同;有些任务比其他任务更昂贵。

让我们深入了解一下管道的不同部分。我们将研究常见的问题,以及如何诊断和修复它们。

浏览器渲染优化

性能对用户来说有很大的影响。web开发者需要构建响应快速和渲染平滑的应用。Google 性能专家Paul Lewis帮助我们消灭jank而且创建60fps的app。课程结束时,你将会掌握你需要的工具来分析应用程序并找出jank的原因。你将探索浏览器的渲染管道,并发现使构建高性能应用程序变得容易的模式。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant