DOM编程
- 访问和修改DOM元素
- 修改DOM元素的样式会导致重绘和重排
- 通过DOM事件处理与用户交互
浏览器通常会把DOM和JavaScript独立实现。两个独立的功能只要通过彼此的接口链接,就会产生消耗。访问的次数越多,产生的消耗越多,所以尽量减少过桥的次数。
DOM的访问和修改
1. innerHTML比DOM(document.createElement)方法更快
2. 节点克隆:使用DOM方法更新页面的另一个方法就是克隆已有元素,而不是创建新的元素。
html集合
1. document.getElementByxxxx返回的都是html集合。这类集合是类数组。有数组length属性,但是没有push()和slice()等方法。每次迭代,读取元素集合的length就会引发集合的更新。这对于浏览器来说有很明显的性能问题。
2. 优化方法: 把集合的长度缓存到一个局部变量里,然后在循环条件退出语句使用该变量。
3. 访问集合元素时使用局部变量:一般来说,对于任何类型DOM访问,需要多访问一次DOM属性或方法,最好使用一个局部变量缓存此成员。
遍历DOM
- 获取DOM元素:通常我们需要某一个DOM元素开始,操作周围的元素,或者递归查找所有的子节点。你可以使用childNOdes得到元素集合,或者使用nextSibling来获取每个相邻元素。
- 选择器API:根据合适的情景,选择getElementByxxxx和queryselect,建议使用queryselct速度比较快
重绘和重排
浏览器下载完所有的组件,会解析生成两种数据结构
- DOM树:表示页面结构
- 渲染树:表示DOM节点如何显示
重排何时发生
1. 添加或删除可见的DOM元素
2. 元素位置改变
- 元素尺寸改变
- 内容改变
- 页面渲染器初始化
- 浏览器窗口尺寸改变
渲染树变化的排队与刷新
优化:不要在布局信息改变时查询它,把读取的代码放在末尾
最小化重绘和重排
- 改变样式: 一次性改变多个样式
- 批量修改DOM
减少重绘和重排步骤:
- 使元素脱离文档流
- 对元素应用多重改变
- 把元素带回文档中
方法:
- 通过改变display属性,临时从文档中移除元素,然后再恢复它
- 在文档之外创建并更新一个文档片段,然后把它附加到原始列表里,
- 为需要修改的节点创建一个备份,然后对副本进行操作,一旦操作完成,就用新的节点代替旧的节点。
var old = document.getElementById('mylist')
var clone = old.cloneNode(data)
appendDataToElement(clone, data)
old.parentNode.replaceChild(clone, old)
缓存布局信息
浏览器尝试通过队列化修改和批量执行的方式最小化重排次数。所以查询布局信息时,尽量减少布局查询的次数,获取后把他赋值给局部变量,然后操作局部变量。
让元素脱离动画流
使用以下步骤可以避免页面中大部分重排
- 使用绝对位置定位页面上的动画元素,将其脱离文档流
- 让元素动起来,当他扩大时,会临时覆盖部分页面。但这只是页面的一小区域的重绘,不会产生重排并重绘页面的大部分内容
- 当动画结束时恢复定位,从而只会下移一次文档的其他元素。
IE和hover
当有大量的hover会降低相应速度
事件委托
使用事件委托减少处理器的数量