同步:同一时间只能做一件事
异步:同一时间做多件事情
1.JS引擎线程
js 内核,js引擎,负责处理执行JavaScript脚本代码,也是JS中的主线程
js是单线处理代码,负责调配其他子线程来处理异步代码
js单线程异步
2.GUI渲染线程
负责渲染浏览器界面 解析HTML树 css树 构建DOM树 reader树
3.事件监听线程
用来处理事件的监听,click mouseover
4.计时器线程
负责处理定时器
5.网络线程
处理http请求
浏览器渲染线程
渲染前奏:
1.浏览器url地址栏中输入网址
2.会进行http请求(域名解析,三次握手,四次挥手)等待服务器的响应,开始下载对应的资源
3.将下载的资源交给GUI渲染引擎进行处理
4.渲染引擎开始进行渲染....
渲染的概念:
-
DOM Tree: 浏览器将HTML解析成树形的数据结构
-
CSS Rule Tree:将css解析成树形的数据结构
-
Render Tree:DOM树和CSS树合并后产生的渲染树
-
layout:根据render Tree 浏览器将每个节点的定位、宽高和从属关系,计算出每个节点在屏幕中的位置
-
painting:按照计算出来的规则,通过显卡,把内容绘制到屏幕上
-
reflow(回流):当浏览器的页面布局发生改变,需要重新生成DOM Tree、cssTree 、renderTree,然后根据渲染树重新进行页面布局,然后绘制
-
repaint(重绘):当浏览器中某个元素的样式(背景颜色,边框颜色),然后去重新绘制样式
异步加载
js加载脚本时也是一个同步的过程,js加载会影响整页面的效率,需要对工具方法进行按需加载,需要用到的时候再加载
js中的异步加载方案:
-
defer异步加载,要等到dom文档全部解析完成之后才会执行
-
async异步加载,只要js文件加载完就执行,
只能加载外部链接的js文件
-
按需加载
js加载时间线
时间线:浏览器解析页面时,记录一系列按照顺序做的事情
-
创建Document对象、创建Element对象,开始解析HTML页面和节点中的内容添加到Element对象和Text对象中去。这个阶段document.readyState = 'loading'。
-
遇到link外部css,创建线程加载,并继续解析文档。并发
-
遇到script外部js,并且没有设置async、defer,浏览器创建线程加载,并阻塞,等待js加载完成并执行该脚本,然后继续解析文档。
js拥有修改dom的能力-->domcument.write
-
遇到script外部js,并且设置有async、defter,浏览器创建线程加载,并继续解析文档。
-
async属性的脚本,脚本加载完成后立即执行。
-
defter等待整个完档解析完之后再执行。
-
document.createElement('script')的方式动态插入script元素来模拟async属性,实现脚本异步加载和执行。
-
-
遇到img等,浏览器创建线程加载,并继续解析文档。并发
-
当文档解析完成,document.readyState = 'interactive'。文档解析完成
-
文档解析完成后,所有设置有defer的脚本会按照顺序执行。(注意与async的不同)
-
document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。
-
当所有async的脚本加载完成并执行后、img等加载完成后,document.readyState = 'complete',window对象触发load事件。
-
从此,以异步响应方式处理用户输入、网络事件等。