3、探究CSS和JS阻塞问题( 三 )


优化措施:JS侧如何避免回流
措施1:避免频繁操作DOM,可以利用文档碎片,批量操作DOM元素 。
在文档碎片上应用所有DOM操作,最后在将之添加到文档中,如此只引起一次回流 。
var fragment = document.createDocumentFragment()fragment.appendChild(目标);document.body.appendChild(fragment);
措施2:脱离文档流,操作完后在放进文档流 。
elem.style.position='absoulte';...elem.style.position='static';
措施3:可以先为元素设置:none,使之脱离渲染树,操作结束后再显示出来 。
ul.style.display = 'none';...ul.style.display = 'block';
措施4:避免频繁操作样式,最好集中改变 。
// 推荐一次性重写style属性,或将样式集中到一个class上elem.style.cssTxt = 'border-left: 1px; border-right: 2px; padding: 5px;';
措施5:克隆节点,操作完成后,再替换回去 。
const ul = document.getElementById('list');const clone = ul.cloneNode(true);...ul.parentNode.replaceChild(clone, ul);
措施6:使用变量缓存可能造成回流的属性、方法的值,避免频繁读取 。
function init() {for (let i = 0; i < paragraphs.length; i++) {paragraphs[i].style.width = box.offsetWidth + 'px';}}// 修改为const width = box.offsetWidth;function init() {for (let i = 0; i < paragraphs.length; i++) {paragraphs[i].style.width = width + 'px';}}
措施7:能使用CSS3动画的,就不要使用JS动画 。
3、探究CSS和JS阻塞问题
知识点1:CSS不会阻塞DOM解析,但会阻塞DOM的渲染
浏览器的解析渲染过程:解析DOM生成DOM Tree,解析CSS生成CSSOM Tree,两者结合生成渲染树( tree),最后浏览器根据渲染树,将文档渲染至页面 。
DOM Tree的解析和CSSOM Tree的解析互不影响,两者并行,因此,CSS不会阻塞DOM的解析,但由于渲染树的生成依赖DOM Tree和CSSOM Tree,因此,CSS可以阻塞DOM的渲染 。
Documentstyle.css加载完之前,你看不到我浏览器解析到link标签时,将立即开始下载CSS样式表,在完成之前不会渲染页面
知识点2:JS会阻塞DOM解析
JS会阻塞DOM的解析,是因为JS中可能对DOM有很大的修改,对DOM树产生影响 。如果不阻塞,等浏览器解析完标签生成DOM树后,JS若做出修改,则浏览器又得重新解析,再更新DOM树,性能会比较差 。

3、探究CSS和JS阻塞问题

文章插图
JS引擎是独立于渲染引擎存在的,JS代码在文档哪里插入,就在哪里执行 。当HTML解析器遇到一个标签时,浏览器会停止渲染过程,将控制权交给JS引擎 。JS引擎对内联JS代码会直接执行,对外部JS文件,需要先下载脚本,再执行 。等JS引擎运行完毕,浏览器又会把控制权还给渲染引擎,继续CSSOM和DOM的构建 。因此,与其说是JS把CSS和HTML阻塞了,不如说是JS引擎抢走了渲染引擎的控制权 。
实际使用JS时,遵循下面两个原则 。
1、CSS资源优于JS资源引入2、JS尽量少影响DOM的构建
知识点3:CSS会阻塞JS的执行