在网上发现了一篇很好的博客文章,对浏览器进程线程、Web Workers、Event Loop 等都解释得通俗易懂。在此,我根据其内容做了几张思维导图,对照着文章看可加深理解。如有更好的理解,欢迎探讨。
博客地址是: http://www.dailichun.com/2018...
目录
1、区分进程和线程
在系统的任务管理器中可以查看当前正在运行的各种进程。
2、浏览器是多进程的
打开 chrome 的任务管理器,可以看到当前浏览器里的进程。在这里浏览器应该也有自己的优化机制,有时候打开多个tab页后,可以在Chrome任务管理器中看到,有些进程被合并了,如下图:
3、重点是浏览器内核(渲染进程)
请牢记,浏览器的渲染进程是多线程的
4、Browser进程和浏览器内核(Renderer进程)的通信过程(文章原图)
- Browser进程收到用户请求,首先需要获取页面内容(譬如通过网络下载资源),随后将该任务通过RendererHost接口传递给Render进程
- Renderer进程的Renderer接口收到消息,简单解释后,交给渲染线程,然后开始渲染
- 渲染线程接收请求,加载网页并渲染网页,这其中可能需要Browser进程获取资源和需要GPU进程来帮助渲染,当然可能会有JS线程操作DOM(这样可能会造成回流并重绘)
- 最后Render进程将结果传递给Browser进程
- Browser进程接收到结果并将结果绘制出来
5、WebWorker与SharedWorker
本质上就是进程和线程的区别。SharedWorker由独立的进程管理,WebWorker只是属于render进程下的一个线程
6、浏览器渲染流程(文章原图)
- 解析html建立dom树
- 解析css构建render树(将CSS代码解析成树形的数据结构,然后结合DOM合并成render树)
- 布局render树(Layout/reflow),负责各元素尺寸、位置的计算
- 绘制render树(paint),绘制页面像素信息
- 浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上。
7、Event Loop(结合 ES6 的 microtask 与 macrotask)
简单版:
复杂版:
检验是否理解事件循环,不依靠控制台,猜一下下面的结果:
提示: async 会返回 Promise 对象; await 会等待 Promise 对象完成,期间会让出线程。
async function async1(){
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start')
setTimeout(function(){
console.log('setTimeout')
},0)
async1();
new Promise(function(resolve){
console.log('promise1')
resolve();
}).then(function(){
console.log('promise2')
})
console.log('script end')
再看看修改版的结果会是啥:
async function async1(){
console.log('async1 start')
await async2()
console.log('async1 end')
}
function async2(){ // 去掉了 async 关键字
console.log('async2');
}
console.log('script start')
setTimeout(function(){
console.log('setTimeout')
},0)
async1();
new Promise(function(resolve){
console.log('promise1')
resolve();
}).then(function(){
console.log('promise2')
})
console.log('script end')
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。