前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 ><script> 脚本以及 <link> 标签对 DOM 解析渲染的影响

<script> 脚本以及 <link> 标签对 DOM 解析渲染的影响

原创
作者头像
coldPlayer
发布2023-11-04 23:40:39
4150
发布2023-11-04 23:40:39
举报

script脚本对DOM的影响

当HTML解析器解析HTML,如果遇到script标签,普通的script标签会暂停对DOM解析渲染,因为该脚本可能会修改DOM。

这里有三种情况:普通脚步、defer、async。 ==<font color=red >defer、async只对外联script脚本文件有效, 内联script脚本设置无效。</font>==

问: script标签总是会触发Paint吗?

回答: script标签时,会触发一次Paint,浏览器会将script标签之前的元素渲染出来。但也并不是所有的script标签都会触发Paint。head中的script标签是不会触发的,毕竟此时body还没有解析,触发Paint也看不到任何内容。 inline(内联:将代码直接嵌入到HTML文档的元素中,而不是通过外部文件引用的方式) 的 script也不会触发Paint。因此,建议script标签放在body结束标签之前,这样不会不会阻塞页面整体内容的DOM解析和渲染。

1、普通脚本

  • 文档解析过程中,如果遇到普通脚本就会直接下载脚本,下载会阻止DOM的解析渲染
  • 如果是多个脚本,则并行下载,不论哪个先下载完,都要按HTML中的顺序执行,即使后面的比前面的先下载完,也要等前面的执行完才能执行
  • 执行脚本会阻止页面的解析渲染
  • 执行完脚本继续页面的解析渲染
  • 执行完script脚本和页面解析渲染完, 才会依此触发DOMContentLoadedloaded事件2、defer,
  • 文档执行时,当遇到有defer属性的script标签时,则脚本的下载则在后台运行,下载不会阻止DOM解析渲染
  • 多个defer属性的script标签,则在后台并行下载
  • 脚本的执行需要等到页面解析完成才能进行
  • 当页面解析渲染完毕后, 会等到所有的defer脚本下载完毕并按照顺序执行,执行完毕后会触发DOMContentLoaded事件。
  • 如果defer脚本下载较慢,在下载完前, 页面解析渲染已完毕; 等所有的defer脚本下载完后, 才按照顺序执行defer脚本。执行完毕后会触发DOMContentLoaded事件。3、async
  • 文档解析时,当遇到有async属性的script标签时,则脚本的下载则在后台运行,下载不会阻止DOM解析渲染
  • 多个async属性的script标签,则在后台同时并行下载
  • async脚本的执行会阻止页面的解析渲染
  • 遵循先下载完先执行,执行不按照HTML页面的中脚本顺序
  • async脚本的下载和执行不计入DOMContentLoaded事件统计。

link标签对DOM的影响

1、link标签不会阻塞DOM解析但会阻塞DOM渲染

link标签并不阻塞DOM的解析,但会阻塞DOM的渲染。浏览器并行解析生成DOM Tree 和 CSSOM Tree,当两者都解析完毕,才会生成render tree,页面才会渲染。所以应尽量减小引入样式文件的大小,提高首屏展示速度。

注意:案例中CSS资源为外网资源,所以并不会直接就加载出来,可以在页面看到渲染的过程,当然可以直接开vpn,css资源几乎秒加载,页面也秒渲染

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<script>
		setTimeout(() => {
			console.log(document.getElementById('num'));
		}, 0);
		document.addEventListener('DOMContentLoaded', () => {
			console.log('dom parse done');
		})
	</script>
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.css">
</head>
<body>
	<div id="num">
		i am content a.
	</div>
	<div>
		i am content b.
	</div>
</body>
</body>
</html>

初始加载页面的时候,控制台打印出来两条数据,但是页面并没渲染,此时CSS资源正在加载中

在这里插入图片描述
在这里插入图片描述

之后CSS资源一直加载,直到加载失败,页面才渲染完成,说明,link标签加载CSS资源时阻止了页面渲染

在这里插入图片描述
在这里插入图片描述

2、link标签会阻塞JS执行

JS运行时,有可能会请求样式信息,如果此时还没有加载和解析样式,js就有可能会得到错误的回复,产生很多问题。因此浏览器在link标签的加载和解析过程中,会禁止脚本运行。

案例一

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
	<tilte>title</title>
		<script>
			console.log(Date.now());
		</script>
		<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.css">
		<script>
			console.log(Date.now());
		</script>
</head>
<body>
	<div id="num">
		i am content a.
	</div>
	<div>
		i am content b.
	</div>
</body>
</body>
</html>

初始页面加载,此时CSS资源正在加载中,所以body中的内容还没渲染出来,并且link标签下的script中的console也还未执行,所以说,link标签加载CSS资源时也阻塞的JS的执行

在这里插入图片描述
在这里插入图片描述

之后,因为CSS资源加载失败,所以开始执行下面的script,并且打印出console内容-当前时间。

在这里插入图片描述
在这里插入图片描述

案例二

代码语言:javascript
复制
<html>
<head>
    <tilte>title</title>
    <!--大文件,加载时间长-->
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.css">
</head>
<body>
    <div>
        i am content a.
    </div>
    <!--js小文件,加载时间短-->
    <script src='test.js'></script>
    <div>
        i am content b.
    </div>
</body>
</html>

页面初始加载时,CSS资源一直在加载,body中的script一直没有加载出来,可以看到控制台并没有打印任何东西。所以说link标签会阻止JS执行

在这里插入图片描述
在这里插入图片描述

当CSS资源加载完成或者加载失败后就执行了script脚本,可以看到控制台打印出来js执行完毕,且此时页面已经渲染出来

在这里插入图片描述
在这里插入图片描述

3、link和@import的区别

  • 用法:
代码语言:javascript
复制
<link href="a.css" rel="stylesheet" type="text/css">

<style>
@import url('b.css');
</style>
  • 功能上:link功能较多,可以定义 RSS、Rel 等,而@import只能用于加载 css;
  • 加载顺序:
    • link标签让浏览器知道这是个样式表文件,html的解析和渲染不会暂停,css文件的加载是同时进行的,这不同于在style标签里面的内置样式;@import添加的样式是在页面载入之后再加载,这可能会导致页面因重新渲染而闪烁。
    • @import会影响浏览器的并行下载,使得页面在加载时增加额外的延迟,增添了额外的往返耗时,而且多个@import可能会导致下载顺序紊乱。比如: 一个css文件index.css包含了以下内容:@import url(“reset.css”),那么浏览器就必须先把index.css下载、解析和执行后,才下载、解析和执行第二个文件reset.css
  • DOM操作:link支持DOM操作改变样式,由于 DOM 方法是基于文档的,无法使用@import的方式插入样式
  • 兼容性:@import是 CSS2.1提出的语法,老版本的浏览器可能不支持;link标签作为 HTML 元素,不存在兼容性问题。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • script脚本对DOM的影响
    • 1、普通脚本
    • link标签对DOM的影响
      • 1、link标签不会阻塞DOM解析但会阻塞DOM渲染
        • 2、link标签会阻塞JS执行
          • 案例一
          • 案例二
        • 3、link和@import的区别
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档