你有没有注意到,关注技术公众号、逛技术社区,总是时不时会看到这个问题:
从输入URL到看到页面渲染,这中间发生了什么?
之前不理解为啥刨根问底一直问到细枝末节,让我怀疑人生。最近领悟了,这道题目是有目的,针对性很强。
不是人人都能搞清楚七层协议、tcp为啥非得三次握手、https加密的细节等,沟通的目的也不是要完美回答每一个细节,这道题目是一个开放性问题,如何解答是有侧重和技巧的,你可以侧重链接,也可以侧重交互,也可以侧重渲染。
后来,我面试别人,也会问这个问题,观察候选人的表达思路、知识框架、知识广度,有时候也会追问一些细节,观察应答情况。
闲话不再说,如果是我,我要怎么回答这个问题?我之前也答不好,回答得很零散,后来开悟了,因为一张图片:
这张图片你或许看到过类似的,本图来自 w3
官方文档 navitation-timing
一节。这是介绍 performance.timing
时候的配图,这张图完美解释了本文提到的问题。我们该如何阅读这张图片呢?
- unload 卸载页面,beforeUnload 和 unload,这里忽略即可
- redirect 重定向,这里忽略即可
AppCache
缓存。这里就可以展开说。DNS
通过DNS查找目标IPTCP
建立链接request
传输请求response
这里开始阅读小字- domInteractiver
- domContentLoadEvent
- load
因此,我们回答的框架可以从这几个点入手:
- 构建请求
GET /a.html HTTP1.1
- 查看缓存
- DNS解析
- 建立TCP链接
- 传输请求
- 获得相应结果
- 渲染页面
来自 页面导航
简单的导航Navigation 包含:
- UI Thread 判断是搜索还是网址,因为可以从地址栏直接发起搜索。
- UI thread 调用 Network thread 请求内容,通知标签栏准备loading 标识
- Network thread 会进行网络请求,这里可以进入单独的 《说尽DNS》《说尽网络协议TCP、HTTP和其他》章节
- 如果返回了301,network thread 会让 UI thread 进行重定向,重新走流程
- 阅读返回内容,选择合适的 MIME Type 解析,同时进行安全性检查,尤其是CORB Cross Origin Read Blocking
- 选择合适的 renderer Process , Network Process 通知 UI thread 准备干活,UI thread 会找一个合适的 renderer process
- 现
从输入完网址发生了什么到性能优化
创建于 2018年11月13日 09:22
涉及的知识点还是挺全的。
梳理主干流程。按照笔记整理了主干流程:
- 从浏览器接受url到开启网络请求线程。
- 开启网络线程到发出完整http请求。
- 从服务器接收到对应后台接收请求。
- 后台和前台的http交互
- 单独解释的缓存问题
- 浏览器接收到响应的解析。
- css处理
- js引擎解析。
- 其他。
浏览器接收url到开启网络请求线程。
浏览器进程、线程模型,JS运行机制。
浏览器的多进程
浏览器是多进程的,一个主控进程,开一个tab就开一个新的进程。
进程包含:
- 浏览器进程,负责协调控制
- 第三方插件进程
- GPU进程,用于3D绘制
- 浏览器渲染进程,进程之间互不影响独立控制、渲染、事件处理。比如页面崩溃了,浏览器不崩。
每个浏览器进程是多线程的,
有几个子线程:
- GUI线程
- JS引擎线程
- 事件触发线程
- 定时器线程
- 网络请求线程
JS引擎是单线程处理的。
解析URL
URL = protocol 协议头 + host 主机域名、IP + port 端口号 + path 路径 + query 查询参数 + fragment hash值 https://segmentfault.com/a/1190000013662126#articleHeader10
网络请求单线程
根据URL得出协议,开辟网络请求线程,请求资源
更多
https://segmentfault.com/a/1190000012925872
from 开启网络请求线程 to 发出完整http请求
DNS查询、 tcp/ip 请求、 互联网五层协议
DNS查询得到IP
这里是 DNS 的工作流程了:
- 如果本机有缓存,直接用浏览器缓存;否则使用本机缓存
- 如果本地没有缓存,就向 DNS域名服务器查询,总之,找到IP
注意,这里可能会接受CDN调度。分配不同的服务器。
DNS解析耗费资源,可以考虑在 html中声明dns-prefetch
,我有个笔记来讲这个。
tcp/ip 请求
见 tcp
五层协议
从发出http请求道服务器接收,经过一系列请求。
- 应用层(dns,http)。把DNS解析成IP,并发送HTTP请求
- 传输层(tcp,udp)。建立tcp连接,三次握手
- 网络层(IP,ARP)。 IP寻址
- 数据链路层(PPP),封装成帧
- 物理层。物理传输,双绞线电磁波等。好多四层协议不包含物理层。
一个完整的OSI包含七层框架,多了会话层、表现层。
会话层,管理不同用户和进程之间的对话,控制登录和注销。
表示层,处理两个通信系统交换的表现方式。
from 服务器接收请求 to 后台接收到请求
负载均衡
比如nginx的负载均衡。
后台处理
一般是容器收到请求,容器里的后台程序处理请求,都用统一的验证,比如拦截、跨域验证,验证后交给后台处理,然后响应返回结果。
后台和前台的HTTP交互
http 报文结构
一般包含: 通用头部、请求/响应头部、请求/响应体
通用头部General
Request URL: http://www.wangxiao.cn/ Request Method: GET Status Code: 200 OK Remote Address: 42.81.4.62:80 Referrer Policy: no-referrer-when-downgrade 接着就是状态码。 状态码具体的不展开了,大致:
- 1xx 指示信息,表示请求已经接受,继续处理
- 2xx 成功,表示请求已经被成功接受、理解、接受
- 3xx 重定向,要完成请求要进一步操作
- 4xx 客户端错误,有语法错误或者请求无法请求
- 5xx 服务端错误,服务器无法实现合法请求
请求头部 Request Headers
网校的首页
GET / HTTP/1.1 Host: www.wangxiao.cn Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7 Cookie: qzjc=1; api的一个接口: GET /zhuanti/new.aspx HTTP/1.1 Host: api.wangxiao.cn Accept: 略去部分相同内容 text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/_;q=0.8 常用请求头部:
Accept
接受类型,表示浏览器支持的MIME类型,对标服务端返回的Content-Type。分号分隔,q表示权重
Accept-Encoding
浏览器支持的压缩类型,如gzip,超出类型不接收
Content-Type
客户端发送的实体内容类型
Cache-Control
缓存部分https://www.yuque.com/xinbao37/high_performance/about-cache
指定请求和响应遵循的缓存行为
Cache-Control: no-cache
If-Modified-Since
【http1】用来匹配文件是否变动,只能精确到 1s
Exprires
【http1】缓存控制
Max-age
【http1.1】表示资源在本地缓存多少秒,有效时间内使用缓存。
If-None-Match
【http1.1】对应服务端的 ETag,用来匹配文件是否改变,精确
Cookie
同域访问有cookie会自动带上
Connection
当浏览器与服务器通信时候,长连接如何处理,比如 keep-alive
Host
请求的服务器URL
Origin
最初的请求从哪里发起,精确到端口,比 Referer 更尊重隐私。
Referer
页面来源的URL,适用于各种请求,会精确到详细页面地址,CSRF拦截用到这个字段。
User-Agent
用户客户端的一些必要信息,如 UA头部等。
响应头部
常用响应头部:
HTTP/1.1 200 OK Server: Tengine Content-Type: text/html Content-Length: 216774 Connection: keep-alive Cache-Control: public,max-age=172800 Last-Modified: Wed, 29 Aug 2018 07:04:17 GMT Accept-Ranges: bytes ETag: “0513b80663fd41:0” sv: 235 Date: Thu, 30 Aug 2018 05:56:58 GMT Via: cache22.l2em21-1[0,304-0,H], cache30.l2em21-1[1,0], kunlun6.cn249[0,200-0,H], kunlun1.cn249[1,0] Expires: Thu, 30 Aug 2018 05:38:07 GMT Age: 3085 X-Cache: HIT TCP_MEM_HIT dirn:1:277385018 mlen:-1 X-Swift-SaveTime: Thu, 30 Aug 2018 06:37:37 GMT X-Swift-CacheTime: 3600 Timing-Allow-Origin: * EagleId: 2a51040115356117035884805e 网校 api 的某个接口 Cache-Control: public, max-age=3600 Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Expires: Thu, 30 Aug 2018 09:08:51 GMT Vary: Accept-Encoding Server: X-AspNet-Version: 4.0.30319 X-Powered-By: 240 Date: Thu, 30 Aug 2018 08:08:51 GMT Content-Length: 3600 常用说明:
Access-Control-Allow-Headers
服务器端允许的请求Headers
Access-Control-Allow-Methods
服务器端允许的请求方法
Access-Control-Allow-Origin
服务器端允许的请求Origin头部(譬如为*),这里要匹配Origin,要不然跨域
Content-Type
服务端返回的实体内容的类型
Date
数据从服务器发送的时间
Cache-Control
告诉浏览器或其他客户,什么环境可以安全的缓存文档
Last-Modified
请求资源的最后修改时间
Expires
应该在什么时候认为文档已经过期,从而不再缓存它
Max-age
客户端的本地资源应该缓存多少秒,开启了Cache-Control后有效
ETag
请求变量的实体标签的当前值
Set-Cookie
设置和页面关联的cookie,服务器通过这个头部把cookie传给客户端
Keep-Alive
如果客户端有keep-alive,服务端也会有响应(如t imeout=38)
Server
服务器的一些相关信息
实体内容
请求实体中一般有一些参数,用于POST
CRLF 回车换行,一般作为分隔符存在
CRLF -> windows style
LF -> Unix style
CR -> Mac style
相关概念
cookie 以及优化
请求静态资源也加载 cookie,需要做优化。把静态资源分组,多域名拆分
请求域名过多,会降低请求速度,所以这里有个优化方案 dns-prefetch
gzip 压缩
这个由 web 服务器开启,比如 nginx apache tomcat
除了 gzip 压缩外,还有 deflate 但是不流行也不高效。只要开启了 gzip 所有请求都是 gzip
长连接和短连接
在 http1中,默认短连接。在 http1.1中,默认长连接。使用长连接会有一行 Connection: keep-alive
. 这个不会永远保持,会保持一段时间,可以再服务器中配置。长连接需要服务器和客户端支持。
http2
在 http1.1中,请求一个资源对应开启一个 tcp/ip 连接。而 tcp/ip 有并发限制,数量一多就回降低速度。
在 http2中,一个tcp/ip 请求可以请求多个资源。一次请求可以获取若干个资源,分割成更小的帧请求,速度提升。
如果 http2全面应用,很多优化方案就无需用到了,比如精灵图,静态资源多域名拆分
http2的一些特性:
- 多路复用。一个tcp/ip请求多个资源
- 首部压缩。http 头部压缩,减少体积
- 二进制分帧。
- 服务器端推送,可以对客户端一个请求发出多个响应,可以主动通知客户端。
- 请求优先级。
https
在请求前会建立 ssl 连接,确保接下来的通信都是加密的,无法被轻易截取分析
一般来说,https 需要的资源更多,配合 http2 体验更佳。
不多讲了,有点深。
http 缓存
https://www.yuque.com/xinbao37/high_performance/about-cache
CSS的可视化格式模型
包含块 Containing Block
元素的定位和尺寸,和某一矩形框有关,这个框就是包含块。
控制框 Controlling Box
一个块级元素会生成
块级元素会生成一个块框,会占领一行。里面要么只包含块框,要么只包含行内框。如果 Block Box含有inlne元素,行内元素会被匿名块框包起来。
<div>
some text.
<p>
here.
</p>
</div>
div生成了一个 BlockBox,里面有一个P和一个文本内容。这个 文本内容会强制加到一个匿名的块框里。这就是 IFC Inline Formatting Context.
可能知道的知识点:
- 对浏览器模型有整体概念,浏览器多进程,内核多线程,进程和线程的区别,输入url会开一个新的网络线程
- 从开启网络线程到发起http请求之间的过程。比如 DNS查询, tpc/ip 链接, 五层协议,优化方案
dns-prefetch
- 对服务器收到的请求对应到后台接收。比如负载均衡、安全拦截、nginx等
- http交互,包括 http报文、头部、cookie、跨域、web安全、缓存、http2、https
- 浏览器接收到数据包解析。解析html、语法分析解析DOM树、解析css、合成render、layout、painting、component、GPU绘制、外链处理、加载顺序等。
- js引擎解析,js的处理、预处理、执行上下文、VO、作用域链、this、GC回收等。