文章目录
- 现代浏览器原理揭秘
-
- 前提计算机基础概念
-
- 1.CPU(Central Processing Unit)
- 2.GPU(Graphics Processing Unit)
- 3.进程 & 线程
- 一、浏览器架构
-
- 多进程的好处
- 多进程的坏处
- 多进程架构的内存优化
- 站隔离 (Site Isolation)
- 二、一个经典问题, 导航时都发生了什么li>
-
- 1. 处理输入
- 2.开始导航
- 3.读取相应
- 4.寻找一个渲染进程来绘制?面
- 5.提交导航
- 6.加载完成
- 三、导航到不同的站点
-
- 1.如果第二次导航是在?面内发起的, 比如?面内Js执行了location.href=xxxx, 这时候浏览器是怎么做的li>
- 2.如果第二次导航是到不同的站点呢li>
- 四、Service Worker场景下的导航
- 五、导航预加载 – Navigation Preload
- 参考文章
- 往期精彩文章
现代浏览器原理揭秘
首先我们先了解一些关键的计算机术语以及Chrome浏览器的多进程架构。
前提计算机基础概念
1.CPU(Central Processing Unit)
图形处理器, 单个GPU核心只能处理一些简单的任务,不过它胜在数量多,单片GPU上会有很多很多的核心可以同时工作,也就是说它的并行计算能力是非常强的
当你在手机或者电脑上打开某个应用程序的时候,背后其实是CPU和GPU支撑着这个应用程序的运行。通常来说,你的应用要通过操作系统提供的一些机制才能跑在CPU和GPU上面。
3.进程 & 线程
上图所示,Chrome浏览器, 是多进程架构, 先来看一下都包含哪些进程
-
Browser(一个) – 浏览器进程, 只有一个浏览器进程,负责浏览器的主体部分,包括导航栏,书签, 前进和后退按钮, 提供存储等功能
-
Network(一个) – 络进程, 主要负责?面的 络资源加载,之前是作为一个模块运行在浏览器进程里 面的,直至最近才独立出来,成为一个单独的进程
-
GPU(一个) – 图像渲染进程, 负责独立于其它进程的GPU任务。它之所以被独立为一个进程是因为它 要处理来自于不同tab的渲染请求并把它在同一个界面上画出来。
-
Renderer(多个) – 渲染进程, 负责tab内和 ?展示相关的所有工作, 比如将 HTML、CSS 和 JavaScript 转换为用戶可以与之交互的 ?, 默认情况下每个tab都有一个独立的渲染进程。
-
Plugin(多个) – 插件进程,例如之前的flash
-
Extensions(多个) – 扩展程序进程
-
其他进程 – 工具进程,辅助框架等等
可以在chrome浏览器 更多工具 – 任务管理器 查看当前浏览器所开启的进程, 以及内存和cpu消耗
多进程的好处
-
容错性
Chrome会为每个tab单独分配一个属于它们的渲染进程(render process)。举个例子,假如你有三个tab,你就会有三个独立的渲染进程。 当其中一个tab的崩溃时,你可以随时关闭这个tab并且其他tab不受到影响。可是如果所有的tab都跑在同一个进程的话,它们就会有连带关系,一个挂全部挂。
-
安全性和沙盒性
同样的优化方法也可以被使用在浏览器进程(browser process)上面。
Chrome浏览器的架构正在发生一些改变,目的是将和浏览器本身(Chrome)相关的部分拆分为一 个个不同的服务,服务化之后,这些功能既可以放在不同的进程里面运行也可以合并为一个单独的 进程运行。
这样做的主要原因是让Chrome在不同性能的硬件上有不同的表现。当Chrome运行在一些性能比较 好的硬件时,浏览器进程相关的服务会被放在不同的进程运行以提高系统的稳定性。相反如果硬件 性能不好,这些服务就会被放在同一个进程里面执行来减少内存的占用。
这样,原来的各种模块会被重构成独立的服务(Service),每个服务(Service)都可以在独立的进 程中运行,访问服务(Service)必须使用定义好的接口,通过 IPC 来通信,从而构建一个更内聚、 松耦合、易于维护和扩展的系统,更好实现 Chrome 简单、稳定、高速、安全的目标。
站隔离 (Site Isolation)
2.开始导航
当用戶按下回?键的时候,UI线程会通知 络进程初始化一个 络请求来获取站点的内容。 这时候tab上的icon会展示一个提示资源正在加载中的旋转圈圈,而且 络进程会进行一系列诸如
DNS寻址以及为请求建立TLS连接的操作。
- tips: 这时如果 络进程收到服务器的HTTP 301重定向响应,它就会告知UI线程进行重定向然后它会再次发起一个新的 络请求。
- 不同响应类型的处理
如果响应的主体是一个HTML文件,浏览器会将获取的响应数据交给渲染进程(renderer process) 来进行下一步的工作。如果拿到的响应数据是一个压缩文件(zip file)或者其他类型的文件,响应数据就会交给下载管理器 (download manager)来处理。
5.提交导航
到这一步的时候,数据和渲染进程都已经准备好了,浏览器进程(browser process)会通过IPC告诉渲染进程去提交本次导航(commit navigation)。
除此之外浏览器进程还会将刚刚接收到的响应数据流传递给对应的渲染进程让它继续接收到来的HTML数据。
一旦浏览器进程收到渲染线程的回复说导航已经被提交了(commit),导航这个过程就结束了,文档的加载阶段(document loading phase)会正式开始。
到了这个时候,导航栏会被更新,安全指示符和站点设置会展示新?面相关的站点信息。 当前tab的会话历史(session history)也会被更新,这样当你点击浏览器的前进和后退按钮也可以 导航到刚刚导航完的?面。为了方便你在关闭了tab或窗口(window)的时候还可以恢复当前tab和 会话(session)内容,当前的会话历史会被保存在磁盘上面。
三、导航到不同的站点
上面讲述了一个导航的过程, 那么这时候如果我们想去浏览另一个 ?, 浏览器会怎么做呢p>
能够想到的是, 浏览器必然会重复一遍导航的步骤, 但是在这之前, 浏览器还有一些收尾工作要做!
浏览器进程会对渲染进程说, 我准备重新发起导航了, 你那边是否需要处理**beforeunload**事件p>
beforeunload可以在用戶重新导航或者关闭当前tab时给用戶展示一个“你确定要离开当前?面吗二次确认弹框。
浏览器进程之所以要在重新导航的时候和当前渲染进程确认的原因是,当前?面发生的一切(包括 ?面的JavaScript执行)是不受它控制而是受渲染进程控制,它不知道里面的具体情况。
- tips:所以不要随便给?面添加beforeunload事件监听,你定义的监听函数会在?面被重新导航的时候执行,因此这会增加重导航的时延。 **beforeunload**事件监听函数只有在十分必要的时候才能被添加,例如用戶在?面上输入了数据, 并且这些数据会随着?面消失而消失。
四、Service Worker场景下的导航
如果开发者在service worker里设置了当前的?面内容从缓存里面获取,当前?面的渲染就不需要重
新发送 络请求了,这就大大加快了整个导航的过程。
这里要重点留意的是service worker其实只是一些跑在渲染进程里面的JavaScript代码。五、导航预加载 – Navigation Preload
在上面的例子中,你应该可以感受到如果启动的service worker最后还是决定发送 络请求的话,浏 览器进程和渲染进程这一来一回的通信包括service worker启动的时间其实增加了?面导航的时延。
导航预加载就是一种通过在service worker启动的时候并行加载对应资源的方式来加快整个导航过程 效率的技术。预加载资源的请求头会有一些特殊的标志来让服务器决定是发送全新的内容给客戶端 还是只发送更新了的数据给客戶端。
参考文章
https://developers.google.com/web/updates/2018/09/inside-browser-part1
往期精彩文章
- leetcode-js刷题记录&数据结构
- docker下YApi部署教程-支持swagger数据导入
- 带你深入理解什么叫js闭包
- 使用Object.defineProperty进行数据劫持,实现响应式原理-剖析vue2.0
- 前端性能优化之rel=“prefetch“预/懒加载功能
- 前端唤起相机的方法H5+JS
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!