-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
36 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,39 @@ | ||
## 浏览器解析是不是HTTP协议, 浏览器后开启线程进行初始化webview | ||
1. 浏览器解析是不是HTTP协议, 浏览器后开启线程进行初始化webview | ||
2. 通过DNS解析域名的实际IP地址 | ||
浏览器缓存1分钟 -> 系统缓存 -> 路由器缓存 -> 运营商 -> 根服务器提供商 | ||
3. 检查浏览器是否有缓存 | ||
3.1 通过Expires 和 Cache-Control来检查是否命中强缓存 | ||
3.1.1 Expires是HTTP1.0的,采用的绝对时间,受系统时间和服务器时间的影响 | ||
3.1.2 Cache-Control是Http1.1的,采用的相对时间,优先级也比Expires高,常用字段包括 max_age, no-cache, no-store。 | ||
3.1.3 Cache-Control存在的问题:在资源到期之前,服务器资源改变也无法知晓 | ||
3.2 如果没有没有命中强缓存,就会进行协商缓存。 | ||
3.2.1 协商缓存有两组字段,Last-Modified/If-Modified-since(http1.0)和Etag/If-None-match(http1.1) | ||
3.2.2 服务器会记录Last-Modified最后一次修改的时间,请求的时候带上If-Modified-since,服务器会比比较是否一样。劣势是只要服务器资源变了,无论内容是否变化,都不会命中缓存。 | ||
3.2.3 etag是资源的唯一标识,服务器将浏览器传来的if-no-matched跟自己的本地的资源的ETag做对比,如果匹配,则返回304通知浏览器读取本地缓存,否则返回200和更新后的资源。劣势是etag存在计算耗时。 | ||
4. 建立HTTP连接,开始TCP三次握手 | ||
4.1 客户端随机初始化一个序列号放在TCP报文的头部,然后将SYN标志位设置为1。接着把第一个SYN报文发给服务端,表示把第一个SYN报文发给服务端。此时客户端处于SYN-SENT阶段 | ||
4.2 服务端接收到SYN报文后,随机初始化自己的序列号,将此序列号放在TCP首部的序号字段中。接着把SYN 和 ACK标志设置为1 。最后把该报文发给客户端,标识确认应答,此时服务端处于SYN-RCVD状态 | ||
4.3 客户端收到服务端报文后,还要发起一个应答报文,将此报文的ACK标志设置为1,确认应答号设置为服务端序列号+1, 这次报文可以携带应用层数据,之后客户端处于ESTABLISHED状态。 | ||
4.4 其中起关键左右的是序列号和SYN、ACK标志位 | ||
5. 服务器或者CDN响应,设置content-type 为html返回给浏览器 | ||
6. 浏览器接受并解析html类型的文件进行渲染 | ||
|
||
## 通过DNS解析域名的实际IP地址 | ||
浏览器缓存 -> 系统缓存 -> 路由器缓存 -> 运营商 -> 根服务器提供商 | ||
|
||
## 检查是否浏览器是否有缓存 | ||
1. 通过Expires 和 Cache-Control来检查是否命中强缓存 | ||
2. 如果没有没有命中强缓存,那就发起请求,服务器通过检查Etag和Last-Modified来与服务器确认是否已修改。如果没有更改就返回状态码,浏览器使用本地资源 | ||
7. 浏览器渲染流程分为多个阶段: | ||
7.1 HTML解析 | ||
在解析过程中,如果遇到css就解析css,但是不会阻塞HTML解析。如果遇到script,就会停止解析,等待script脚本下载和执行完成,因为js的执行可能会影响DOM结构,所以会阻断html解析。 | ||
但是script有两个属性 async 和 defer 可以让脚本的下载不阻塞HTML的解析 | ||
7.1.1 script async 脚本的下载不会阻塞html的解析,但是当下载完成后会,会暂停解析并先执行脚本,等脚本执行完成后再继续html解析 | ||
7.1.2 script defer 脚本的下载不会阻塞html的解析,会等待html解析完成之后,再按脚本的顺序,执行下载好的脚本。 | ||
7.1.3 解析完成之后,会得到DOM Tree 和 CSSDOM Tree。 | ||
7.2 样式计算,构建渲染树,render tree。在这一过程中,一些预设值会变成绝对值,一些display none的dom树不会出现再渲染树中。 | ||
7.3 布局, layout, 这阶段会一次遍历渲染树的每一个节点,计算每个节点的几何信息,例如节点的宽高、相对块的位置等。 | ||
7.4 分层,主线程使用一套复杂的策略将布局树进行分层,分层的好处就是某一层改变后,只需处理该层,从而提升效率。滚动条、zindex、transform、opacity等都会影响分层结果。 | ||
7.5 绘制,主线程会为每一层单独产生渲染的指令集,用于描述这一层的内容该如何画出来。完成绘制后,主线程将每个图层的绘制信息提交给合成线程,剩下的工作将由合成线程完成。 | ||
7.6 分块,合成线程首先对每个图层进行分块,将其划分为更多的小区域 | ||
7.7 光栅化, 分块完成后,进入光栅化阶段, 光栅化的结果就是一个一个的像素图。 | ||
7.8 画, 指引会标识出每个位图应该画到屏幕的哪个位置。 以及会考虑到旋转、缩放等变形。变形发生在合成线程,与渲染主线程无关,这就是transform效率高的本质原因。 | ||
|
||
## 建立HTTP连接,开始TCP三次握手 | ||
8. 重绘 和 重排 | ||
8.1 重绘:重新根据分层信息计算了绘制指令,只要是样式变化了就一定会触发重绘 | ||
8.2 重排:重新计算布局树,通过dom操作修改布局树的位置信息,还有获取dom节点的宽高等行为都会触发重排,但是重排不是立刻执行的,会节流和patch。 |