[Chromium中文文档]Chromium如何展示网页

2024-06-08 18:18

本文主要是介绍[Chromium中文文档]Chromium如何展示网页,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//Start_Here_Background_Reading/How_Chromium_Displays_Web_Pages.html

全书地址

Chromium中文文档 for https://www.chromium.org/developers/design-documents
持续更新ing,欢迎star
gitbook地址:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//
github地址: https://github.com/ahangchen/Chromium_doc_zh

Chromium如何展示网页

这个文档从底层描述了Chromium是如何展示网页的。请确认你已经读过多进程架构这篇文章。你会特别想要了解主要组件的框架。你也可能对多进程资源加载感兴趣,以了解网页是如何从网络中获取到的。

应用概念层

layer

(关于这个阐述的原始Google文档是http://goo.gl/MsEJX,开放给所有@chromium.org的人编辑)

每个矩形代表了一个应用概念层,每一层都不了解上一层,也对上一层没有依赖。

  • WebKit:Safari,Chromium和其他所有基于WebKit的浏览器共享的渲染引擎。WebKit Port是WebKit的一个部分,用来集成平台独立的系统服务,比如资源加载与图像。

  • Glue:将WebKit的类型转为Chromium的类型。这就是我们的“WebKit嵌入层”。这是两个browser,Chromium,和test_shell(允许我们测试WebKit)的基础。

  • Renderer / Render host: 这是Chromium的“多进程嵌入层”。它代理通知,并跨过进程边界执行指令。

  • WebContents:一个可重用的组件,是内容模块的主类。它易于嵌入,允许多进程将HTML绘制成View。查看content module pages以获得更多信息。

  • Browser: 代表浏览器窗口,包含多个WebContent。

  • Tab Helpers:可以被绑定到WebContent的独立对象(通过WebContentsUserData混杂)。浏览器将这些独立对象中的一种绑定到WebContent给它持有,一个给网站图标,一个给信息栏,等等。

WebKit

我们使用WebKit开源工程来布局web页面。这部分代码是从Apple中pull过来的,存储在/third_party/WebKit目录。WebKit主要由“WebCore”组成,这代表了核心的布局功能,还有“JavaScriptCore”,这被用来运行JavaScript。我们只在测试时运行JavaScriptCore,通常情况下,我们用我们自己高性能的V8 Javascript引擎来代替它。事实上,我们不完全是使用Apple称之为“WebKit”的那一层,这是WebCore和OS X应用程序(比如Safari)之间的嵌入API。为了方便,我们通常把从Apple学到的代码称为“WebKit”。

The WebKit port

在最低层,我们有我们的WebKit “port”。这是我们对于需要的平台相关功能的实现,它们与平台无关的WebCore代码交互。这些文件在WebKit树上,通常在chromium目录,或以Chromium为后缀的文件中。我们的port中的大部分其实是与操作系统无关的:你可以把它认为WebCore的“Chromium port”。但某些方面,比如字体渲染,必须在不同平台上做不同的处理。

  • 网络交流由我们的多进程资源加载系统处理,而非直接从渲染线程跳到操作系统处理
  • 图像使用了为Android开发的Skia图形库。这是一个跨平台的图形库,处理所有的图形和图像,除了文本。Skia在/third_party/skia里。图形操作的主要入口是/webkit/port/platform/graphics/GraphicsContextSkia.cpp。它在这个目录里,使用了许多其他的文件,还有那些/base/gfx里的文件。

The WebKit glue(胶水)

Chromium应用程序使用不同的类型,编码风格,以及代码布局和第三方的WebKit代码。WebKit胶水使用Google编码传统与类型为WebKit提供了一个更加方便的嵌入式API(例如,我们使用std::string而非WebCore::String,使用GURL而非KURL)。胶水代码位于/webkit/glue。glue对象通常有与WebKit对象相似的命名,但在开头有Web前缀。例如, WebCore::Frame变成了WebFrame。

WebKit胶水层将Chromium代码的其他部分与WebCore数据类型隔离开,以帮助减少WebCore的改变对Chromium代码基础的影响。因此,WebCore数据类型从不直接被Chromium使用。为了Chromium的便利,需要碰一些WebCore对象时,会把API加入WebKit的胶水层。

test shell应用程序是一个为测试我们的WebKit port和胶水代码的裸web浏览器。它在与WebKit交流时,像Chromium那样使用一样的胶水接口。它为开发者提供了简单的方式去测试新的代码,而不用理会许多复杂的浏览器特性,线程和进程。这个应用程序也被用于运行自动化WebKit测试。然而,test shell的缺点在于,它不像Chromium那样用多进程方式实践WebKit。内容模块嵌入在一个被称为“content shell”的应用程序,它很快就能用于测试工作。

渲染器进程

这里写图片描述

Chromium的浏览器进程使用胶水接口嵌入在我们的WebKit port中,它不包含很多代码:它的工作主要是作为渲染器端到浏览器的IPC通道。渲染器中最重要的类是RenderView,位于/content/renderer/render_view_impl.cc。这个对象代表一个web页面。它处理与浏览器之间所有导航相关的命令。它驱动RenderWidget提供绘图和输入事件处理。

RenderView与浏览器进程通过全局(每个渲染器进程)RenderProcess对象与浏览器进程交流。

**FAQ:RenderWidget和RenderViewHost之间的区别在哪里?**RenderWidget通过在胶水层实现抽象接口(称为WebWidgetDelegate)映射到一个WebCore::Widget对象。基本一个屏幕上的window接收输入事件和我们画进去的东西。一个RenderView继承自RenderWidget,并且是一个标签页或一个填出窗口的内容。除了绘制与组件输入事件外,它还处理导航指令。只有一种情况下,RenderWidget可以在没有RenderView时存在,就是网页中的下拉选择框(select box)。下拉选择框必须用native window来渲染,这样他们可以在任何其他空间上方出现,并在必要时弹出。这些window需要绘制和接受输入,但他们没有独立的web页面(RenderView)。

渲染器中的线程

每个渲染器有两个线程(查看多进程架构页面来查看图表,或者threading in Chromium来理解如何用它们编程)。渲染线程是主要的对象,比如RenderView和所有的WebKit代码运行的地方。当它与浏览器交流时,消息一开始发送到主线程,主线程轮流分发消息给浏览器进程。在其他情况里,这允许我们从渲染器同步发送消息到浏览器。当一个来自浏览器的结果是用于后续操作时,这可以用于小量的操作。一个例子是,JavaScript从网页请求cookie。渲染器线程会阻塞,主线程会让所有的接收到的消息排队,直到得到正确的响应。此时任何接收到的消息会突然发送给渲染器线程以执行普通的处理。

浏览器进程

这里写图片描述

底层浏览器进程对象

所有的与渲染器进程交流的IPC是在浏览器的I/O线程完成的。这个线程也处理所有的网络交流,使得它不受用户界面的干扰。

当一个RenderProcessHost对象在主线程完成初始化(当用户界面运行时),它会创造新的渲染器进程和一个通道代理IPC对象(有一个命名了的管道通向渲染器),自动转发所有的消息回给UI线程的RenderProcessHost。一个ResourceMessageFilter会安装在这个通道,它会过滤我们指定的消息,以直接在I/O线程处理(比如网络请求)。这个过滤器发生在ResourceMessageFilter::OnMessageReceived里。

UI线程中的RenderProcessHost负责分发所有view相关消息给合适的RenderViewHost(它自己处理有限数量的与View相关的消息)。这种分发发生在RenderProcessHost::OnMessageReceived。

上层浏览器进程对象

View相关消息出现在RenderViewHost::OnMessageReceived。这里处理的大部分消息,剩下的部分转发给RenderWidgetHost基类。这两个对象在渲染器里里映射到RenderView和RenderWidget(查看上面的“渲染器进程”来理解它们的含义)。每个平台有一个view类(RenderWidgetHostView[Aura|Gtk|Mac|Win])以集成到native view系统。

在RenderView/Widget上面是WebContents对象,大部分的消息事实上结束于这个对象的函数调用。一个WebContent代表网页的内容。它是内容模块的顶层对象,并且负责在一个矩形的view中展示网页。查看内容模块页面获取更多信息。

WebContents对象包含在一个TabContentsWrapper中,它位于chrome/。负责标签页。

说明样例

额外的例子(包含了导航和启动相关代码)在Getting Around the Chromium Source Code里。

“设置光标”消息的生命周期

设置光标是一个渲染器发往浏览器的典型消息的例子。在渲染器端,以下是发生的事情:

  • 设置光标消息由WebKit内部生成,通常是作为输入事件的响应。设置光标消息开始于 content/renderer/render_widget.cc中的RenderWidget::SetCursor。

  • 它会调用RenderWidget::Send来分发消息。这个方法也用于RenderView向browser分发消息。它会调用 RenderThread::Send.

  • 这会调用IPC::SyncChannel,它在内部代理消息到渲染器的主线程,并将其发送给命名的管道以发送给浏览器。

然后浏览器获得了控制权:

  • RenderProcessHost中的IPC::ChannelProxy通过浏览器的I/O线程接收所有的消息。它首先把他们通过ResourceMessageFilter(它在I/O线程上直接分发网络请求与相关的消息)发送出去。由于我们的消息没有被过滤掉,它继续发送到浏览器的UI线程(IPC::ChannelProxy在内部完成这个事情)。

    content/browser/renderer_host/render_process_host_impl.cc中的RenderProcessHost::OnMessageReceived为所有的View在对应的渲染进程获取消息。它直接处理几种消息,并把剩下的部分转发到合适的与发送消息的源RenderView对应的RenderViewHost。

    消息到达content/browser/renderer_host/render_view_host_impl.cc中的RenderViewHost::OnMessageReceived。许多消息是在这里处理的,但我们这时的消息不是,因为它是一个从RenderWidget来,由RenderWidgetHost处理的消息。

    RenderViewHost中所有未处理的消息自动转发给了RenderWidgetHost,包括我们的设置光标消息。

    这个映射到content/browser/renderer_host/render_view_host_impl.cc的消息最终在RenderWidgetHost::OnMsgSetCursor接收到消息,并调用合适的UI函数来设置鼠标的光标。

“鼠标点击”消息的生命周期

发送一个鼠标点击是一个经典的浏览器到渲染器的例子。

  • Windows消息在浏览器的UI线程被RenderWidgetHostViewWin::OnMouseEvent接收,然后在同一个类中调用ForwardMouseEventToRenderer。

  • 转发函数打包输入时间为一个跨平台的WebMouseEvent,最后把它发送到它所关联的RenderWidgetHost.

  • RenderWidgetHost::ForwardInputEvent创建一个IPC消息ViewMsg_HandleInputEvent,将这个WebInputEvent对象序列化进去,然后调用RenderWidgetHost::Send。

  • 这只是转发到自己的RenderProcessHost::Send函数,它会轮流将消息发送给IPC::ChannelProxy。

  • 在内部,IPC::ChannelProxy会将消息代理到浏览器的I/O线程,将它写入渲染器对应的命名管道。

注意,许多种消息创建于WebContents,特别是导航类的消息。这些消息遵循一个相似的从WebContents到RenderViewHost的路径。

然后渲染器得到了控制权:

  • 渲染器主线程的IPC::Channel读取浏览器发送的消息,然后IPC::ChannelProxy将消息代理到渲染线程。

  • RenderView::OnMessageReceived拿到这个消息。许多种消息在这里直接处理。由于点击事件不是,它继续往下走(和其他所有没有被处理的消息一起)到RenderWidget::OnMessageReceived,它会轮流把消息转发给RenderWidget::OnHandleInputEvent。

  • 输入事件被交给WebWidgetImpl::HandleInputEvent,在这里它被转换成一个WebKit PlatformMouseEvent类,然后交给WebKit内的WebCore::Widget类。

这篇关于[Chromium中文文档]Chromium如何展示网页的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1042942

相关文章

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

利用Python操作Word文档页码的实际应用

《利用Python操作Word文档页码的实际应用》在撰写长篇文档时,经常需要将文档分成多个节,每个节都需要单独的页码,下面:本文主要介绍利用Python操作Word文档页码的相关资料,文中通过代码... 目录需求:文档详情:要求:该程序的功能是:总结需求:一次性处理24个文档的页码。文档详情:1、每个

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

Python实现自动化删除Word文档超链接的实用技巧

《Python实现自动化删除Word文档超链接的实用技巧》在日常工作中,我们经常需要处理各种Word文档,本文将深入探讨如何利用Python,特别是借助一个功能强大的库,高效移除Word文档中的超链接... 目录为什么需要移除Word文档超链接准备工作:环境搭建与库安装核心实现:使用python移除超链接的

Python实现中文大写金额转阿拉伯数字

《Python实现中文大写金额转阿拉伯数字》在财务票据中,中文大写金额被广泛使用以防止篡改,但在数据处理时,我们需要将其转换为阿拉伯数字形式,下面我们就来看看如何使用Python实现这一转换吧... 目录一、核心思路拆解二、中文数字解析实现三、大单位分割策略四、元角分综合处理五、测试验证六、全部代码在财务票

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

Python自动化处理PDF文档的操作完整指南

《Python自动化处理PDF文档的操作完整指南》在办公自动化中,PDF文档处理是一项常见需求,本文将介绍如何使用Python实现PDF文档的自动化处理,感兴趣的小伙伴可以跟随小编一起学习一下... 目录使用pymupdf读写PDF文件基本概念安装pymupdf提取文本内容提取图像添加水印使用pdfplum