前言Chrome漫画,简单介绍Chrome架构的漫画,2008年和Chrome浏览器一起发布的。虽然Chrome已经发布了十多年来,[Chrome漫画]漫画中介绍的核心原理对理解Electron仍然有帮助。(原文,中文)漫画目录如下:开源浏览器背后的故事稳定、严格和多任务架构速度:Webkit和V8搜索和用户体验安全、沙盒模式和无危险浏览Gears、标准和开源代码1.CPU、GPU内存和多进程架构计算机的核心是CPU和GPUCPUCPU是计算机的大脑,可以处理很多不同的任务。大多数CPU都是单芯片。一个核心相当于同一芯片中的另一个CPU。GPUGPU最初是为图形处理而开发的,擅长同时跨多个CPU处理简单任务。通常,应用程序使用操作系统提供的机制在CPU和GPU上运行。进程和线程进程可以描述为应用程序的执行程序,而线程是存在于进程内部并执行其进程程序的任何部分的线程。一个程序在启动时会创建一个进程,程序也可能会创建线程来帮助它工作。操作系统提供了一个“内存块”供进程使用,所有的应用程序状态都保存在这个私有内存空间中。当应用程序关闭时,进程也随之消失,操作系统释放内存。一个进程可以要求操作系统启动另一个进程来运行不同的任务,此时会为新进程分配不同的内存部分。如果两个进程需要聊天,就需要IPC。如果一个工作进程变得没有响应,它可以在不停止运行应用程序不同部分的其他进程的情况下重新启动。浏览器架构对于浏览器来说,一个进程可以有多个不同的线程,或者多个不同的进程可以有多个线程通过IPC进行通信。对于Chrome浏览器,最新的架构如下:进程充当Browser浏览器进程,控制应用程序的“chrome”部分,包括地址栏、书签、后退和前进按钮。还处理Web浏览器的不可见的特权部分,例如网络请求和文件访问。呈现器控制网站选项卡内任何内容显示的呈现器进程。插件进程,它控制网站使用的任何插件,例如flash。GPU图形处理进程独立于其他进程处理GPU任务。它被分成不同的进程,因为GPU处理来自多个应用程序的请求并将它们绘制在同一表面上。下图是不同的进程指向浏览器UI的不同部分:当然还有更多的进程,比如extension进程,utility进程等等。Chrome中多处理的优势假定打开了三个选项卡,每个选项卡都由单独的渲染器进程运行。如果选项卡变得无响应,您可以关闭无响应的选项卡并继续工作,同时保持其他选项卡处于活动状态。如果所有选项卡都在一个进程上运行,当一个选项卡变得无响应时,所有选项卡都会变得无响应。将浏览器的工作拆分为多个进程的另一个好处是安全性和沙盒。由于操作系统提供了一种限制进程权限的方法,因此浏览器可以将某些进程从某些功能中沙箱化。例如,Chrome浏览器将任意文件访问限制为处理任意用户输入的进程,例如渲染器进程。因为进程有自己的私有内存空间,它们通常包含公共基础设施的副本(例如V8,它是Chrome的JavaScript引擎)。这意味着更多的内存使用,因为它们不能像它们是同一进程中的线程那样共享。为了节省内存,Chrome限制了它可以启动的进程数。限制取决于设备的内存和CPU能力,但当Chrome达到限制时,它会开始在一个进程中运行来自同一站点的多个选项卡。更多内存节省——在Chrome中为Chrome提供服务Chrome正在经历架构更改,以将浏览器程序的每个部分作为服务运行,这些服务可以轻松地拆分为单独的进程或聚合为单个进程。当Chrome在强大的硬件上运行时,它可能会将每个服务拆分到不同的进程中以提供更高的稳定性,但如果它在资源受限的设备上运行,Chrome会将服务合并到一个进程中以节省内存使用。在此更改之前,类似的方法已在Android等平台上使用,以合并进程以减少内存使用。站点隔离站点隔离为每个跨站点iframe运行一个单独的渲染器进程,并在不同站点之间共享内存空间。同源策略是网络的核心安全模型,它确保一个站点不能在未经他们同意的情况下访问其他站点的数据。对于攻击者来说,绕过同源策略是安全攻击的主要目标,而对于浏览器来说,需要使用进程来分隔站点。从Chrome67开始,桌面端默认启用站点隔离,标签页中的每个跨站点iframe都有一个单独的渲染器进程,当然,从根本上改变了iframe之间的通信方式。2、导航跳转在浏览器中写入一个URL,然后浏览器从网上获取数据,显示一个页面。请求站点和浏览器在渲染之前做了什么?前面我们知道,tab之外的所有内容都是由浏览器进程处理的,也就是BrowserProcess。浏览器中的进程具有绘制按钮和输入的UI线程、处理网络堆栈以从Internet接收数据的网络线程、控制文件访问的存储线程等线程。当在地址栏中输入URL时,输入由浏览器进程的UI线程处理。入门第1步:处理输入当在地址栏中输入内容时,UI线程首先询问的是“这是搜索查询还是URL?”。在Chrome中,地址栏也是一个搜索输入框,因此UI线程需要解析它并决定是将其发送到搜索引擎,还是发送到请求的站点。第2步:开始查找当按下Enter键时,UI线程发起网络请求以获取站点内容。Loading微调器显示在选项卡的一角,网络线程通过适当的协议,例如DNS查找和为请求建立TLS连接。此时,网络线程可能会收到服务器重定向头,例如HTTP301。此时,网络线程与服务器请求重定向的UI线程进行通信。然后,将发出另一个URL请求。第3步:读取响应一旦响应的开头出现,即请求的有效负载,网络线程会在必要时查看流的前几个字节。响应的Content-Type标头应该说明它是什么类型的数据,但由于它可能丢失或错误,因此在这里完成MIME类型验证。如果响应是一个HTML文件,那么下一步就是将数据传递给GPU进程,但是如果它是一个zip文件或其他一些文件,那么它就是一个下载请求,然后他们需要将数据传递给下载经理。它也是执行安全浏览检查的地方。如果域和相应的数据匹配到恶意网站,网络线程将发送警报并显示警告页面。在此过程中还会进行CORS检查,以确保不会将敏感的跨站数据丢给Renderer。第四步:找到渲染器进程一旦完成所有检查并且网络线程确定浏览器应该导航到请求的站点,网络线程就会告诉UI线程数据已准备就绪。然后UI线程找到渲染器进程来渲染网页。由于网络请求可能需要数百毫秒才能获得响应,因此应用优化来加速该过程。当UI线程在第2步中向网络线程发送URL请求时,它已经知道他们想要导航到哪个站点。UI线程尝试与网络请求并行地主动查找或启动渲染器进程。这样,如果一切按预期进行,渲染器进程在网络线程接收到数据时已经处于待命状态。如果导航跨站点重定向,则可能不会使用此替代过程,在这种情况下可能需要不同的过程。第5步:提交现在数据和呈现器进程已准备就绪,IPC从浏览器进程发送到呈现器进程以提交导航。它还传递数据流,因此呈现器进程可以继续接收HTML数据。一旦浏览器进程听到渲染器进程中发生提交的确认,导航就完成了,文档渲染阶段开始了。此时,地址栏已经更新,安全指示器和站点设置UI反映了新页面的站点信息。该选项卡的会话历史记录将更新,因此后退/前进按钮将逐步浏览您刚刚导航到的站点。为了在关闭选项卡或窗口时促进选项卡/会话恢复,会话历史记录存储在磁盘上。其他步骤提交后,renderer进程会继续加载资源,渲染页面。当渲染器进程“完成”渲染时,它会将IPC发送回浏览器进程(这是在页面加载中的所有帧上触发所有事件并完成执行之后)。此时,UI线程停止在选项卡上加载小负载。在这一点之后,客户端JavaScript仍然可以加载额外的资源并呈现新的视图。导航到其他站点如果用户再次将不同的URL放入地址栏会怎样?浏览器进程通过相同的步骤导航到不同的站点。但在此之前,它需要检查当前呈现的站点是否有beforeunload事件。beforeunload可以创建一个“离开这个站点?”事件,该事件在左或关闭选项卡时提醒。选项卡内的所有内容,包括JavaScript代码,都由渲染器进程处理,因此当有新的导航请求进入时,浏览器进程必须检查当前的渲染器进程。注意:不要添加无条件的beforeunload处理程序。它会导致更多延迟,因为处理程序需要在导航开始之前执行。只应在必要时添加此事件处理程序,例如,如果需要警告用户他们可能会丢失在页面上输入的数据。当新导航到达与当前呈现的站点不同的站点时,将调用单独的呈现进程来处理新导航,同时保持当前呈现进程处理诸如卸载之类的事情。有关页面生命周期状态的信息,请参见此处。下图是从浏览器进程到新渲染器进程的2个IPC,告诉页面渲染,告诉旧渲染器进程卸载:从网络中检索得到新的数据。如果服务工作者设置为从缓存加载页面,则无需从网络请求数据。注意:ServiceWorker是在渲染器进程中运行的JavaScript代码。但是当导航请求进来时,浏览器进程如何知道哪个站点有ServiceWorker?注册ServiceWorker后,ServiceWorker的范围将被保留。发生导航时,网络线程会根据已注册的服务工作人员范围检查域,如果为URL注册了服务工作人员,则UI线程会查找渲染器进程来执行服务工作人员代码。ServiceWorker可能会从缓存中加载数据,这样它就不需要从网络请求数据,或者它可能会从网络请求新资源。下图是浏览器进程中的UI线程启动了renderer进程来处理serviceworker;渲染器进程中的工作线程然后从网络请求数据:导航预加载如果服务工作线程最终决定从网络请求数据,则浏览器进程和渲染器进程之间的这种往返可能会导致延迟。导航预加载是一种通过在ServiceWorker启动的同时加载资源来加速此过程的机制。它用标头标记这些请求,允许服务器决定为这些请求发送不同的内容;例如,只更新数据而不是完整的文档。3.渲染导航后,浏览器会调用渲染器(UI)进程进行工作。渲染器进程处理Web渲染器进程负责选项卡内发生的所有事情。在渲染器进程中,主线程处理大部分发送给用户的代码。如果使用WebWorker或ServiceWorker,一些JavaScript由工作线程处理。合成器和光栅器线程也在渲染器进程中运行,以高效、流畅地渲染页面。渲染器进程的核心工作是将HTML、CSS和JavaScript转换成用户可以与之交互的网页。解析和构建DOM当渲染进程接收到用于导航的提交消息并开始接收HTML数据时,主线程开始解析HTML并将其制作成DOM。DOM是浏览器对页面的内部表示,是开发人员可以通过JavaScript与之交互的数据结构和API。将HTML文档解析成DOM是HTML标准定义的,所以有时错误的标签会被自动更正。有关详细信息,请参阅解析器中的错误处理。子资源加载对于图像、CSS、JavaScript等外部资源,需要从网络或缓存中加载。主线程在解析和构建DOM的过程中,可以找到并一一请求,但是为了加快速度,“preloadscanner”并发运行。如果HTML文档中有类似或的东西,预加载扫描器会查看HTML解析器生成的令牌,并将请求发送到浏览器进程中的网络线程。JavaScript可以阻止解析当HTML解析器找到标签中添加async或defer属性。然后浏览器异步加载和运行JavaScript代码,并且不会阻止解析。如果浏览器支持,当然你也可以使用JavascriptModule。
