IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> css、js的加载是否阻塞DOM的解析与渲染 -> 正文阅读

[JavaScript知识库]css、js的加载是否阻塞DOM的解析与渲染

首先说一下浏览器渲染页面的流程:
浏览器内核(渲染进程)拿到静态资源后,渲染大概可以划分成以下几个步骤:

  • 解析html构建dom树
  • 解析css构建render树(将CSS代码解析成树形的数据结构,然后结合DOM合并成render树)
  • 布局render树(Layout/reflow),负责各元素尺寸、位置的计算
  • 绘制render树(paint),绘制页面像素信息
  • 浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上。

从以上步骤可以得出几个结论:
1.html和css的加载和解析是异步的,不会互相干扰
2.只有等dom树和cssom树构建完成并且合并成render树之后,页面才开始渲染,所以css的加载不会影响dom的解析,但会影响dom的渲染

根据以上的基本结论,我们开始探索js加载和html、css的关系:

一、JS 会阻塞 DOM 解析

当解析器遇到script标签时(不带有async/defer属性),浏览器会停止DOM的解析,会一直等到该script的加载并执行后,才继续往下解析。比较合理的解释就是,首先浏览器无法知晓JS的具体内容,倘若先解析DOM,万一JS内部全部删除掉DOM,那么浏览器就白忙活了,所以就干脆暂停解析DOM,等到JS执行完成再继续解析。

二、CSS 会阻塞 JS 的执行

css的加载会阻塞js的执行,这一点不是很好理解,看以下代码:

<head>
  <link rel="stylesheet" href="./style.css?sleep=3000"> //假设css的加载会花3s
  <script src="./index.js"></script>
</head>
<body>
  <p>hello world</p>
</body>

我们从head开始解析,首先遇到link标签,去加载css(加载需要3s),此时浏览器不会停下来,会继续往下解析,然后遇到script标签,开始加载js,js很快就加载完了,但是js不会马上执行,因为它会等到上面的css资源加载完成之后再开始执行。从而导致了下面的p标签一直没有得到解析,因为上面说了js是会阻塞DOM的解析的,浏览器会等到js执行了才会继续往下解析DOM。

千万不要认为是css的加载阻塞了DOM的解析!

流程是:css和js可以同时去加载—>css加载很慢,即使js已经加载完了也会等到css加载完了才开始执行—>js一直不执行所以阻塞了DOM的解析

那么为什么js明明都加载完了,还要等css加载完才开始执行呢?

可以这样理解,浏览器并不知道js中的代码会干些什么,js可以去改动DOM,也可以获取/改变css样式。js要获取正确的样式就必须等css加载完

三、js会触发页面的渲染

大概意思是,浏览器在解析时,如果遇到了script标签,会先渲染一次这个script标签之前的DOM,然后再去加载和执行js。因为js是可以操作DOM的,如果浏览器不先去渲染一次,js获取的DOM就会是null。比如:

<body>
    <p id="box1">world</p>
    <script>
        console.log(document.getElementById('box1'));
        console.log(document.getElementById('box2'));
    </script>
    <p id="box2">hello</p>
</body>

上面代码的js是可以获取到id为box1的p标签,但是不能获取box2的p标签,原因很简单,因为script在box2前面。js执行的时候,box2还没有被解析和渲染。

另外说一下,浏览器解析DOM时,虽然会一行一行向下解析,但是它会预先加载具有引用标记的外部资源(例如带有src标记的script、link标签),而在解析到此标签时,则无需再去加载,直接运行,以此提高运行效率。

以上参考:https://juejin.cn/post/6973949865130885157

四:关于script的async/defer属性

关于两者的区别,先直接上图:

蓝色线代表网络读取(加载),红色线代表js执行,这俩都是针对脚本的;绿色线代表 HTML 解析
在这里插入图片描述
这张图可以说是非常清晰了,结论:

  • 没有 defer 或 async,浏览器会立即加载并执行脚本,并且会阻塞DOM的解析
  • 有 async,浏览器立即加载脚本,加载的时候不会阻塞DOM解析,加载完了会立即执行,js执行时会阻塞DOM解析。如果有两个async的标签,两者的执行顺序也无法预料,是谁先加载完就谁先执行,这一点很不可控
  • 有 defer,浏览器立即加载脚本,加载的时候不会阻塞DOM解析,但是 js执行要在DOM解析完成之后,DOMContentLoaded 事件触发之前。如果有两个defer的标签,两者的执行顺序是按照加载顺序来的,谁先加载谁先执行
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-01 15:38:21  更:2022-05-01 15:39:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:15:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码