一、当前chrome多进程架构
- 浏览器主进程:主要负责界面展示,用户交互,子进程管理,同时提供缓存功能
- 渲染进程:解析,渲染页面,JS执行,合成网页图片。运行在沙箱环境中
- 网络进程:负责网页的网络资源加载
- 插件进程:负责插件的运行
- GPU进程:进行页面绘制
多进程架构优点:
- 进程相互隔离,一个页面或者插件崩溃,只会影响当前页面进程
- 每个页面都是独立渲染进程,有一个出现死循环或者渲染问题,不会影响其他页面
- 渲染进程和插件进程运行在沙箱中,恶意程序无法获取系统权限
缺点:
- 更多的资源占用和内存消耗
二、渲染进程相关线程
- GUI渲染线程:负责渲染页面,解析HTML,CSS,生成render tree;布局绘制,重绘重排等
- JS引擎线程:与线程1互斥,解析运行JS
- 事件触发线程:当事件被触发(click,ajax等)
- 定时触发器线程:(setTimeout,setInterval)
- 异步http请求线程:处理XMLHttpRequest
- 合成线程:GUI渲染线程后执行,将GUI渲染线程生成的待绘制列表=》位图
- IO线程:通信
由此引申,CSS和JS是否阻塞DOM渲染和解析
- CSS不会阻塞DOM的解析,但会阻塞DOM的渲染(影响render tree的生成)
- JS会阻塞DOM的解析(JS可能会操作DOM)
- CSS会阻塞后面JS的执行(线程互斥,JS可能会操作CSSOM)
三、输入url到页面展示的过程
- 合成URL:判断是搜索还是网址
- DNS域名解析:在浏览器和客户端之间是递归查找,在本地DNS和根域及其子域之间是迭代查找
- 建立TCP连接:三次握手,SSL/TLS
- 发送HTTP请求,服务器处理请求,返回响应结果(判断强缓存和协商缓存等)
- 关闭TCP连接,四次挥手
- 浏览器渲染
四、浏览器渲染
准备渲染进程:
- 新增渲染进程:1.每个标签对应一个渲染进程 2.从一个页面打开了另一个新页面,新页面不是同一个站点
- 复用渲染进程:从一个页面打开了另一个新页面,新页面是同一个站点
渲染阶段:
1.构建DOM树:
字节流 Bytes=》分词器Tokens =》生成节点Node =》DOM树
display:none的img标签,会加载图片资源,原因:仍然会在dom树中进行加载,只是不会被渲染
2.样式计算(生成CSSOM)
CSS =》 document.styleSheets =》标准化样式表中的属性 =》计算每个节点的具体样式
3.生成布局树(render tree)
* 遍历DOM树中的所有可见节点, 并把这些节点加到布局中
* 不可见的节点会被布局树忽略掉, 如head标签下面的全部内容, 和display: none属性的元素
4.图层构建(生成图层树)
* 拥有层叠上下文属性的元素会被提升为单独的一层
* 需要剪裁的地方也会被创建为图层
5.图层绘制
生成图层绘制的绘制列表,提交给合成线程,按照绘制列表执行绘制操作
6.分块
由于图层大小可能远大于视口的大小,所以合成线程会把图层分割成图块
7.栅格化
将视口附近的图块生成位图,非像素=》像素等
8.合成和显示
讲页面内容绘制到内存中,最后再将内存显示在屏幕上
回流(重排reflow)
- 添加或删除可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化
- 内容发生变化
- 浏览器窗口尺寸变化
由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。但是,当你获取布局信息的操作的时候,会强制队列刷新
- offsetTop、offsetLeft、offsetWidth、offsetHeight
- scrollTop、scrollLeft、scrollWidth、scrollHeight
- clientTop、clientLeft、clientWidth、clientHeight
- getComputedStyle()
- getBoundingClientRect