课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
在做网页设计中,我们需要将不同的文字和图片通过css样式表进行修饰完善,然后定位到网页上面,完成页面布局,那么css到底是如何运作的呢?
Chrome渲染主要包括Parse Html、Recalculate Style、Layout、Rasterizer、Paint、Image Decode、Image Resize和Composite Layers等。简单了解一下其含义,以便后续内容的更好理解。
Parse Html
发送一个 http 请求,获取请求的内容,然后解析HTML的过程。
有一个经典的前端面试题: 当你在浏览器中输入google.com并且按下回车之后发生了什么? 这个面试题或许能帮助大家更好的理解Parse Html,甚至是浏览器渲染的其他几个部分。
Recalculate Style
重新计算样式,它计算的是Style,和Layout做的事情完全不同。Layout计算的是一个元素绝对的位置和尺寸,或者说是“Compute Layout”。
Recalculate被触发的时候做的事情就是处理JavaScript给元素设置的样式而已。Recalculate Style会计算Render树(渲染树),然后从根节点开始进行页面渲染,将CSS附加到DOM上的过程。
任何企图改变元素样式的操作都会触发Recalculate。同Layout一样,它也是在JavaScript执行完成后才触发的。
Layout
计算页面上的布局,即元素在文档中的位置及大小。正如前面所述,Layout计算的是布局位置信息。任何有可能改变元素位置或大小的样式都会触发这个Layout事件。
触发Layout的属性非常的多,如果想了解什么属性会触发Layout事件,可以在 CSS Triggers 网站查阅。下图截了一部分:
Rasterizer
光栅化,一般的安卓手机都会进行光栅化,光栅主要是针对图形的一个栅格化过程。低端手机在这部分耗时还是蛮多的。
Paint
页面上显示东西有任何变动都会触发Paint。包括拖动滚动条,鼠标选择中文字等这些完全不改变样式,只改变显示结果的动作都会触发Paint。
Paint的工作就是把文档中用户可见的那一部分展现给用户。Paint是把Layout和Recalculate的计算的结果直接在浏览器视窗上绘制出来,它并不实现具体的元素计算。
Image Decode
图片解码,将图片解析到浏览器上显示的过程。
Image Resize
图片的大小设置,图片加载解析后,若发现图片大小并不是实际的大小(CSS改变了宽度),则需要Resize。Resize越大,耗时越久,所以尽量以图片的原始大小输出。
Composite Layers
最后合并图层,输出页面到屏幕。浏览器在渲染过程中会将一些含有特殊样式的DOM结构绘制于其他图层,有点类似于PhotoShop的图层概念。一张图片在PotoShop是由多个图层组合而成,而浏览器最终显示的页面实际也是有多个图层构成的。
下面这些因素都会导致新图层的创建:
进行3D或者透视变换的CSS属性
使用硬件加速视频解码的 元素
具有3D(WebGL)上下文或者硬件加速的2D上下文的 元素
组合型插件(即Flash)
具有有CSS透明度动画或者使用动画式Webkit变换的元素
具有硬件加速的CSS滤镜的元素
有关于Composite方面的深入剖析,可以阅读《 无线性能优化:Composite 》一文。
像素渲染流水线
通过前面的介绍,在屏幕上最终呈现的页面,是类似于图层一样合并输出到屏幕上的。其实所写的Web页面最终以像素的形式在浏览器屏幕上呈现。这样一来,我们需要理解所写的页面代码是如何被转换成屏幕上显示的像素。这个转换过程可以归纳为这样的一个流水线,主要包含五个关键步骤:
JavaScript :一般来说,我们会使用JavaScript来实现一些视觉变化的效果。比如CSS Animation、Transition和Web Animation API。
Style :计算样式。这个过程是根据CSS选择器,对每个DOM元素匹配对应的CSS样式。这一步结束之后,就确定了每个DOM元素上应该应用什么CSS样式规则。
Layout :布局。上一步确定了每个DOM元素的样式规则,这一步就是具体计算每个DOM元素最终在屏幕上显示的大小和位置。Web页面中元素的布局是相对的,因此一个元素的布局发生变化,会联动地引发其他元素的布局发生变化。比如, 元素的 width 变化会影响其后代元素的宽度。因此,对于浏览器而言, 布局过程是经常发生的 。
Paint :绘制。本质上就是填充像素的过程。包括绘制文字、颜色、图像、边框和阴影等,也就是一个DOM元素所有的可视效果。一般来说,这个绘制过程是在多个层上完成的。
Composite :渲染层合并。前面也说过,对于页面中DOM元素的绘制是在多个层上进行的。在每个层上完成绘制过程之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后在屏幕上呈现。对于有位置重叠的元素的页面,这个过程尤其重要,因为一量图层的合并顺序出错,将会导致元素显示异常。
上述过程的每一步都有可能会发生,因此一定要弄清楚自己的代码将会运行在哪一步。
虽然在理论上,而面的每一帧都是结过上述的流水线处理之后渲染出来的,但并不意味着页面每一帧的渲染都需要经过上述五个步骤的处理。实际上,对视觉变化效果的一个帧的渲染,有三种常用的流水线。
JavaScript/CSS =>计算样式=>布局=>绘制=>渲染层合并
如果你修改一个DOM元素的“Layout”属性,也就是改变了元素的样式(比如 width、 height 或者 position 等),那么浏览器会检查哪些元素需要重新布局,然后对页面激发一个reflow(重排)过程完成重新布局。被reflow(重排)的元素,接下来也会激发绘制过程,最后激发渲染层合并过程,生成最后的画面。
reflow又叫重排,是指浏览器计算页面的全部或部分布局所做的处理。reflow必定会引发重绘,这对于Web的性能影响是极大的。
JavaScript/CSS => 计算样式 =>绘制 =>渲染层合并
如果你修改一个DOM元素的“Paint Only”属性,比如背景图片、文字颜色或阴影等,这些属性不会影响页面的布局,因此浏览器会在完成样式计算之后,跳过布局过程,只会绘制和渲染层合并过程。
JavaScript/CSS => 计算样式 =>渲染层合并
如果你修改一个非样式且非绘制的CSS属性,那么浏览器会在完成样式计算之后,跳过布局和绘制的过程,直接做渲染层合并。这种方式在性能上是最理想的,对于动画和滚动这种负荷很重的渲染,我们要争取使用第三种渲染过程。
通过前面这么多的内容介绍,我们可以得知,影响Web性能主要过程包括Layout、Paint和Composite。那么对于CSS Animation而言,我们的所有操作都是通过CSS的样式控制动画,言外之意,只要是会触发Layout、Paint和Composite的CSS属性都会直接影响动画的性能。在CSS中所有影响Layout、Paint和Composite的属性都可以通过CSS Triggers **网站查阅。那么如何避免达到前面所述的,整个动画尽量避开重排和重绘,只做渲染层合并呢?暂且先不讨论,把这部分放到最后面来讨论。接下来接着先看看其他相关的知识点。
渲染性能
在理解渲染性能之前,我们有必要先了解前面提到的两个概念 重排(也就是回流) 和 重绘 。因为这两者与前面介绍的像素渲染流水线中的 Layout 和 Paint 都有关系,而且Layout和Paint对性能的渲染又有莫大的关系。
Reflow(重排)
Reflow(重排)指的是计算页面布局(Layout)。某个节点Reflow时会重新计算节点的尺寸和位置,而且还有可能触其后代节点Reflow。在这之后再次触发一次Repaint(重绘)
当Render Tree中的一部分(或全部)因为元素的尺寸、布局、隐藏等改变而需要重新构建。这就称为回流,每个页面至少需要一次回流,就是页面第一次加载的时候。
在Web页面中,很多状况下会导致回流:
调整窗口大小
改变字体
增加或者移除样式表
内容变化
激活CSS伪类
操作CSS属性
JavaScript操作DOM
计算 offsetWidth 和 offsetHeight
设置 style 属性的值
CSS3 Animation或Transition
Repaint(重绘)
Repaint(重绘)或者Redraw遍历所有节点,检测节点的可见性、颜色、轮廓等可见的样式属性,然后根据检测的结果更新页面的响应部分。
当Render Tree中的一些元素需要更新属性,而这些属性只是影响元素的外观、风格、而不会影响布局的。就是重绘。
将重排和重绘的介绍结合起来,不难发现: 重绘(Repaint)不一定会引起回流(Reflow重排),但回流必将引起重绘(Repaint) 。
既然如此,那么什么情况之下会触发浏览器的Repaint和Reflow呢?
页面首次加载
DOM元素添加、修改(内容)和删除(Reflow + Repaint)
仅修改DOM元素的颜色(只有Repaint,因为不需要调整布局)
应用新的样式或修改任何影响元素外观的属性
Resize浏览器窗口和滚动页面
读取元素的某些属性( offsetLeft 、 offsetTop 、 offsetHeight 、 offsetWidth 、 getComputedStyle() 等)
可以说Reflow和Repaint都很容易触发,而它们的触发对性能的影响都非常大,但非常不幸的是,我们无法完全避免,只能尽量不去触发浏览器的Reflow和Repaint。
从前面的内容可以了解到,Reflow和Repaint对性能影响很大,那么具体哪些点会影响到渲染性能呢?
影响Layout的属性
当你改变页面上某个元素的时候,浏览器需要做一次重新布局的操作,这次操作会包括计算受操作影响所有元素的几何数,比如每个元素的位置和尺寸。如果你修改了html 这个元素的 width 属性,那么整个页面都会被重绘。
由于元素相覆盖,相互影响,稍有不慎的操作就有可能导致一次自上而下的布局计算。所以我们在进行元素操作的时候要一再小心尽量避免修改这些重新布局的属性。
具体有关于会影响Layout的CSS属性可以在 CSS Triggers 网站中查阅。
影响Repaint的属性
有些属性的修改不会触发重排,但会触Repaint(重绘),现代浏览器中主要的绘制工作主要用光栅化软件来完成。所以重新会制的元素是否会很大程度影响你的性能,是由这个元素和绘制层级的关系来决定的,如果这个元素盖住的元素都被重新绘制,那么代价自然就相当地大。
具体有关于会影响Layout的CSS属性可以在 CSS Triggers 网站中查阅。
如果你在动画里面使用了上述某些属性,导致重绘,这个元素所属的图层会被重新上传到GPU。在移动设备上这是一个很昂贵耗资源的操作,因为移动设备的CPU明显不如你的电脑,这也意味着绘制的工作会需要更长的时间;而上传线CPU和GPU的带宽并非没有限制,所以重绘的纹理上传就自然需要更长的时间。
CSS Triggers 网站中可以得知哪些属性会触发重排、哪些属性会触发重绘以及哪些属性会触合成。但并不是CSS中所有的属性都可以用于CSS Animation和Transition中的。在W3C官方规范中明确定了哪些CSS属性可以用于 Animation 和 Transition中。 @Rodney Rehm 还对这些 属性做过一个兼容测试 。如果你想深入的了解这方面的知识,建议您阅读下面两篇文章:
CSS animatable properties
Thank God We Have A Specification!
如此一来,我们知道可用于CSS Animation或者Transition的CSS属性之后,再配合CSS Triggers 网站,可以轻易掌握哪些CSS属性会触发重排、重绘和合成等。 虽然无法避免,但我们可以尽量控制 。
达内时代科技集团致力于培养面向电信和金融领域Java、C++、C#/.Net、3G/Android、3G/IOS、PHP、嵌入式、软件测试、UID、网络营销、网络工程、会计、UED、web、Unity3D、大数据、童程童美等17大方向中高端软件人才课程与少儿教育课程。选择达内太原it培训,不再孤军奋战,轻轻松松做IT高薪白领。太原达内培训带领有明确目标的学子迈向成功之路!想找工作的求职者可以加QQ:3373924515(太原达内就业服务部)咨询了解。