浏览器渲染原理和性能优化 红太狼 2022-05-09 04:28 239阅读 0赞 **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
还没有评论,来说两句吧...