Abiel1024 / blog

Abiel's blog
8 stars 1 forks source link

解析页面渲染流程 #5

Open Abiel1024 opened 6 years ago

Abiel1024 commented 6 years ago

学习前端很自然的就从html、css和js开始了。当你学习完基础的内容之后,如何才能写出优雅又高效的代码呢?这就得了解其原理了。

总的来说,页面渲染的过程: DOM => CSSOM => Render Tree => Layout => Painting => composite

DOM与CSSOM

构建DOm与CSSOM的过程中,主要通过四个步骤。 字节流(Bytes) → 字符流(characters) → 词语(Tokens)→ 节点(nodes) → object model.

字节流是通过协议获取到的数据,通过解码转换为字符流,也就是日常编写的代码。

拿到字符流之后,浏览器会根据字符流去解释成Tokens,这里在渲染dom时会用HTMLTokenizer类和XSSAuditor。一个进行分析,一个进行验证(安全考虑)。构建CSSOM则会用CSSParser类来实现。

构建渲染树

当DOM树和CSSOM都有了后,就要开始构建渲染树了。 一般来说,渲染树和DOM树相对应的,但不是严格意义上的一一对应。 因为有一些不可见的DOM元素不会插入到渲染树中,如head这种不可见的标签或者display: none等。 整体的流程是这样的: image 创建完RenderObject之后,浏览器就能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。

渲染

创建完RenderObject后,webkit会根据盒模型计算css样式,然后构建出一个渲染树,根据计算的渲染树进行布局,即让浏览器知道哪个节点在屏幕中是哪个位置,样式是什么样子的,这一步成为回流。最后浏览器,要按照计算的数据,将内容显示到屏幕上,这一步称作重绘。所以一个页面显示完成,至少要进行一次回流和重绘。当时当js修改了dom结构或样式,就可能导致了重新布局(Layout)或渲染。 所以回流必将引起重绘,而重绘不一定会引起回流。

回流

意味着元素的内容、结构、位置或尺寸发生了变化,需要重新计算样式和渲染树。

什么会引起回流?

1.页面渲染初始化
2.DOM结构改变,比如删除了某个节点
3.render树变化,比如减少了padding
4.窗口resize
5.最复杂的一种:获取某些属性,引发回流,
很多浏览器会对回流做优化,会等到数量足够时做一次批处理回流,
但是除了render树的直接变化,当获取一些属性时,浏览器为了获得正确的值也会触发回流,这样使得 
浏览器优化无效,包括
    (1)offset(Top/Left/Width/Height)
    (2) scroll(Top/Left/Width/Height)
    (3) cilent(Top/Left/Width/Height)
    (4) width,height
    (5) 调用了getComputedStyle()或者IE的currentStyle

重绘

 元素发生的改变只是影响了元素的一些外观的时候,此时只需要应用新样式绘制这个元素就可以了。

什么会引起重绘?

背景色
边框颜色
文字颜色

回流的成本开销要高于重绘,而且一个节点的回流往往回导致子节点以及同级节点的回流, 所以优化方案中一般都包括,尽量避免回流。

针对回流优化方案。

减少逐项更改样式,最好一次性更改style,或者将样式定义为class并一次性更新
避免循环操作dom,创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添 加到window.document
避免多次读取offset等属性。无法避免则将它们缓存到变量
将复杂的元素绝对定位或固定定位,使得它脱离文档流,否则回流代价会很高

最后一点,又会涉及到另一个知识点。

简单层与复合层 渲染中的绘制,可以结合复合层和简单层的概念来讲。 首先,普通文档流内可以理解为一个复合图层(这里称为默认复合层,里面不管添加多少元素,其实都是在同一个复合图层中) 其次,absolute布局(fixed也一样),虽然可以脱离普通文档流,但它仍然属于默认复合层。 然后,可以通过硬件加速的方式,声明一个新的复合图层,它会单独分配资源 (当然也会脱离普通文档流,这样一来,不管这个复合图层中怎么变化,也不会影响默认复合层里的回流重绘) 可以简单理解下:GPU中,各个复合图层是单独绘制的,所以互不影响,这也是为什么某些场景硬件加速效果一级棒 可以Chrome源码调试 -> More Tools -> Rendering -> Layer borders中看到,黄色的就是复合图层信息

将该元素变成一个复合图层,就是传说中的硬件加速技术 具体可以参考http://web.jobbole.com/83575/