js执行是单线程,并不是说整个浏览器都是单线程的,姑且就成为单线程吧
js单线程的原因是为了避免多线程操作dom,引发的并发问题,dom属于基础数据,从多线程上讲,对它的操作要加事物,而js的操作最初就是为了操作dom,嗯,幸好是单线程的,总之一句话,凡是能够修改dom的一定得同步
浏览器解析html页面过程中,整个js运行的状态分为三个状态
loading:页面开始解析的准备
创建了document,节点,文本,准备将所有的节点注入到document中
document.readState=loading;
interactive:页面解析中
解析页面上的所有html
1、遇到css(头部样式、link),独立开启一个线程下载;创建cssDom继续解析
2、遇到js:
<script></script>或者<script src="1.js">,终止解析(html解析阻塞)
<script></script>:一边读取 一边执行
<script src="1.js">:先下载,执行js
3、遇到js:(异步引入)
<script async src = "1.js"></script>
独立一个线程,继续解析(边解析边下载),文件下载完毕回立即执行js(解析停止:html解析阻塞)
4、遇到js:(异步引入)
<script dafer src = "1.js"></script>
继续解析,不会引起阻塞
defer会先上下载文件,等html结构解析完毕后在执行js
5、继续解析 img、iframe等
先解析结构,对应标签的 src 异步处理下载资源
6、html结构解析完成
document.readState=interactive
当状态变更为interactive时,
底层会触发一个事件:DOMContentLoaded
DOMContentLoaded(只能用事件监听器绑定)
complete:页面解析完毕
填充图片、资源填充
document.readState=complete