浏览器渲染原理
Request请求阶段:
浏览器(客户端) -- DNS解析,TCP三次握手和四次挥手 --> 服务器端
Response响应阶段
服务器端 -- 网页源代码,HTTP状态码,304缓存,HTTP响应报文 --> 浏览器
解析渲染
浏览器拿到代码后,从内存中开辟一块栈内存为代码执行提供环境;
同时,分配一个主线程去逐行解析代码(因此JS是单线程的)。
代码每一行都存在栈内存里面,每次执行完一行代码,该行代码都会出栈,即从栈内存删除。
<!DOCTYPE html> //每行执行完出栈 ... <link href="..."> ... <img src="..."> ... <script href="..."> ...
每个<link>,<image>和<script>都会创建一个新的线程去执行这些标签引用的代码(script执行JS,单线程)。
因此我们说,浏览器是多线程的但是JavaScript是单线程的。
然后,浏览器会开辟一个任务队列(Task Queue)来执行这些线程。
第一次自上而下读取:生成DOM树
浏览器的主线程同时继续从上往下读取并且执行HTML代码,最终生成DOM树。页面的内容获得了。
接着,浏览器把Task Queue里面已经解析完的任务出队,并把它放入栈内存执行。执行完成后,再去Task Queue里面获取已解析完的任务...这个过程被称为事件循环(Event Loop)。
Task Queue里面的任务分为微任务和宏任务,微任务优先级较高。
注意:解析时HTML时,浏览器遇<script>标签会去执行JS它而非往下读,阻塞HTML解析。这是因为浏览器并不知道Js里面是否有document.write,如果有的话就白解析了。
事件循环完成后生成CSSOM。页面的样式获得了。
DOM+CSSOM结合,成为渲染树(Rendar Tree)。
回流/布局(Layout):加载页面至少会执行一次,且引起重绘和重排。
计算图像在屏幕窗口上的实际具体位置和大小并生成Layout Tree。
display:none的元素不会出现在Layout tree但是会出现在DOM Tree里。
div:before等伪类内content的内容会出现在Layout tree而不会出现在DOM tree里。
重绘(Painting)
根据渲染树回流得到的信息得到节点的绝对像素并绘制样式,创建绘制记录表存储绘制顺序。
如果用DOM tree的顺序绘制会导致出错,例如Z-index属性出问题。
当我们改变一个元素的尺寸位置时,会导致浏览器重新进行布局计算以及后面流程,这个过程叫做重排。
当我们改变一个元素的颜色样式时,会导致浏览器重新进行样式计算以及后面流程,这个过程叫做重绘。
当页面内有JS,重绘和重排时主线程也会执行Js,二者会争夺主线程,影响页面性能,因此要尽量避免重绘重排。
requestAnimationFrame(),React Fiber和CSS3的Transform可以让页面在不影响性能的情况下展示动画效果。
展示(Display)
GPU读取渲染树,绘制并且显示网页。
chrome:是多进程浏览器,包括浏览器进程,网络进程,缓存进程,渲染器进程,GPU进程和插件进程。
多进程浏览器的好处?
每个tab都是一个单独的进程,这样当一个tab出现问题的时候,不会连累整个浏览器进程。
知识点的应用:减少HTTP的请求次数和大小以优化网页性能
1. 通过减少css和js的引入,压缩图片或者使用精灵图来实现资源合并压缩。
2. 图片懒加载,即生成DOM树之后再加载图片,且页面滚动到哪里就加载哪里。
3. 音视频走流文件,即边用边加载。

浙公网安备 33010602011771号