当前位置: 首页 > Web前端 > HTML

浏览器回流和重绘

时间:2023-04-02 15:04:04 HTML

浏览器渲染流程从上图可以看出,浏览器渲染流程如下:解析HTML生成DOM树,解析CSS生成CSSOM树,结合DOM树和CSSOM树生成渲染树renderTreeLayout(reflow):根据生成的渲染树,reflow(Layout)获取节点的几何信息(位置,大小)Painting(redraw):根据渲染树和reflow获取的几何信息,获取节点的绝对像素Display:将像素发送给GPU在页面上显示。生成渲染树(RenderTree)为了构建渲染树,浏览器主要完成以下任务,从DOM树的根节点开始遍历每个可见节点。对于每个可见节点,在CSSOM树中找到对应的规则,并应用它们。根据每个可见节点及其对应的样式,组合生成渲染树。第一步,既然说到遍历可见节点,那么首先要知道哪些节点是不可见的。不可见节点包括:一些不会渲染输出的节点,如script、meta、link等。一些通过css隐藏的节点。例如显示:无。请注意,被可见性和不透明度隐藏的节点仍将显示在渲染树上。只有带有display:none的节点不会显示在渲染树上。回流(Layout)在我们构造渲染树之前,我们将可见的DOM节点和它们对应的样式组合在一起,但是我们还需要计算它们在设备视口(viewport)中的确切位置和大小。这个计算的阶段是reflow。浏览器为了找出每个对象在网站上的确切大小和位置,从渲染树的根节点开始遍历,在回流阶段,我们需要根据具体的将其转换为实际的像素值视口的宽度重绘(Painting)通过重排(Layout)阶段,我们知道了所有可见节点的样式和具体的几何信息(位置、大小),然后我们就可以将渲染树的每个节点转换为实际的渲染树节点屏幕像素,这个阶段称为重绘节点。reflow重绘发生时reflow阶段是计算节点的几何信息和位置,所以当页面布局或几何信息发生变化时,需要reflow。添加或删除可见的DOM元素元素的位置和大小发生变化当页面开始渲染时(这肯定是不可避免的)浏览器视口的大小发生变化(因为回流是根据浏览器的大小计算元素的位置的viewportandsize)注意:回流一定会触发重绘,重绘(非几何信息变化的样式)不一定会引起回流。回流reflow的成本高于repaint重绘。节点和对等节点的回流;根据变化的范围和程度,渲染树或多或少的部分需要重新计算,有些变化会触发整个页面的重新排列,例如出现滚动条或修改根节点时。基于回流(Layout)和重绘(Painting)的优化方式避免了对现代浏览器优化机制的干扰。在现代浏览器中,由于每次回流和重绘都需要额外的计算消耗,所以会通过队列。通过优化修改并批量执行来优化流程。浏览器会将修改操作放入队列中,等待一段时间或达到某个阈值后才会清空队列。但是当获取到布局信息时,队列会被强制刷新,例如:offsetTop,offsetLeft,offsetWidth,offsetHeightscrollTop,scrollLeft,scrollWidth,scrollHeightclientTop,clientLeft,clientWidth,clientHeightgetComputedStyle()getBoundingClientRect()以上方法都需要获取最新的布局信息,所以浏览器会强制刷新队列并进行回流和重绘,以获取最新的信息。所以我们在修改样式的时候,尽量避免使用上面的属性和方法。如果我们一定要使用它们,我们可以先缓存它们,然后再把它们放在一起。CSS的修改方法考虑如下代码constel=document.getElementById('el')el.style.padding='xxx'el.style.margin='xxx'el.style.border='xxx'几何信息这里元素的修改了3次,但是现代浏览器会缓存它,但是如果在这期间通过上面列出的属性和方法访问到位置信息,就会触发3次回流和重绘。所以建议通过cssText或者class方法修改一次。el.style.cssText+='border-left:1px;右边框:2px;padding:5px;';//或el.className+='xxx';批量修改DOM当我们需要对DOM进行一系列修改时,可以通过以下方式减少回流重绘的次数:隐藏元素,应用修改,重新显示functionappendDataToElement(appendToElement,data){letli;for(leti=0;inodeflashmulti-transparency做css动画其他优化使用translate代替oftopchange:top会触发reflow,而前者不会用opacity代替visibility:前者不会触发reflow和redraw(前提是在单层),后两者会触发不使用table布局,表格的一个小改动可能会引起回流,影响性能,尽量使用div。动画实现的速度选择:为新的动画层启用GPU硬件加速:使用transform:translateZ(0)和transform:translate3d(0,0,0)启用GPU硬件加速CSS和JS块DOM解析和渲染在此方式通过标签时,为了给最好放在底部(防止阻塞DOM解析)。最好放在头部(为渲染过程提供样式)。如果头部同时有放在之上(以免CSS脚本加载时间过长,导致js等待时间过长)dddefer和async直接看图,绿色代表html解析,蓝色代表javascript脚本下载,红色代表javascript脚本执行。