浏览器渲染原理
概念说明:
- TTFB: 请求发送到请求首字节返回的时间
- 宏观视角下的浏览器
- 进程和线程之间的关系, chrome启动一个页面有几个进程
- 计算机网络的七层模型
- HTTP的请求流程
- 从输入URL地址到页面显示发生了什么
1. 宏观视角下的浏览器
wireshark抓包工具
- 为什么是谷歌浏览器
- 因为chrome edge以及国内的大多数浏览器都是基于chrominum二次开发的, 而chrome是目前全球使用率最高的浏览器
- C/S架构和B/S架构
- C/S => client/Server (app 客户端)
- B/S => browser/Server (基于浏览器的客户端)
- 为什么学习浏览器原理
- 准确的评估一个项目的可行性
- 从更高的维度审视页面(工程化, 动画卡顿,性能优化)
- 快速迭代中掌握页面的本质
2. 进程和线程
-
进程就是在任务管理器中运行的应用程序
- 进程是操作系统资源分配的基本单位,进程中包含线程
- 在内存中独占一个内存空间
- 进程和进程之间相互隔离
-
线程: 就是进程中最小执行单位
- 一个进程是由多个线程组成
- 每个线程之间都是在内存中相互隔离的
- 线程是由进程所管理的,为了提高浏览器的安全性和稳定性, 浏览器采用了多进程模型
-
浏览器中的5个进程
- 浏览器主进程
- 负责页面显示,用户交互,子进程管理, 提供存储等
- GPU进程
- 3D绘制提高性能
- 插件进程
- chrome安装插件或者扩展插件的功能
- 渲染进程
- 每个页卡都有单独的渲染进程, 核心用于渲染页面
- 网络进程
- 主要用于处理网络资源加载(html, css, js等)
- 浏览器主进程
3. 从输入URL地址到页面显示发生了什么
- 用户输入url会开始导航, 如果是关键字,会将关键字根据默认的引擎生成地址,会在浏览器进程中导航,
- 浏览器进程会准备一个渲染进程用于渲染页面,
- 通过网络进程加载资源, 最终将加载的资源交给渲染进程来处理
- 渲染完毕后显示, 进程之间的通信使用ipc
浏览器发送请求链接是怎样处理的?
- 请求先去查找缓存, 检测缓存是否过期, 直接返回缓存中的内容
- 看域名被解析过,将域名通过DNS解析为ip地址, dns解析是基于
udp的, 解析出的ip + 端口号找到对应的资源 - 开始发送请求,请求是https, 会有ssl协商,保证数据的安全性
- 利用ip地址进行寻址, 排队等待, 同一个时间在http1.1中只能发送6个请求
- tcp创建链接用于传输,(三次握手)
- 利用tcp进行传输数据(分包传输), 传输的过程是有序的, 安全可靠,有序, 服务器会按照顺序来接收进行重组
- 发送通过http请求(请求行, 请求头, 请求体)
- 默认不会断开(keep-alive), 为了下次传输数据时, 可以服用上次创建的链接
- 服务器收到数据后, 需要进行http请求(请求行, 请求头,请求体)进行解析, 解析完毕后给客户端一个响应(响应行,响应头,响应体)
- 服务器返回会有状态码, 有两个特殊的状态码, 301,302, 会进行重定向操作, 会进行重新发送请求的操作
- 服务器返回304,会通过查询浏览器缓存进行返回
4. 计算机网络的七层模型
- 网络的七层模型
- 物理层
- 数据层
- 网络层 (ip)
- 传输层 (tcp, udp)
- (会话层)
- (表示层)
- (应用层) (http协议)
5. Http的阶段
- http0.9: 负责传输HTML, 最早没有请求头和响应头
- http1.0: 提供了http的 header, 根据header的不同处理不同的资源
- http1.1: 默认开启keepAlive, 链路复用(建立长连接), 增加了一种机制
管线化(一个域名之下可以处理6个连接), 服务器处理多个请求, (会按顺序处理,队头阻塞问题) - http2.0: 用同一个tcp链接来发送数据, 一个域名一个tcp(多路复用, 第一个请求复用同一个tcp), 解决对头阻塞问题, http2启用头部压缩, 服务器可以推送数据给客户端
- http3.0: 解决了tcp队头阻塞的问题,QUIC协议采用UDP
浏览器收到内容后是如何解析的(渲染流程)
-
- 浏览器无法直接使用HTML,需要将HTML转换为DOM树(document)
-
- 遇到css不会阻塞DOM的解析,加载完CSS样式, 浏览器无法解析纯文本的CSS样式,需要对css解析,解析成styleSheets, CSSOM(document.styleSheets)
-
- 计算出DOM树中每个节点的具体样式(Attachment)
-
- 最终创建出布局树, 将DOM树中的可见节点,添加到布局树中, 并计算节点渲染到页面中的坐标位置
-
- 通过布局树,进行分层(根据定位属性, 透明属性,tranform属性,clip属性等)生产图层树
-
- 将不同图层进行绘制, 转交给
合成线程处理,最终生成页面,并显示在浏览器上(painting Display)
- 将不同图层进行绘制, 转交给
-
css放在页面的顶端, js放在页面的底端?
- HTML是自上而下进行解析的,遇到css不会阻塞DOM的解析,html元素依次解析, 解析完之后需要把样式和HTMl组成一棵树 => 布局树 => 进行绘制,渲染到页面上
<!-- index 放在上面在浏览器中只会绘制一次 --> <head> <link rel="stylesheet" href="./css/index.css"> </head> <body> <div class="box"></div> </body> <!--样式放在下面,浏览器会先解析div元素,绘制一次,在解析css进行合成重新计算,会发生重绘现象 --> <head></head> <body> <div class="box"></div> <link rel="stylesheet" href="./css/index.css"> </body> - HTMl加载js的时候,会阻塞html渲染,等待js加载完毕后,再进行渲染,
<!-- loadjs会阻塞html的解析,加载完成后,再解析html--> <head> <link rel="stylesheet" href="./css/index.css"> </head> <body> <div class="box">hello</div> <script src="./js/loadjs.js"></script> <div class="world">world</div> </body> - HTML是自上而下进行解析的,遇到css不会阻塞DOM的解析,html元素依次解析, 解析完之后需要把样式和HTMl组成一棵树 => 布局树 => 进行绘制,渲染到页面上