1. 浏览器进程
1. 浏览器的多进程架构
- 一个好的程序常常被划分为几个相互独立又彼此配合的模块,浏览器也是如此。
- 以 Chrome 为例,它由多个进程组成,每个进程都有自己核心的职责,它们相互配合完成浏览器的整体功能,
- 每个进程中又包含多个线程,一个进程内的多个线程也会协同工作,配合完成所在进程的职责。
- Chrome 采用多进程架构,其顶层存在一个 Browser process 用以协调浏览器的其它进程。
2. 浏览器的主要进程与功能
详见下面的思维导图
2. 浏览器渲染流程
- 解析 HTML 文件,构建 DOM 树,同时浏览器主进程负责下载 CSS 文件
- CSS 文件下载完成,解析 CSS 文件成树形的数据结构,然后结合 DOM 树合并成 RenderObject 树,CSSOM 的解析过程与 DOM 的解析过程是并行的。
- 布局 RenderObject 树 (Layout/reflow),负责 RenderObject 树中的元素的尺寸,位置等计算,计算图层布局
- 绘制 RenderObject 树 (paint),绘制页面的像素信息,绘制图层
- 浏览器主进程将默认的图层和复合图层交给 GPU 进程,GPU 进程再将各个图层合成(composite),最后显示出页面,整合图层成界面
3. 一些题解
1.为什么js是单线程
这是因为 Javascript 这门脚本语言诞生的使命所致!
JavaScript 为处理页面中用户的交互,以及操作 DOM 树、CSS 样式树来给用户呈现一份动态而丰富的交互体验和服务器逻辑的交互处理。
如果 JavaScript 是多线程的方式来操作这些 UI DOM,则可能出现 UI 操作的冲突。
如果 Javascript 是多线程的话,在多线程的交互下,处于 UI 中的 DOM 节点就可能成为一个临界资源,
假设存在两个线程同时操作一个 DOM,一个负责修改一个负责删除,那么这个时候就需要浏览器来裁决如何生效哪个线程的执行结果。
当然我们可以通过锁来解决上面的问题。但为了避免因为引入了锁而带来更大的复杂性,Javascript 在最初就选择了单线程执行。
2. 为什么js阻塞页面加载
js能够操作dom,如果在修改dom的时候渲染界面,那么渲染线程先后获得的元素数据可能会不一致,为了防止渲染出现不可预期的结果,GUI渲染线程与js引擎线程互斥,js引擎执行时,GUI线程被挂起,保存在队列中等到js引擎线程空闲时立即被执行,因此如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
3. css加载会造成阻塞吗
dom和cssdom是并行构建的,所以css加载不会阻塞dom的解析,然而,由于 Render Tree 是依赖于 DOM Tree 和 CSSOM Tree 的,
所以他必须等待到 CSSOM Tree 构建完成,也就是 CSS 资源加载完成(或者 CSS 资源加载失败)后,才能开始渲染。因此,CSS 加载会阻塞 Dom 的渲染。
4. 优化策略
1. css样式表优化:
SS 引擎查找样式表,对每条规则都按从右到左的顺序去匹配
eg:
#myList li {
}
查找所有的li,并且每次去确认这个li的父元素id是不是myl