资源加载和页面事件
domLoading
浏览器开始解析dom树的时间点
domInteractive
表示浏览器已经解析好dom树了。
domContentLoaded
同步的JS已经执行完毕了。
这里需要再解释一点:
由于同步JS会阻塞Dom的解析,因此在有同步JS的情况下,domInteractive和domContentLoaded的区别不大。
如果JS添加了defer属性,那么domInteractive和domContentLoaded的时间差取决于JS的下载和执行时间。defer JS表示告诉浏览器,这段JS在domInteractive后执行。见http://www.w3.org/TR/html5/syntax.html#the-end 。一旦执行完defer JS,就会触发domContentLoaded.
如果JS属性为async,那么domContentLoaded和domInteractive又几乎没什么区别了,因为js的解析不会阻塞dom,也不阻塞domContentLoad事件。
onload
页面上的元素已经加载完毕了。包括所有CSS, JS, Image等等。
一些小实验
疑问1:同步的JS通过document.write写入JS script会不会延迟DomContentLoaded?
结论:会。从例子中可以看到,DomContentLoaded必须等到同步写入的JS文件写完才触发。
代码:
<html>
<head>
</head>
<body>
<script>
document.write('<script src="t/wait-3s.js"' + '></' + 'script>');
</script>
{{flush 1000}}
<h1>Hello World</h1>
</body>
</html>
时间线:
疑问2: 同步的JS动态插入defer JS会不会延迟DomContentLoaded?
结论:不会延迟comContentLoaded,但会阻塞onload的时间。需要补充的是,即便是动态插入没有defer的JS,也不会延迟DomContentLoaded.
对于如下代码:
<html>
<head>
</head>
<body>
<script>
var script = document.createElement('script');
script.src= "/t/wait-2s.js";
script.defer = true;
document.head.appendChild(script);
</script>
{{flush 1000}}
<h1>Hello World</h1>
</body>
</html>
时间线如下:(蓝色为主文档,黄线为JS文件)
疑问3:如果在domContentLoaded的时刻动态插入(同步/defer/async)的script,会不会阻塞onload事件?
结论:(同步/defer/async)均会阻塞onload事件。
代码(以defer为例):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
document.addEventListener('DOMContentLoaded', function(){
var script = document.createElement('script');
script.src= "/t/wait-2s.js";
script.defer = true;
document.head.appendChild(script);
});
</script>
{{flush 1000}}
<h1>Hello World</h1>
</body>
</html>
时间线:
上面的两个小实验应证的是规范中的:Spin the event loop until the
set of scripts that will execute as soon as possible
andthe list of scripts that will execute in order as soon as possible
are empty.
疑问三:如果在domContentLoaded时动态插入CSS/图片/iframe,会阻塞onload事件吗?
结论:会阻塞。动态插入的图片/CSS会阻塞onload事件,iframe不会。
代码(以image为例):
<html>
<head>
</head>
<body>
<script>
document.addEventListener('DOMContentLoaded', function(){
var img = document.createElement('img');
img.src= "/t/wait-2s.png";
document.body.appendChild(img);
/*
var link = document.createElement('link');
link.rel = "stylesheet";
link.href = "t/wait-3s-red.css";
document.body.appendChild(link);
*/
/*
var iframe = document.createElement('iframe');
iframe.src = "t/wait-3s.html";
document.body.appendChild(iframe);
*/
});
</script>
{{flush 1000}}
<h1>Hello World</h1>
</body>
</html>
结果:
【更多待补充...】
原文地址:https://www.cnblogs.com/jlfw/p/12677795.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- mysqldump命令详解 Part 8 其他的一些的参数的介绍
- mysqldump命令详解 Part 6- --master-data参数的使用
- 腾讯云语音识别.net-sdk使用笔记0818
- mysqldump命令详解 Part 9 mysqldump命令总结
- [MySQL学习笔记] 3.mysqldump命令详解 Part 2 -备份全库
- [MySQL学习笔记]1. MySQL测试数据的构造
- [MySQL学习笔记]2. mysqldump命令详解 Part 1
- 怎样在PF_ring上使用RSS实现网络流量负载均衡
- Docker镜像原理 aufs overlay overlay2
- Zabbix 5.0 LTS 安装
- 技术博客测试: Elasticsearch
- Oracle基本参数(COMPATIBLE)
- Oracle基本参数(CONTROL_FILES)
- Oracle基本参数(DB_BLOCK_SIZE)
- Oracle基本参数(DB_CREATE_FILE_DEST,DB_CREATE_ONLINE_LOG_DEST_n)