你有没有注意到,关注技术公众号、逛技术社区,总是时不时会看到这个问题:

从输入URL到看到页面渲染,这中间发生了什么?

之前不理解为啥刨根问底一直问到细枝末节,让我怀疑人生。最近领悟了,这道题目是有目的,针对性很强。

不是人人都能搞清楚七层协议、tcp为啥非得三次握手、https加密的细节等,沟通的目的也不是要完美回答每一个细节,这道题目是一个开放性问题,如何解答是有侧重和技巧的,你可以侧重链接,也可以侧重交互,也可以侧重渲染。

后来,我面试别人,也会问这个问题,观察候选人的表达思路、知识框架、知识广度,有时候也会追问一些细节,观察应答情况。

闲话不再说,如果是我,我要怎么回答这个问题?我之前也答不好,回答得很零散,后来开悟了,因为一张图片:

image.png

这张图片你或许看到过类似的,本图来自 w3 官方文档 navitation-timing 一节。这是介绍 performance.timing 时候的配图,这张图完美解释了本文提到的问题。我们该如何阅读这张图片呢?

  • unload 卸载页面,beforeUnload 和 unload,这里忽略即可
  • redirect 重定向,这里忽略即可
  • AppCache 缓存。这里就可以展开说。
  • DNS 通过DNS查找目标IP
  • TCP 建立链接
  • 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

image.png


从输入完网址发生了什么到性能优化
创建于 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请求道服务器接收,经过一系列请求。

  1. 应用层(dns,http)。把DNS解析成IP,并发送HTTP请求
  2. 传输层(tcp,udp)。建立tcp连接,三次握手
  3. 网络层(IP,ARP)。 IP寻址
  4. 数据链路层(PPP),封装成帧
  5. 物理层。物理传输,双绞线电磁波等。好多四层协议不包含物理层。
    一个完整的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元素,行内元素会被匿名块框包起来。

  1. <div>
  2. some text.
  3. <p>
  4. here.
  5. </p>
  6. </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回收等。

https://segmentfault.com/a/1190000013662126?utm_source=weekly&utm_medium=email&utm_campaign=email_weekly