参考 高性能javascriptjavascript
文档对象模型(DOM)是独立于语言的,用于操做XML和HTML文档的程序接口API,在浏览器中主要经过DOM提供的API与HTML进行交互,浏览器一般会把DOM和javascript独立实现,这意味着当咱们经过javascript操做DOM的时候势必的产生性能上的开销,所以提高页面性能的的思路是尽量的减小DOM操做或者优化DOM操做css
DOM的访问与修改html
(1)减小频繁的读取DOM元素java
(1)for(var i = 0;i < 10;i++) { document.getElementById("test") += "a"; } //上面的代码每次循环都进行了读取
(2)var content = ""; for(var i = 0;i < 10;i++) { content += "a"; } document.getElementById("test").innerHTML = content; //只有在最后一次经过innerHTML进行了读取 当咱们更新一段html是使用innerHTML代替原始的dom操做
(2)节点克隆node
当须要建立大量类似的节点的时候,经过element.clonenode()复制相应的节点,来代替重复的建立相应的节点来提高一部分的性能数组
(3)处理HTML集合浏览器
当咱们经过document.getElementsByTagName() document.getElementsByClassName() document.getElementsByName() 返回的是nodelist 它是一种类数组的集合,咱们能经过下标的方式查找到集合中的元素缓存
一样的经过下面的属性获得的也是html集合 dom
document.images | document.links | document.forms | document.forms[0].elements |
操做html集合会出现性能的问题是html集合是维持实时的状态,也就是当你在文档中添加一个元素的时候,这个时候你在经过特定的方式获取html集合的长度的时候它的长度是实时变化的,html集合与文档处于链接的状态,获取html的信息的时候须要进行查询操做。布局
处理html集合元素有大体两种方式:
3.1将html集合转换成数组,由于遍历数组相对于遍历集合更快
function toArray(coll) { for(var i = 0,a = [],length = coll.length;i < len;i++) { a[i] = coll[i]; } return a; }
3.2减小集合的查询操做,缓存局部变量
function test(coll) { var length = coll.length; var id = ""; for(var i = 0;i <length;i+=1) { var el = coll[i]; id = el.getAttribute("id"); console.log(id); } }
(4)选取dom元素
4.1 使用能区分元素节点的选择API
属性名 | 被替代的属性 |
children | childNodes |
childElementCount | childNodes.length |
firstElementChild | firstChild |
lastElementChild | lastChild |
nextElementSibling | nextSibling |
previousElementSibling | previousSibling |
上面的第一列属性只会返回相应的元素节点(两个节点之间的空格也会被识别成文本节点) 当咱们经过第二列属性进行操做的时候,就须要在进行一步过滤的操做,增长了开销
4.2 使用选择器API
当须要进行大量的组合操做的时候,经过document.querySelectorAll()来进行元素的选择,经过这种方式获取的是一个nodelist,但它不与文档进行实时的更新,是一种静态的列表
(5)重绘与重排
当下载完页面的组件后,就会生成两个页面结构 DOM树 表示页面的结构 渲染树 表示DOM节点如何被显示 每个在DOM树中须要被显示的元素在渲染树中至少存在一个对应的节点(在渲染树中的节点称为帧或者盒),当DOM的变化影响了元素的几何属性(宽高)的时候,这样浏览器就会从新计算元素的几何尺寸,其余元素的几何尺寸也会受到相应的影响,浏览器会使渲染树中受到影响的部分失效并从新构造渲染树,这个过程叫作重排,完成重排后浏览器从新绘制受到影响的部分,这个过程就叫作重绘
重绘和重排都是代价昂贵的操做,因此优化的方案是最小化重绘和重排
重排发生的时机
浏览器会优化重排的过程,经过队列的方式修改并批量的执行重拍的过程,可是当咱们使用一些属性或者方法的时候,会强制的刷新渲染队列触发重排,当咱们频繁的进行这些操做的时候,就会形成性能的开销
优化的思路:
(1)集中操做 将设置样式和获取样式进行分离(不要在布局信息改变的时候去进行查询操做),而且尽量的合并操做
var el = document.getElementById("test"); el.style.cssText = "border-left:1px;border-right:2px;border-bottom:3px;";
(2)批量的修改DOM的时候,能够经过下面的方式减小重绘与重排
脱离文档流的方案
(3)缓存布局信息 这个思路有点像处理集合元素的时候的方案,经过缓存局部的布局信息,能减小强制刷新渲染队列的次数,也就减小了重排
(4)动画元素的处理 其实思路是同样的 动画有可能会形成大量其余元素位置改变,当动画开始的时候,让它脱离文档流,进行动画的展现,动画完结后让它回到文档流