Fork me on GitHub

前端性能优化与原理实践之【DOM 优化原理与实践】

前端性能优化与原理实践之 DOM 优化原理与实践!

一、DOM 优化思路

1.1 问题:为什么操作 DOM 那么慢?

JS 引擎和渲染引擎是独立实现的,当我们使用 JS 去操作 DOM 的时候,本质上就是“跨界”操作。每次“跨界“的操作过程性能的开销是非常大的,同时修改 DOM 的过程也是非常慢的。所以我们要尽量减少 DOM 的操作。

1.2 优化:减少访问 DOM 次数

优点:通过字符串先将 DOM 结点进行拼接,拼接好之后,再插入一次,只会发生一次重绘。

缺点:但是本地的字符串操作不是非常的快。

1
2
3
4
5
6
7
8
9
10
// 错误示范
for(var count=0;count < 10000;count++){
document.getElementById('container').innerHTML+='<span>我是一个小测试</span>'
}

// 优化
let container = document.getElementById('container')
for(let count=0;count<10000;count++){
container.innerHTML += '<span>我是一个小测试</span>'
}

1.3 进一步优化:DOM Fragment

考虑 JS 的运行速度,比 DOM 快得多这个特性。我们减少 DOM 操作的核心思路,就是让 JS 去给 DOM 分压DomcumentFragment 的实现更加的优雅。

DocumentFragment 不是真实 DOM 树的一部分,它的变化不会引起 DOM 树的重新渲染的操作(reflow),且不会导致性能等问题。

1
2
3
4
5
6
7
8
9
10
11
12
let container = document.getElementById('container')
// 创建一个DOM Fragment对象作为容器
let content = document.createDocumentFragment()
for(let count = 0;count < 10000;count++){
// span此时可以通过DOM API去创建
let oSpan = document.createElement("span")
oSpan.innerHTML = '我是一个小测试'
// 像操作真实DOM一样操作DOM Fragment对象
content.appendChild(oSpan)
}
// 内容处理好了,最后再触发真实DOM的更改
container.appendChild(content)