减少js操作dom
js引擎与渲染引擎相互独立,
- js操作dom过程开销大
- 操作到了dom层面会触发渲染树的变化,触发
回流与重绘
开销大
让js给dom分压
js处理完操作后,最后给dom
- 缓存变量
let container = document.getElementById('container')
let content = ''
for(let count=0;count<10000;count++){
// 先对内容进行操作
content += '<span>我是一个小测试</span>'
}
// 内容处理好了,最后再触发DOM的更改
container.innerHTML = content
- DOM Fragment 对象 代替真实的dom元素
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)
- 事件循环
js运行过程中,会先将全局上下文压入执行栈,然后执行同步代码,遇到异步代码则放入任务队列,当执行栈空,会从任务队列中取出任务执行,这个过程就是事件循环,
执行完毕,渲染页面
任务队列
分为macro(宏任务)队列和 micro(微任务)队列。
常见的 macro-task 比如: setTimeout、setInterval、 setImmediate、script(整体代码)、 I/O 操作、UI 渲染等。
常见的 micro-task 比如: process.nextTick、Promise.then、MutationObserver 等。
取异步任务的时候先微再宏
更新 DOM 的时间点
,应该尽可能靠近渲染的时机。当我们需要在异步任务中实现 DOM 修改时,把它包装成 micro 任务
是相对明智的选择。