1. 渲染原理:
(1)处理HTML生成DOM树
(2)处理CSS生成CSSDOM树
(3 )将两树合并成render树
(4 )对render树进行布局计算
(5)将render树中的每一个节点绘制到屏幕上
细化分析:
1.浏览器把获取到的html代码解析成1个Dom树,html中的每个标签都是Dom树中的1个节点,根节点就是我们常用的document对象(<html> tag),当然这里包含用js动态创建的dom节点
2浏览器把所有样式(主要包括Css和浏览器的默认样式设置)解析成样式结构体,在解析的过程中会去掉浏览器不能识别的样式,生成CSSDOM树
3.DOM tree和CSSDOM tree合并成render tree,render tree中每个node都有自己的style,而且render tree不包含隐藏的节点(比如display:none的节点,还有无样式head节点),因为这些节点不会用于呈现,而且不会影响呈现的,注意visillty:hiddedn隐藏的元素还是会包含到render tree中的,因为vsibilt:hidden会影响布局(ayout),会占有空间。
4.render tree构建完毕之后根据样式计算布局,布局阶段的输出结果称为“盒模型”( box model)。盒模型精确表达了窗口中每个元素的位置和大小,而且所有的相对的度量单位都被转化成了屏幕上的绝对像索位置(根据css2的标准,render tree中的每个节点都称为box(Box dimensions---盒子模型) , box所有属性:width,height,margin,padding,left,top,border等。)
5.将这些信息渲染为屏幕上每个真实的像素点了。这个阶段称为"绘制”, 或者“栅格化
2. 重绘、重排
(1 )我们计算它们在当前设备中准确的位置和尺寸。这正是布局阶段要做的的工作,该阶段在英语中也被称为“回流”( reflow),当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。也会回流(其实我觉得叫重新布局更简单明了些)。每个页面至少需要一-次回流,就是在页面第一-次加载的时候。
(2)重绘(repaints )当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color.则就叫称为重绘。
(3)重绘,重排会影响性能, 在浏览器的performance(性能)下,刷新看执行时间
蓝色:网络通信和HTML解析
黄色: JavaScript执行
紫色:样式计算和布局,即重排
绿色:重绘
(4)触发重排的方法:
以下这些属性和方法需要返回最新的布局信息,重新计算渲染树,就会造成回流,能发重排以返回正确的值。建议将他们合并到一起操作,可以减少回流的次数。
这些属性包括:
offsetTop. offsetLeft. offsetWidth, offsetHeight ; scrolTopscrolleft. scrollWidth. scrollHeight ; dientTop. clientLeft. clientWidth、dientHeight ; getComputedStyleO、currentStyle( ).
提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。
DOM变动和样式变动,都会触发重新渲染。但是,浏览器已经很智能了,会尽量把所有的变动集中在一起, 排成一一个队列
然后一次性执行,尽量避免多次重新渲染div.style.color = 'red';
div.style.background='yellow';div.style.left = '10px';div.style.width = '20px';
但是浏览器只会触发一次重排和重绘。
般来说,样式的写操作之后,如果有上面那些属性的读操作,都会引发浏览器立即重排,这种重排,不会形成之前队列优化div.style.color= 'red';
var height = div.offseHeight;div.style.height = height + 'px';
Bad :
div.style.left = div.offsetLeft + 'px';div.style.top = div.offsetTop+ 'px';
重排重绘两次
Good:
Var left = div.offsetLeft + 'px';Var top = div.offsetTop+ 'px';div.style.left = left;div.style.top = top;
放到队列一次执行重排重绘一次
我们来测试一下js动态添加10000个li不同颜色而且设置宽度所耗费renderpainting的时间吧
(5)理论上的解决优化办法:
1.DOM的多个读操作(或多个写操作), 应该放在一起。 不要两个读操作之间,加入一个写操作。
2.离线操作DOM如使用隐藏元素documentcreateDocumentFagment() cloneNode();
3.修改样式的时候添加类名,或次性添加到dom.style.cssText上等
3. 3D属性可以提高性能
(1)尽可能的多用硬件能力,使用3D属性来开启GPU加速,前提是用户电脑性能较好,因为3D效果会消耗更多的内存。
-webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
-webkit-transform: rotate3d(1,1,1,30deg);
-moz-transform: rotate3d(1,1,1,30deg);
-ms-transform: rotate3d(1,1,1,30deg);
transform: rotate3d(1,1,1,30deg);
(2)注意:如果动画过程中有闪烁现象,常出现在动画开始的时候,可以尝试下面的hack方法:测试出来的方法
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-bisibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;
(3)还有比如:transform:translate3d()移动效果的流畅度,远高于任性形式下的left属性值变化(animation,transition,JavaScript定时器等)
(4)尽可能的避免使用box-shadow阴影和gradients渐变,这个两个属性是页面性能杀手
(5)尽可能的让动画元素不在文档流中,及减少重排
position:fixed;
position:absolute;
(6)优化DOM reflow