【浏览器基础架构】
单进程浏览器不详述,简单描述多进程浏览器
Process为一个进程,以Chome浏览器为例,存在Browser Process,Renderer Process,Plugin Process,GPU Process等做各种事务的处理
Site Isolation机制,默认开启,允许在一个Process下中的iframe使用单独的进程渲染
【输入网址后发生了什么】
Browser Process 主进程进行处理
1. UI Thread,判断输入的是网址还是非网址(非网址进行搜索操作)
2. Network Thread,开始发送网址请求,获取响应,同时做一个Safe安全检查防止恶意网站,通过后根据响应内容定位,是下载则去下载管理器,是HTML则返回通知UI Thread,UI会安排一个Renderer Process进程来渲染页面
3. Renderer Process渲染页面(包括进行JS运算)
额外操作
1. 点击浏览器Browser Process控制的返回按钮,主页按钮之类的事件,会触发通知Renderer Process来处理
2. 页面中的location.href,点击外链跳转之类,由Renderer Process通知Browser Process进行URL变更
请求操作
1. URL会先从本地DNS缓存中查找
2. 如果没有则去DNS服务器查询,如果查找不到则返回失败,查找到了则开始建立连接
3. TCP/IP会执行连接的三次握手,建立连接后发送HTTP请求
【Renderer Process渲染过程】
渲染过程包含几个主要线程:主线程mt,工作线程wt,排版线程ct,光栅线程rt
1. 构建DOM,由mt开始构建
2. 下载图片,js文件,css文件等,由mt在构建DOM过程中一一请求,同时Network Thread会同时帮忙下载
3. 遇到<script>标签会停止DOM构建先行运行JS(使用async则不会阻塞)
4. 计算样式,解析CSS
5. html解析树与CSS解析树结合,构建Layout Tree(Render Tree)
6. 合成帧,光栅线程会对每层做栅格化处理,合成层,存放在GPU显存,GPU进行绘制
【Renderer Process如何处理绑定事件】
当存在绑定事件的时候,渲染过程会将该节点绑定事件并将整个节点标记,发生在该标记节点内的事件都会向主线程请求执行绑定的JS代码,这时候会产生等待,假设设置了最顶层元素的绑定事件,则每次操作都会向主线程请求而发生等待
【优化】
【1. 首次关键路径渲染优化】
1. 减少关键资源数量(阻塞)
1.1 优化CSS元素数量与搜索方式(因为Render树需要等待CSSDOM渲染,所以会阻塞)
1.2 优化JS文件加载(script标签会阻塞解析DOM,并且需要CSSDOM加载完成才能执行)
1.2.1 async 浏览器解析被async修饰的js文件不会阻塞解析器,会继续解析DOM,同步下载js文件并马上执行
1.2.2 defer 同async,不同在于脚本会同步下载但必须在文档解析后才执行(DOMContentLoaded之前)
PS:DOM加载结束调用DOMContentLoaded方法,同JQuery的ready方法,重新绑定
2. 减少获取关键资源的总时间
3. 减少关键资源的总大小
3.1 缩小代码注释与空格(可以使用uglify.js或gzip压缩)
3.2 HTTP缓存
【2. 重绘回流优化】
1. 重绘: 元素样式改变不会改变元素在文档流中的位置,浏览器只是重新绘制
2. 回流:某部分元素的尺寸结构或某些属性发生了改变,浏览器需要重新渲染整个或部分文档(包含:页面首次渲染,浏览器窗口变化,元素尺寸位置字体改变,新增或删除DOM元素,激活:hover伪类)
PS:浏览器会将重绘回流的所有操作,存放在队列进行批处理,但获取高度宽度方法会立即清空队列,保证获取的是最新的数值
如何优化:
css类的表达式有时无法避免,主要进行js的优化
1. 避免频繁操作样式,避免频繁操作DOM,可以使用documentFragment进行批处理
2. 将元素设为display:none,在该元素上的DOM操作不会触发重绘与回流
3. 复杂动画设置在绝对定位的元素上,脱离文档流,避免频繁回流
【3. 图片优化】
懒加载
【4. 事件优化】
事件委托
【5. 页面优化】
防抖与节流
【Vue性能优化】
TODO
【为什么打开了一个页面,系统打开了四个进程】
chrome多进程浏览器,打开一个页面同时需要1个网络进程,1个浏览器进程,1个GPU进程和1个渲染进程
【参考文档】