这个问题实在是 老生常谈,甚至是面试必考题之一,
我这里记录一下我学习的结果,仅供自己学习
1、浏览器的进程
- 首先要了解的是,一个浏览器 是有好多进程的,比如 浏览器进程、渲染进程、GPU进程、网络进程、插件进程
- 浏览器进程 是 管理浏览器本身的,而渲染进程 基本上是一个标签页一个,那么为什么要说基本上呢?可以看 4.7 的内容
- GPU进程是 在 渲染进程的基础上,对 展现的图像进行进一步处理的
- 网路进程 是用来和 网络通信的,而在 chrome 中,一个标签页同一时间 只会 对同一个 域名维持 6个TCP链接,多余的在这六个连接结束之前只能挂起。所以当 请求被放到了 三个域名下的话,同时最多会有 18个连接
- 插件进程是用来专门运行插件的
- 因为任何 输入都是不可信的,所以 渲染进程、插件进程其实都是被放在了一个沙箱中,禁止 访问系统的 私密文件以及 操作
2、所以说了这么多,进程和 URL 之间有什么关系呢?
你首先输入之后,会对 你的输入内容进行检查,然后根据检查的结果,去决定是 使用搜索引擎搜索,还是当作一个url 资源
所以 当浏览器认为是一个 URL 资源之后,
- 浏览器进程会给 当前的url 加上对应的协议,如 http,cookie,请求头,当前的 ip,当前服务的端口号 等等信息
- 浏览器进程将 完整的 url 信息 推给 网络进程
- 网络进程 对 该信息 进行命中,如果有缓存,则从缓存中读取,没有的话,继续
- 接下来就会进行 DNS 服务的解析,这个是通过 UDP 的 (浏览器会缓存 这个解析的结果,所以第二次打开同一个网页的时候,会发现快一点的原因,这个占了一部分)
- 获取 对应服务的 ip 之后,这个时候才进行 TCP 的三次握手
- 握手成功 发出 http 请求 (http1和 http2 是基于TCP 的)
- 进行数据包信息的传输,在这个过程中,TCP 会校验每个包 是否都 收到,没有的话进行重发,并且 给每个包 打上序号标签,保证信息的完整,客户端根据数据包的序号标签对数据进行整理排序 (所以说 为什么 http3 出现的原因就在这里了,实在是效率太低。硬生生将 数据的传输量 增加了一倍)
- 信息传输完之后会第一时间关闭TCP吗?还真不一定
- 如果你的请求中带着 keep-alive 的话,接下来的请求会 复用这个TCP连接,省去了 三次握手的过程
- 然后根据之前 包装的 服务端口号 等信息 定位到 对应的应用中
3、浏览器获取了 后端给的数据之后,又发生了什么呢?
首先,会检查 响应头是什么,然后会检查 content-type
- 如果是 301 或者 302 ,那么 重新进行第二大点 的内容
- 如果是 304 ,也就是说 服务器告诉 浏览器 数据没有过期,继续从缓存拿
- 还有其他的,我也不多说(其实我也一知半解)
- 接着是 前端 都喜欢的 200 了,你以为 200 就结束了?
- 浏览器会检查 返回的 content-type,然后根据这个 值来决定该怎么处理 返回来资源,比如说 是要 下载这个资源呢,还是渲染这个资源呢? (application/msword : Word文档格式,application/octet-stream : 二进制流数据)
- 咱们进入 text/html 中
4、终于进入了熟悉的渲染进程了
渲染进程 又会分为好几个 线程,比如常说的 js 线程
- 这个时候 会给 前端开发者一个最后挣扎的机会:beforeunload,比如还有东西没有保存,是否离开之类的。如果选择 否,则 不进行接下来的操作
- 如果用户选了确定,开始解析,则会替换之前的页面 (所以直到这一步之前,之前的页面都是保留着的!!)
- 浏览器并不能直接识别 html 和 css,所以需要解析 这一部分,生成两棵树
- 具体树的结构可以在 控制台 输出 document 获得 dom 树,以及 document.styleSheets 获得 css 的树
- 在css树中,其实浏览器 是 不能直接使用类似于 color: red 这样的属性的,会转化为 color:rgb(255, 0,0),也不能识别 rem,会转化为 对应的 px,等等
- 接下来的解析过程不多说,其他的资料有很多,但是要注意的是,渲染树中其实 不包含 那些不可见的东西,比如 display:none
- 需要注意的是,如果你是从一个页面中打开的另一个页面,浏览器 会 判断当前 url 中的 域名是否是和之前的是同一个,是的话,则共用 上一个页面的渲染进程 (所以会出现一挂挂好几个 的现象)
- 全部数据都处理好了之后,会将 渲染的树 推到浏览器本身
- 然后 浏览器会将这些 渲染的指令 进行 光栅化 去渲染,部分交给 GPU 进程进行渲染
- 而在执行过程当中,如果js 中有 generator ,就又会生成 单独的协程来进行 控制权的移交