Open Abiel1024 opened 6 years ago
学习前端很自然的就从html、css和js开始了。当你学习完基础的内容之后,如何才能写出优雅又高效的代码呢?这就得了解其原理了。
总的来说,页面渲染的过程: DOM => CSSOM => Render Tree => Layout => Painting => composite
构建DOm与CSSOM的过程中,主要通过四个步骤。 字节流(Bytes) → 字符流(characters) → 词语(Tokens)→ 节点(nodes) → object model.
字节流是通过协议获取到的数据,通过解码转换为字符流,也就是日常编写的代码。
拿到字符流之后,浏览器会根据字符流去解释成Tokens,这里在渲染dom时会用HTMLTokenizer类和XSSAuditor。一个进行分析,一个进行验证(安全考虑)。构建CSSOM则会用CSSParser类来实现。
当DOM树和CSSOM都有了后,就要开始构建渲染树了。 一般来说,渲染树和DOM树相对应的,但不是严格意义上的一一对应。 因为有一些不可见的DOM元素不会插入到渲染树中,如head这种不可见的标签或者display: none等。 整体的流程是这样的: 创建完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/
起
学习前端很自然的就从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等。 整体的流程是这样的: 创建完RenderObject之后,浏览器就能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。
渲染
创建完RenderObject后,webkit会根据盒模型计算css样式,然后构建出一个渲染树,根据计算的渲染树进行布局,即让浏览器知道哪个节点在屏幕中是哪个位置,样式是什么样子的,这一步成为回流。最后浏览器,要按照计算的数据,将内容显示到屏幕上,这一步称作重绘。所以一个页面显示完成,至少要进行一次回流和重绘。当时当js修改了dom结构或样式,就可能导致了重新布局(Layout)或渲染。 所以回流必将引起重绘,而重绘不一定会引起回流。
回流
什么会引起回流?
重绘
什么会引起重绘?
回流的成本开销要高于重绘,而且一个节点的回流往往回导致子节点以及同级节点的回流, 所以优化方案中一般都包括,尽量避免回流。
针对回流优化方案。
最后一点,又会涉及到另一个知识点。
简单层与复合层 渲染中的绘制,可以结合复合层和简单层的概念来讲。 首先,普通文档流内可以理解为一个复合图层(这里称为默认复合层,里面不管添加多少元素,其实都是在同一个复合图层中) 其次,absolute布局(fixed也一样),虽然可以脱离普通文档流,但它仍然属于默认复合层。 然后,可以通过硬件加速的方式,声明一个新的复合图层,它会单独分配资源 (当然也会脱离普通文档流,这样一来,不管这个复合图层中怎么变化,也不会影响默认复合层里的回流重绘) 可以简单理解下:GPU中,各个复合图层是单独绘制的,所以互不影响,这也是为什么某些场景硬件加速效果一级棒 可以Chrome源码调试 -> More Tools -> Rendering -> Layer borders中看到,黄色的就是复合图层信息
将该元素变成一个复合图层,就是传说中的硬件加速技术 具体可以参考http://web.jobbole.com/83575/