前端性能优化:写出高性能的JavaScript

减少浏览器的repaint/reflow

1.什么是浏览器的repaint/reflow

页面在加载的过程中,需要对文档结构进行解析,同时需要结合各种各样的样式来计算这个页面长什么样子,最后再经过浏览器的渲染页面就出现了。这整个过程细说起来还是比较复杂,其中充满了repaint和reflow。对于DOM结构中的各个元素都有自己的盒子模型,这些都需要浏览器根据各种样式(浏览器的、开发人员定义的等)来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow;当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为repaint。

在页面加载完成后,用户的一些操作、脚本的一些操作都会导致浏览器发生这种行为。

2.如何触发浏览器的repaint/reflow

DOM元素的添加、修改(内容)、删除( Reflow + Repaint) 仅修改DOM元素的字体颜色(只有Repaint,因为不需要调整布局) 应用新的样式或者修改任何影响元素外观的属性 Resize浏览器窗口、滚动页面 读取元素的某些属性(offsetLeft、offsetTop、offsetHeight、offsetWidth、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()、currentStyle(in IE))

3.为什么要避免repaint/reflow

每一次触发repaint/reflow都会导致祖先节点和子节点重新渲染

4.如何避免触发repaint/reflow

Fast because there’s no repaint/reflow(通过避免repaint/reflow提高js性能) Techniques:
  • –Remove element from the document, make changes, insert back into document( 先将元素从document中删除,完成修改后再把元素放回原来的位置)
  • –Set element’s display to “none”, make changes, set display back to default(将元素的display设置为”none”,完成修改后再把display修改为原来的值)
  • –Build up DOM changes on a DocumentFragment then apply all at once(如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入document)

DocumentFragment

JS中提供了一个DocumentFragment的机制,相信大家对这个并不陌生,它可以提供一个缓冲的机制,将DOM节点先放到内存中,当节点都构造完成后,再将DocumentFragment对象添加到页面中,这时所有的节点都会一次渲染出来,这样就能减少浏览器很多的负担,明显的提高页面渲染速度。

function CreateNodes(){

for(var i = 0;i < 10000;i++){

var tmpNode = document.createElement(“div”);
tmpNode.innerHTML = “test” + i + ” <br />”;
document.body.appendChild(tmpNode);//每次循环都要执行一次appendChild,也就是触发了reflow

}
}

function CreateFragments(){

var fragment = document.createDocumentFragment();//构造缓存空间

for(var i = 0;i < 10000;i++){

var tmpNode = document.createElement(“div”);
tmpNode.innerHTML = “test” + i + “<br />”;
fragment.appendChild(tmpNode);//把节点缓存到缓存空间中
}

document.body.appendChild(fragment);//最后一次提交
}

发布了46 篇原创文章 · 获赞 8 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章