关于CSS和JS如何阻塞浏览器渲染DOM,提出优化方案

  • dom解析:将页面上的标签、属性、文本档转换成dom对象,构建dom树
  • css解析:将css代码解析,构建css树
  • dom tree加css tree=render tree(渲染树) -->渲染页面

浏览器渲染流程:

  1. 浏览器开始解析目标HTML文件,执行流的顺序为自上而下。
  2. HTML解析器将HTML结构转换为基础的DOM(文档对象模型),构建DOM树完成后,触发DomContendLoaded事件。
  3. CSS解析器将CSS解析为CSSOM(层叠样式表对象模型),一棵仅含有样式信息的树。
  4. CSSOM和DOM开始合并构成渲染树,每个节点开始包含具体的样式信息。
  5. 计算渲染树中个各个节点的位置信息,即布局阶段。
  6. 将布局后的渲染树显示到界面上。
    渲染原理
    根据以上的流程,可以知道,当cssdom还没构建完成时,页面是不会渲染到浏览器界面的,这也是为什么当css下载过慢时,会出现白屏的现象。

link css不会堵塞DOM解析

//在头部插入<script defer src="/js/logDiv.js"></script>
const div = document.querySelector('div');
console.log(div);

但是会堵塞页面渲染;

<header>
    <link rel="stylesheet" href="/css/sleep3000-common.css">
    <script src="/js/logDiv.js"></script>
</header>

script会堵塞DOM解析;

const arr = [];
for (let i = 0; i < 10000000; i++) {
  arr.push(i);
  arr.splice(i % 3, i % 7, i % 5);
}
const div = document.querySelector('div');
console.log(div);

浏览器遇到 script 标签时,会触发页面渲染

<body>
	<div></div>
	<script src="/js/sleep3000-logDiv.js"></script>
	<style>
		div {
			background: lightgrey;
		}
	</style>
	<script src="/js/sleep5000-logDiv.js"></script>
	<link rel="stylesheet" href="/css/common.css">
</body>

如果想script不堵塞dom解析,我们可以给script标签加defer/async属性;当浏览器遇到script标签,且script没有defer和async属性的时候,会触发页面渲染。如果script标签前面有css资源,会等到css资源加载完毕再执行script脚本

优化方案:
script最好放底部,link最好放头部,如果头部同时,script和link的情况下,最好将script放在link上面

Defer和async的区别:

  1. 执行时机不同:
    defer的脚本在dom解析完后,触发DOMContentLoad事件前执行
    async脚本一旦加载完毕,就会执行(不论是在dom解析阶段还是DOMContentLoad之前之后,但是一定是在window.load之前执行)
  2. 执行顺序不同:
    defer能保证多个脚本按照书写顺序执行
    async不能保证多个脚本的执行顺序
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值