前言
该markdown作为浏览器篇的骨架,梳理一下有关浏览器的相关知识。
多进程模型
首先肯定的一点,浏览器是一个多进程的应用,而我们常常说的js是单线程的,就是指js引擎是浏览器渲染进程里的一个线程。
-
进程与线程
- 进程是cpu资源分配的最小单位,线程是cpu调度的最小单位
- 不同线程间可以共享进程的资源
- 不同线程间通过信号量和共享锁来保证对同一资源的访问
- 线程可以并发执行
-
浏览器有哪些进程
-
浏览器主进程
- 负责浏览器界面显示,与用户交互。如前进,后退等
- 负责各个页面的管理,创建和销毁其他进程
- 创建网络线程下载需要加载的资源
-
GPU进程
- 用于硬件加速图形绘制
-
渲染进程(也就是我们常说的浏览器内核Webkit, Gecko等)
- 内部是多线程的
- 每个页面一个渲染进程互不影响(Chrome中有一些优化,同一域名下的网站可共用一个渲染进程)
- 用于解析页面,渲染页面,执行脚本,处理事件等等
-
渲染进程
渲染进程与我们前端日常开发生活息息相关,需要着重了解。并且天天喜闻乐见的兼容性问题也是因为各家使用了不同的浏览器内核造成的。渲染进程里有如下线程:
-
GUI渲染线程
- 当浏览器收到响应的html后,该线程开始解析HTML文档构建DOM树,解析CSS文件构建CSSOM,合并构成渲染树,并计算布局样式,绘制在页面上(该处可深挖的坑,HTML解析规则,CSS解析规则,渲染流程细节)
- 当界面样式被修改的时候可能会触发reflow和repaint,该线程就会重新计算,重新绘制,是前端开发需要着重优化的点
- GUI线程与JS引擎线程是互斥的,当JS引擎线程执行的时候GUI线程就会被挂起
-
JS引擎线程
- 一个Tab页内有且只有1个JS引擎线程
- 由于单线程,依靠任务队列来进行js代码的执行,js引擎会一直从任务队列里面取任务执行(Event Loop)
-
事件触发线程
- 将响应各种DOM事件,异步请求的回调,定时器的回调放到不同的任务队列里(主任务,microtask, macrotask)
-
定时触发器线程
- 需要一个单独线程来实现计时的功能,因为单线程不能因为阻塞而导致计时的误差,需要多开一个线程来支持
- 注意,W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms
-
异步http请求线程
- 涉及网络,新开一个线程去做请求,并使用该线程监听状态的改变,如果状态变更则将回调添加到任务队列中去
WebWorker
js引擎线程向浏览器申请开一个子进程,来进行十分耗时的操作。两个线程之间通过postMessage()
进行通信,
参考
- http://www.dailichun.com/2018/03/12/whenyouenteraurl.html
- https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/
- https://segmentfault.com/a/1190000009975744
如果喜欢可以star一下,以后会不断更新github地址
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。