前端为什么操作DOM的成本是昂贵的
引起成本增加的主要原因:重绘和重排(回流)
重排(回流):渲染树(render tree)的元素的内容、结构、位置或尺寸发生了变化,需要重新计算样式和渲染树
重绘 :节点的一些样式(背景色,边框颜色,文字颜色等)发生改变,只需要应用新样式绘制这个元素就可以了;
重排必定会引起重绘
如果上面看不懂,不妨了解一下浏览器的渲染过程
浏览器渲染过程
在输入URL后,浏览器的执行操作:查找缓存 —> 没有找到则 查询DNS —> 封装http请求为一个TCP请求包 —> 服务器解析请求返回请求资源 HTML (如果是http2.0,则还会推送其他js、css、img等静态资源)—> 浏览器拿到HTML之后开始解析、渲染。
-
解析HTML,构建DOM树(这里遇到外链,此时会发起请求 link 或者 script标签)
-
解析CSS,生成CSS规则树
-
合并DOM树和CSS规则,生成render渲染树
-
根据渲染树对各元素尺寸、位置的计算布局
-
绘制渲染树,绘制页面像素信息
-
浏览器会将各层的信息发送给GPU,GPU将各层合成,显示在屏幕上
而每次操作DOM都会带来样式和渲染树的重新计算也就是所谓的重排(回流)和重绘,消耗GPU资源。
为了减少重绘和重排,可以采用几点措施:
-
避免逐个修改节点样式,尽量一次性修改
-
将需要多次修改的DOM元素缓存
-
可以将需要多次修改的DOM元素设置
display:none,操作完再显示。(因为隐藏元素不在render树内,因此修改隐藏元素不会触发回流重绘) -
将复杂的节点元素脱离文档流,降低回流成本
-
将CSS的引入文件放在文件头部,js引入文件放到尾部
普通的脚本会阻塞浏览器解析,加上defer或async属性,脚本就变成异步,可等到解析完毕再执行。
-
async异步执行,异步下载完毕后就会执行,不确保执行顺序,一定在onload前
-
defer延迟执行,相对于放在body最后
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
