阅读 155

浏览器相关原理

CPU && GPU

  • CPU 可以看作是计算机的大脑。一个 CPU 可以逐一解决很多不同任务。

  • 与 CPU 不同,GPU 擅长同时处理跨内核的简单任务。

  • 当你在电脑或手机上启动应用时,是 CPU 和 GPU 为应用供能。通常情况下应用是通过操作系统提供的机制在 CPU 和 GPU 上运行。

  • image-20210902183314737

进程 && 线程

  • 进程可以被描述为是一个应用的执行程序。线程存在于进程并执行程序任意部分。

  • image-20210902183626107

浏览器架构

  • 那么如何通过进程和线程构建 web 浏览器呢?关于如何构建 web 浏览器并不存在标准规范。一个浏览器的构建方法可能与另一个迥然不同。

  • image-20210902184314298

  • image-20210902184326414

进程各自控制什么
  • image-20210902184519404

Chrome 多进程架构的优点
  • 每个标签页都有自己的渲染进程时,如果某个标签页失去响应,你可以关掉这个标签页,此时其它标签页依然运行着,可以正常使用。如果所有标签页都运行在同一进程上,那么当某个失去响应,所有标签页都会失去响应。

  • 安全性与沙箱化。

    • Chrome 正在经历架构变革,它转变为将浏览器程序的每一模块作为一个服务来运行,从而可以轻松实现进程的拆解或聚合。

    • 通常观点是当 Chrome 运行在强力硬件上时,它会将每个服务分解到不同进程中,从而提升稳定性,但是如果 Chrome 运行在资源有限的设备上时,它会将服务聚合到一个进程中从而节省了内存占用。在这一架构变革实现前,类似的整合进程以减少内存使用的方法已经在 Android 类平台上使用。

    • 当用户开始在地址栏键入时,UI 线程要问的第一件事是 “这是一次搜索查询还是一个 URL 地址?”

    • 当用户按下 Enter 键时,UI 线程启用网络调取去获取站点内容。

    • 网络线程会通过适当的协议,像 DNS 查找和为请求建立 TLS 连接。

    • 一旦开始收到响应主体(payload),网络线程会在必要时查看数据流的前几个字节。响应报文的 Content-Type 字段会声明数据的类型,

    • 如果响应是一个 HTML 文件,那么下一步就会把数据传给渲染进程,但是如果是一个压缩文件或是其他文件,那么意味着它是一个下载请求,因此需要将数据传递给下载管理器。

    • 此时也会进行 SafeBrowsing 检查。如果域名和响应数据似乎匹配到一个已知的恶意网站,那么网络线程会显示一个警告页面。除此之外,还会发生 Cross Origin Read Blocking(CORB)检查,以确保敏感的跨域数据不被传给渲染进程。

    • 一旦所有的检查执行完毕并且网络线程确信浏览器会导航到请求的站点,网络线程会告诉 UI 线程所有的数据准备完毕。UI 线程会寻找渲染进程去开始渲染 web 页面。

    • 由于网络请求会花费几百毫秒才获取回响应,因此可以应用一个优化措施。当第 2 步 UI 线程正发送一个 URL 请求给网络线程时,它已经知道它们会导航到哪个站点。在网络请求的同时,UI 并行地线程尝试主动寻找或开启一个渲染进程。这样,如果一切按预期进行,渲染进程在网络线程接受到数据时就已经处于待命状态。如果导航跨域重定向,这个待命进程也许不会被用到,这种情况下也许会用到另一个进程。

    • 现在数据和渲染进程已经就绪,浏览器进程会发送一个 IPC(进程间通信)到渲染进程去提交导航。

    • 一旦浏览器进程收到渲染进程已经提交的确认消息,导航完毕并且文档加载解析开始。

    • 一旦导航被提交,渲染进程开始加载资源和渲染页面。

    • 一旦渲染进程渲染“完毕”。它会发送一个 IPC 返回给浏览器进程(这会在页面所有的 frame 的 onload 事件已经触发和执行完毕后发生)。

    • 这时,UI 线程停止标签页上的加载动画。

    • 简单导航已经完毕!但是用户在地址栏输入另一个 URL 会怎样呢?好吧,浏览器进程会执行相同的步骤来导航到一个不同的站点。但是在它做这个之前,它会检查当前已经渲染的站点是否关心 beforeunload 事件。

    • beforeunload 可以在你试图导航离开或关闭标签页时创建“离开此站点?”警告。包括你的 JavaScript 代码,所有标签页内的东西都是由渲染进程处理,所以当新的导航请求到来时,浏览器进程必须要跟当前的渲染进程核对。

    • 如果渲染进程已经启动了导航(像用户点击一个链接或者客户端 JavaScript 运行 window.location = "newsite.com"),渲染进程会先检查 beforeunload 事件处理程序。然后,它会像浏览器处理启动导航一样执行相同的步骤。唯一不同的是导航请求是由渲染进程发送到浏览器进程的。

    • 渲染进程负责标签页内发生的所有事情。在渲染进程中,主线程处理服务器发送到用户的大部分代码。

    • 渲染进程的核心工作是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页。

    • 当渲染进程收到导航的提交消息并开始接收 HTML 数据时,主线程开始解析文本字符串(HTML)并将其转换为文档对象模型(DOM)。

    • DOM 是一个页面在浏览器内部表现,也是 Web 开发人员可以通过 JavaScript 与之交互的数据结构和 API。

    • 在解析构建 DOM 时,主线程会按处理顺序逐个请求它们(图像、CSS 和 JavaScript 等外部资源),但为了加快速度,“预加载扫描器(preload scanner)”会同时运行。

    • 如果 HTML 文档中有 <img><link> 之类的内容,则预加载扫描器会查看由 HTML 解析器生成的标记,并在浏览器进程中向网络线程发送请求。

    • image-20210902211226630

    • 当 HTML 解析器遇到 <script> 标记时,会暂停解析 HTML 文档,开始加载、解析并执行 JavaScript 代码。为什么?因为JavaScript 可以使用诸如 document.write() 的方法来改写文档,这会改变整个 DOM 结构(HTML 规范里的 overview of the parsing model 中有一张不错的图片)。

    • Web 开发者可以通过多种方式向浏览器发送提示,以便很好地加载资源。如果你的 JavaScript 不使用 document.write(),你可以在 <script> 标签添加 async 或 defer 属性,这样浏览器会异步加载运行 JavaScript 代码,而不阻塞解析。如果合适,你也可以使用 JavaScript 模块。可以使用 <linkrel="preload"> 告知浏览器当前导航肯定需要该资源,并且你希望尽快下载。

    • 主线程解析 CSS 并确定每个 DOM 节点计算后的样式。这是有关基于 CSS 选择器对每个元素应用何种样式的信息,这可以在 DevTools 的 computed 部分中看到。

    • image-20210902211607675

    • 现在,渲染进程知道每个节点的样式和文档的结构,但这不足以渲染页面。

    • 布局是计算元素几何形状的过程。主线程遍历 DOM,计算样式并创建布局树,其中包含 x y 坐标和边界框大小等信息。

    • image-20210902211916591

    • 拥有 DOM、样式和布局仍然不足以渲染页面。假设你正在尝试重现一幅画。你知道元素的大小、形状和位置,但你仍需要判断绘制它们的顺序。

    • 例如,可以为某些元素设置 z-index,此时按 HTML 中编写的元素的顺序绘制会导致错误的渲染。

    • 在绘制步骤中,主线程遍历布局树创建绘制记录。绘制记录是绘图过程的记录

    • 渲染管道中最重要的事情是:每个步骤中,前一个操作的结果用于后一个操作创建新数据。

    • 现在浏览器知道文档的结构、每个元素的样式、页面的几何形状和绘制顺序,它是如何绘制页面的?把这些信息转换为屏幕上的像素,我们称为光栅化。


    • 由于操作系统提供了限制进程权限的方法,浏览器就可以用沙箱保护某些特定功能的进程。例如,Chrome 浏览器限制处理任意用户输入的进程(如渲染器进程)对任意文件的访问。

    • 由于进程有自己的私有内存空间,所以它们通常包含公共基础设施的拷贝(如 V8,它是 Chrome 的 JavaScript 引擎)。这意味着使用了更多的内存,如果它们是同一进程中的线程,就无法共享这些拷贝。为了节省内存,Chrome 对可加速的内存数量进行了限制。具体限制数值依设备可提供的内存与 CPU 能力而定,但是当 Chrome 运行时达到限制时,会开始在同一站点的不同标签页上运行同一进程。

      节省更多内存——Chrome 中的服务化

      简单导航

      1、处理输入

      2、开始导航

      3、读取响应

      4、查找渲染进程

      5、提交导航

      初始加载完毕

      导航到另一个站点

      三 渲染进程

      渲染进程处理网站内容

      解析

      1、DOM 的构建

      2、子资源加载

      3、js 阻塞解析

      4、提示浏览器如何加载资源

      5、样式计算

      6、布局

      7、绘制

      更新渲染管道成本很高

      合成

      如何绘制一个页面

      什么是合成

      从浏览器看输入事件

image.png

    -   浏览器进程会把事件类型和坐标发送给渲染进程

    **合成器接收输入事件**

    ## 其他

    ### 1

    -   浏览器是多线程的,在内核控制下相互配合以保持同步。它至少三个常驻线程:js 引擎线程,GUI 渲染线程,浏览器事件触发线程。

        -   js 引擎是基于事件驱动单线程执行的
        -   渲染线程负责渲染浏览器界面,**但是 GUI 渲染线程与 JS 引擎是互斥的**,当js执行时GUI线程会被挂起,GUI 的更新也会被保存在一个队列中,等到 js 引擎空闲时才会被执行。**这就是 js 阻塞页面加载**。
        -   事件触发线程,当一个事件被触发时,该线程会把事件添加到任务队列的队尾,等待 js 引擎的处理。

    -   浏览器

        -   界面、浏览器引擎、渲染引擎、网络、ui 后端的接口、js 解释器、数据存储
        -   ![image-20210904203455954]()
        -   浏览器内核:Webkit、Gecko、Trident

    -   引擎一开始会从网络获取请求文档的内容,然后如下流程

        -   ![image-20210904203812133]()

    -   ![image-20210904204402927]()

    ### 2

    <https://www.bilibili.com/video/BV1x54y1B7RE/?spm_id_from=333.788.recommend_more_video.0>

    -   每个应用程序必须至少启动一个进程来执行其功能。进程会创建一些小的线程帮他完成yixie
    -   ![image-20210904230009334]()
    -   ![image-20210904230106442]()
    -   ![image-20210904230912166]()

    <!---->

    -   浏览器进程中的网络线程请求获取到html数据后,通过 IPC 将数据传给渲染器进程的主线程,主线程将html解析,生成DOM树,根据样式计算生成layout树,遍历layout树生成绘制顺序表,绘制顺序表和layer树一起发送给合成器线程,合成器线程按规则进行分图层,并把图层分成更小的图块,传给栅格线程进行栅格化,栅格化完成后,合成器线程会获得栅格线程传过来的draw quads 图块信息,根据这些信息,合成器线程合成一个合成器帧,然后将该合成器帧通过IPC传给浏览器进程,浏览器进程再传到GPU进行渲染。

    <!---->

    -   react 的渲染引擎 react fiber 用了 requestAnimationFrame()做了优化


作者:qqq946
链接:https://juejin.cn/post/7018897062322405390

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐