Chrome的表情符号

各种表情符号的图像。
各种表情符号的图像。

我们经常谈论最常用的表情符号——、、❤️……但是呢?谁来为发言?拥有超过 3,521 个表情符号,您必须滚动浏览很多内容才能找到。在家工作时,再加上 Unicode下一个表情符号发布的延迟,我们有一些时间来反思和回答去年看似反问的问题:如果没有新的表情符号,世界表情符号日会是什么样子?

好吧,这看起来像是对你键盘上已有的数百个表情符号给予了一些爱——专注于让它们更通用、更易于访问和更真实——这样你就可以找到一个全新的最爱表情符号(我喜欢)。而且,您可以在包括 Android、Gmail、Chat、Chrome OS 和 YouTube 在内的更多 Google 平台上找到所有这些表情符号(是的,包括国王,)。

适合所有人的表情符号

Emoji 的受众遍及全球,对它们而言,具有全球相关性非常重要。派表情符号是一个奇怪的表情——它以前看起来像一个非常特殊的美国南瓜派(家庭的最爱!)。现在这是每个人都认可的事情。我可以开个玩笑,说有更多的食物可以吃,但这并不是一个真正的玩笑:这个微小的变化意味着这个表情符号可以代表一大堆馅饼——苹果派、蓝莓派、草莓派、樱桃派、鸡肉馅饼、牛肉和蘑菇……不胜枚举。

馅饼表情符号的动画从整个馅饼的切片变化

你有没有想过为什么表情符号看起来像它的样子?就像,比基尼表情符号——真的需要一个隐形的幽灵穿着它吗?现在,任何身体都是比基尼身体。

比基尼表情符号的动画更改为新设计

其他表情符号的变化早就应该发生了。今年令人大开眼界,现在,面膜表情符号也是如此。这个表情符号起源于日本,人们甚至在 COVID-19 大流行之前就经常戴口罩。今天,蒙面是向他人表示善意的普遍方式。

面具表情符号睁开眼睛和眨眼的动画

你不能错过的表情包

在设计表情符号时,您经常不得不夸大尺寸。我们的交通表情符号现在更容易看到,因为新设计允许他们利用他们占用的小空间。

表情符号汽车的动画更改为新设计

完成工作的表情符号

然而,有时偏离现实太远意味着一个表情符号出现并嘲弄你,困扰你的梦想。哦,这不会发生在你身上吗?只有我?好吧,当我闭上眼睛时,我看到了剪刀表情符号 (✂️)。我知道这只是一个表情符号,并不需要能够实际切割东西……但新的可以!

剪刀表情符号的动画更改为新设计和闭合刀片

这份工作的好处之一是我可以学习各种各样的东西——比如手风琴设计的历史、章鱼的解剖结构、降落伞的工作原理!作为一个从来没有学过开车的人,设计表情符号才知道马路上的黄色画线告诉你要留在黄线的右边。但是,如果道路两侧是黄线,你怎么能留在黄线的右边呢?好吧,我们新设计的高速公路️ 将通过下一次驾驶考试。

高速公路更改为新设计的动画

其他表情符号只需要煮久一点(或者在某些情况下,放入油炸锅中)。

食物表情符号(羊角面包、米饭、培根、甜面包)的动画更改为新设计

让你在晚上陪伴的表情符号

如果您看得足够近,当您在一些新设计中切换到深色主题时,您可能还会注意到一些新增内容。

露营 emoji 的动画变成了用新星星变暗的动画

出现在比以往更多地方的表情符号

Android 12 将在今年秋季推出时包含所有这些表情符号。为了让每个人都能更轻松地看到表情符号,无论您的手机有多旧,或者您最喜欢的消息应用程序何时更新,从 Android 12 开始,所有支持 Appcompat 的应用程序都将自动获得最新最好的表情符号。 

不能等到秋天吗?从本月开始,您将可以在 Gmail 和 Chat 中发送 和接收 表情符号,而不必担心它们会损坏 。有 Chromebook 吗?我们已经为您提供了 ☔ 本月即将推出的闪亮的新表情符号选择器。在 YouTube 上观看您最喜欢的创作者并在实时聊天中聊天 ?今年晚些时候发送尽可能多的 表情符号。

Chrome的隐私沙盒承诺更新

自从我们今年早些时候宣布我们的隐私沙盒承诺以来,我们继续与英国竞争和市场管理局 (CMA) 合作,以解决作为其公众咨询过程的一部分提出的反馈。我们还继续更新并寻求市场和英国信息专员办公室 (ICO) 对我们的建议的反馈。

我们决心确保以适用于整个生态系统的方式开发隐私沙盒,作为此过程的一部分,我们现在提供了修订后的承诺,可以在CMA 的网站上找到完整的承诺。

这些修订强调了我们的承诺,即确保我们在 Chrome 中所做的更改将以与任何第三方相同的方式适用于 Google 的广告技术产品,并且隐私沙盒 API 的设计、开发和实施将受到监管监督和来自CMA 和 ICO。我们还支持昨天在 ICO 关于在线广告提案的数据保护和隐私期望的意见中提出的目标,包括支持和开发保护人们隐私和防止秘密跟踪的隐私安全广告工具的重要性。

修订后的承诺包含许多变化,包括:

  1. 监测和报告。我们已提议任命一名独立的监控受托人,他将拥有确保合规所需的访问权限和技术专长。
  2. 测试和咨询。我们向 CMA 提供了更广泛的测试承诺,以及更透明的流程来获取市场对隐私沙盒提案的反馈。
  3. 进一步明确我们对数据的使用。我们强调我们不会使用 Google 第一方个人数据来跟踪用户以定位和衡量在非 Google 网站上展示的广告的承诺。我们的承诺还将限制在 Google 或非 Google 网站上使用 Chrome 浏览历史记录和分析数据来执行此操作。

如果 CMA 接受这些承诺,我们将在全球范围内实施这些承诺。

在我们制定隐私沙盒提案时,我们继续感谢 CMA 和 ICO 的周到方法和参与。我们欢迎并将仔细考虑人们在咨询过程中提供的任何意见。

使用 Chrome 完成假日购物的 5 个技巧

文章的英雄媒体
文章的英雄媒体

我们正忙于假日购物,我们中的许多人都在网上疯狂地搜索最后一分钟的库存填充物。幸运的是,Chrome 即将推出一些新功能,这将使最后几轮购物变得更容易——帮助您跟踪想要购买的商品并最终点击“订购”。

以下是使用 Chrome 获得无压力购物体验的五种方法。

1. 跟踪降价:您是否正在等待那副耳机的优惠,但没有时间不断刷新页面?本周在美国的 Android 版 Chrome 上推出了一项新的移动功能,它将在您打开的标签网格中显示商品的更新价格,以便您轻松查看价格是否以及何时下降。同样的功能将在未来几周内在 iOS 上推出。

屏幕截图显示了 Chrome 中四个选项卡的网格。 两个标签是产品页面,并在标签预览顶部显示价格下降,以绿色突出显示。

2. 使用地址栏中的快照进行搜索:如果您在外出购物时有什么东西引起了您的注意,您现在可以使用 Android 版 Chrome 中的 Google Lens 搜索您的周围环境。在地址栏中,点击镜头图标并开始使用您的相机进行搜索。

即将推出,您还可以在桌面上的 Chrome 浏览器中使用智能镜头。如果您在图像中看到产品并想了解它是什么,只需右键单击并选择“使用 Google 镜头搜索图像”选项。

3. 重新发现你的购物车里有什么:你知道你的购物车里有物品,但你不记得具体在哪里。无需重新搜索。从美国的 Windows 和 Mac 上的 Chrome 开始,您现在可以打开一个新标签并滚动到“您的购物车”卡片,以快速查看您已将商品添加到购物车的任何网站。一些零售商,如 Zazzle、iHerb、Electronic Express 和 Homesquare,甚至可能会在您回来结账时提供折扣。

4. 从您的盘子中获取密码:不必担心为您最喜欢的购物网站设置和记住您的帐户详细信息。Chrome 可以帮助创建唯一、安全的密码并保存您的登录详细信息以供将来访问。

5. 简化结帐流程:通过使用 Autofill 保存您的地址和付款信息,Chrome 可以自动填写您的帐单和送货详细信息。当您在新表单中输入信息时,Chrome 会询问您是否要保存它。

2021 年最受欢迎的 Chrome 扩展程序

深蓝色背景,带有蓝色、红色、橙色和绿色的几个轮廓形状。 中间是一个金色的抽象奖杯,上面覆盖着一颗心和镀铬的标志轮廓。
深蓝色背景,带有蓝色、红色、橙色和绿色的几个轮廓形状。 中间是一个金色的抽象奖杯,上面覆盖着一颗心和镀铬的标志轮廓。

全年,来自世界各地的开发人员都在构建 Chrome 扩展程序,使浏览变得更轻松、更高效和更个性化——无论您是在网络上工作、学习、娱乐还是以上所有目的。今天,我们将分享我们今年最喜欢的扩展,帮助人们继续保持虚拟联系、完成工作并在此过程中获得一些乐趣。让我们仔细看看它们。

沟通和协作

无论您是在办公室、沙发上还是两者兼而有之,扩展都可以帮助您与队友保持联系。Loom可让您更轻松地捕捉视频并与他人分享,而Mote可让您通过语音评论和转录提供快速反馈。Wordtune还可以通过改写句子和捕捉电子邮件和文档中的拼写错误来帮助您进行清晰的交流。

Loom、Mote 和 Wordtune 的三个图标并排。 最左边的图标有一个蓝色的方形背景,中间有一个白色的星芒,下面标有“Loom”。 中间的图标有一个紫色的圆形背景,中间有一个草书“M”,下方标有“Mote”。 最右边的图标有一个深紫色的圆形背景,带有草书“W”,下方标有“Wordtune”。

保持生产力

其他扩展提供了保持专注和高效的新方法。Forest通过虚拟植树和奖励来提高生产力,而Dark Reader在漫长的工作日中保护您的眼睛(和睡眠时间)。Tab Manager Plus还可让您免于淹没在无尽的标签海洋中,而Nimbus 屏幕截图和屏幕录像机可以更轻松地快速截屏和录制内容以跨平台共享。

Forest、Dark Reader、Tab Manager Plus 和 Nimbus Screenshot & Screen Video Recorder 的四个图标并排排列。 最左边的图标有绿色背景,前景是土壤和树叶,下面标有“森林”。 右边的图标有一个透明的背景,前景是一个带有发光眼镜的黑头,下面标有“Dark Reader”。 其右侧的图标具有透明背景,三个浏览器窗口重叠,颜色为黄色、绿色和橙色,在其下方标有“Tab Manager Plus”。 最右边的图标有一个透明的背景,带有一个虚线的蓝色方形轮廓,中间有一个蓝色的“N”,右下角有一个蓝色的加号。 在下面,它被标记为“Nimbus Screenshot & Screen Video Recorder”。

虚拟学习

随着在线教育比以往任何时候都多,学生和教师需要有用的虚拟课堂工具。Kami为学生和教师创建了一个交互式在线学习空间,InsertLearning可帮助您轻松记笔记并与 Google Classroom 集成。同时,Toucan让学习新语言变得有趣和身临其境,Rememberry将词汇组织成抽认卡组,以便全天快速学习。

Kami、InsertLearning、Toucan 和 Rememberry 的四个图标并排。 最左边的图标有一个圆形的蓝色背景,中间有一个白色的粗体“K”,下面标有“Kami”。 其右侧的图标为深紫色方形背景,中间有一个粗体“IL”,下方标有“InsertLearning”。 其右侧的图标有绿色背景,前景是一只巨嘴鸟,在其下方标有“巨嘴鸟”。 最右边的图标有一个透明的背景,一个人头轮廓朝左,一个圆圈,一端有一个箭头,指向逆时针方向。 在下面,它被标记为“记忆”。

进行(并保存)一些更改

为了给您的浏览体验带来个性化的体验,Stylus可帮助您为您喜爱的网站构建和安装自定义主题和皮肤。乐天通过在网络上自动查找优惠券和交易,将现金返还到您的口袋里——在网上购物最繁忙的一年中尤其有用。

Stylus 和 Rakuten 的两个图标并排。 左边的图标有一个深蓝色的方形背景,有一个浅蓝色的轮廓,中间有一个浅蓝色的“S”,下面标有“手写笔”。 右边的图标有一个透明的背景,中间有一个紫色的“R”并带有下划线,下面标有“Rakuten”。

要安装和了解有关这些扩展程序的更多信息,请访问我们的 2021 年 Chrome 网上应用店收藏夹系列。如果您是一名开发人员,正在寻找设计高质量 Chrome 扩展程序的技巧,请查看我们的最佳实践

Chrome 中的新变化

Chrome 浏览器界面:显示了针对“youtube”一词执行的标签页搜索。

Chrome 的速度和易用性随着一次次的更新不断提升。试试新功能:更好的链接发送方式,以及更快速地找到所需标签页。

工作效率

正在分享链接?那就让链接直接跳到要分享的确切部分吧。

在分享链接时尝试使用“复制指向突出显示的内容的链接”选项。当收件人打开您分享的链接时,会直接看到相应页面中您选中的那部分内容(而非此页的页首)。

  1. 突出显示您想分享的文本。
  2. 右键点击所选内容,然后选择复制指向突出显示的内容的链接
  3. 将链接粘贴到任意位置,例如电子邮件或会话集内。
Chrome 浏览器界面:显示了针对“youtube”一词执行的标签页搜索。

工作效率

使用“标签页搜索”功能更快速地找到所需标签页

打开了很多标签页?如果您无法快速找到自己所需的标签页,不妨试试 Chrome 的“标签页搜索”功能。

在您的 Chrome 窗口顶部,点击“标签页搜索”图标 ,即可查看您已打开的所有 Chrome 标签页的列表。

Chrome 浏览器界面:显示了在个人资料选择屏幕“谁在使用 Chrome?”中,一个名为“Elisa Beckett”的用户名下有 2 份不同的个人资料。

CHROME 小窍门

为 Chrome 选择一个新的背景和配色

想让您的浏览器旧貌换新颜?不妨试试 Chrome 的背景和颜色选项。如果您有多份 Chrome 个人资料,甚至能为每份个人资料采用不同的背景。

  1. 打开新标签页。
  2. 在右下角,点击  自定义 Chrome

Chrome为何不再支持Flash

自 2021 年起,Adobe 已停止为 Flash Player 插件提供支持。在任何版本的 Chrome 中,Flash 内容(包括音频和视频)都将无法再正常播放。只有ie内核浏览器(ie、MyIE)才能播放flash。
chrome为什么不再支持flash呢?

Adobe 宣布计划在 2020 年底停止支持 Flash。

20 年来,Flash 帮助塑造了您在网络上玩游戏、观看视频和运行应用程序的方式。但在过去的几年里,Flash 变得不那么普遍了。三年前,80% 的桌面Chrome用户每天都使用 Flash 访问网站。今天的使用率只有17%,而且还在继续下降。

这一趋势表明,网站正在向开放网络技术迁移,这些技术比 Flash 更快、更节能。它们也更安全,因此您在购物、银行业务或阅读敏感文件时可以更加安全。它们还适用于移动设备和桌面设备,因此您可以在任何地方访问您最喜爱的网站。

去年底,当网站开始需要征得您的许可才能运行 Flash 时,这些开放的网络技术成为 Chrome 的默认体验。在接下来的几年里,Chrome 将继续逐步淘汰 Flash,首先要求您允许在更多情况下运行 Flash,并最终默认禁用它。到 2020 年底,我们将从 Chrome 中彻底移除 Flash。

如果您现在经常访问使用 Flash 的网站,您可能想知道这对您有何影响。如果该站点迁移到开放 Web 标准,您应该不会注意到太大的不同,只是您将不再看到在该站点上运行 Flash 的提示。如果该站点继续使用 Flash,并且您授予该站点运行 Flash 的权限,则它将持续到 2020 年底。

与 Adob​​e、其他浏览器和主要出版商进行了大量密切合作,以确保 Web 已准备好实现无 Flash。我们支持 Adob​​e 今天的声明,我们期待与大家合作,让网络变得更好。

Chrome如何启用Flash

1.点击地址栏头部位置

2. 点击网站设置。

(如果已经有flash,则点击允许即可)

3. 找到flash,点击允许。

说明:

再打开Chrome时,每次都得这么设置。

可以安装MyIE浏览器,对需要flash的网站,直接用MyIE打开即可。

chrome多进程架构

问题

构建几乎不会崩溃或挂起的渲染引擎几乎是不可能的。构建完全安全的渲染引擎几乎也是不可能的。

在某种程度上,2006年左右的网络浏览器的状态类似于过去的单用户,协作多任务操作系统。由于此类操作系统中的行为异常的应用程序可能会破坏整个系统,因此Web浏览器中的行为异常的网页也可能因此而崩溃。它只需要一个浏览器或插件错误即可关闭整个浏览器和所有当前运行的选项卡。

现代操作系统更强大,因为它们将应用程序置于相互隔离的单独进程中。一个应用程序中的崩溃通常不会损害其他应用程序或操作系统的完整性,并且每个用户对其他用户数据的访问受到限制。

建筑概述

我们对浏览器选项卡使用单独的过程,以保护整个应用程序免受渲染引擎中的错误和干扰。我们还限制了每个渲染引擎进程对其他进程以及系统其余部分的访问。在某些方面,这为Web浏览带来了内存保护和访问控制带给操作系统的好处。

我们将运行UI并管理选项卡和插件过程的主要过程称为“浏览器过程”或“浏览器”。同样,特定于选项卡的过程称为“渲染过程”或“渲染器”。渲染器使用Blink开源布局引擎来解释和布局HTML。

管理渲染过程

每个渲染进程都有一个全局RenderProcess对象,该对象管理与父浏览器进程的通信并维护全局状态。浏览器RenderProcessHost 为每个渲染进程维护一个对应项,该进程管理浏览器状态和渲染器的通信。浏览器和渲染器使用Chromium的IPC系统进行通信。

管理视图

每个渲染过程都有一个或多个RenderView对象,由管理RenderProcess,这些对象对应于内容的选项卡。对应项 在渲染器中RenderProcessHost维护RenderViewHost与每个视图对应的内容。每个视图都有一个视图ID,该ID用于区分同一渲染器中的多个视图。这些ID在一个渲染器中是唯一的,但在浏览器中不是唯一的,因此要识别视图,需要一个RenderProcessHostID和一个View ID。通过这些RenderViewHost对象可以完成从浏览器到特定内容选项卡的通信,这些对象知道如何将消息通过它们发送RenderProcessHostRenderProcessRenderView

组件和接口

在渲染过程中:

  • 在浏览器中RenderProcess使用相应的句柄处理IPC RenderProcessHostRenderProcess每个渲染过程只有一个对象。这就是所有浏览器↔渲染器通信的发生方式。
  • RenderView对象RenderViewHost在浏览器进程中(通过RenderProcess)和我们的WebKit嵌入层与其对应的对象通信。此对象表示选项卡或弹出窗口中一个网页的内容

在浏览器过程中:

  • Browser对象表示顶级浏览器窗口。
  • RenderProcessHost对象表示单个浏览器↔渲染器IPC连接的浏览器端。有一个RenderProcessHost在每个渲染过程中的浏览器进程。
  • RenderViewHost对象封装的通信与远程RenderViewRenderWidgetHost处理用于输入和绘画RenderWidget在浏览器中。

有关此嵌入的工作方式的更多详细信息,请参阅Chromium如何显示网页  设计文档。

共享渲染过程

通常,每个新窗口或选项卡都会在新过程中打开。浏览器将产生一个新进程,并指示它创建一个RenderView

有时有必要或希望在选项卡或窗口之间共享渲染过程。Web应用程序会打开一个新窗口,希望与之进行同步通信,例如,使用  JavaScript中的window.open。在这种情况下,当我们创建新的窗口或选项卡时,我们需要重用打开窗口的过程。如果进程总数太大,或者用户已经打开一个导航到该域的进程,我们还可以为新进程分配新选项卡的策略。这些策略在过程模型中进行了描述。

检测崩溃或行为异常的渲染器

与浏览器进程的每个IPC连接都会监视进程句柄。如果发出了这些句柄的信号,则表示渲染过程已崩溃,并且向选项卡通知了崩溃。现在,我们显示一个“悲伤的标签”屏幕,通知用户渲染器崩溃了。可以通过按下重新加载按钮或开始新的导航来重新加载页面。发生这种情况时,我们注意到没有任何流程,而是创建一个新的流程。

沙盒渲染器

鉴于渲染器在单独的进程中运行,我们有机会通过sandboxing限制其对系统资源的访问。例如,我们可以确保渲染器对网络的唯一访问是通过其父浏览器进程进行的。同样,我们可以使用主机操作系统的内置权限来限制其对文件系统的访问。

除了限制渲染器对文件系统和网络的访问之外,我们还可以限制对渲染器对用户的显示和相关对象的访问。我们在用户看不见的单独Windows“ 桌面 ” 上运行每个渲染过程。这样可以防止受损的渲染器打开新窗口或捕获击键。

回馈记忆

给定渲染器在单独的进程中运行,将隐藏的选项卡视为较低优先级就变得很简单。通常,Windows上最小化的进程会将其内存自动放入“可用内存”池中。在低内存情况下,Windows将在交换出更高优先级的内存之前将该内存交换到磁盘上,从而有助于使用户可见的程序具有更高的响应速度。我们可以将相同的原理应用于隐藏的标签。当渲染进程没有顶级选项卡时,我们可以释放该进程的“工作集”大小,以提示系统在必要时先将该内存换出到磁盘。因为我们发现减小工作集大小也会降低用户在两个选项卡之间切换时的选项卡切换性能,所以我们逐渐释放此内存。这意味着,如果用户切换回最近使用的选项卡,则与最近使用的选项卡相比,该选项卡的内存更有可能被分页。具有足够内存来运行所有程序的用户根本不会注意到此过程:Windows仅会在需要时才真正回收这些数据,因此,如果有足够的内存,则不会对性能造成任何影响。

这有助于我们在低内存情况下获得更好的内存占用。与很少使用的背景标签相关联的内存可以完全换出,而前景标签的数据可以完全加载到内存中。相比之下,单进程浏览器会将所有选项卡的数据随机分布在其内存中,并且不可能如此干净地分离使用和未使用的数据,从而浪费内存和性能。

插件和扩展

Firefox风格的NPAPI插件在其自身的进程中运行,与渲染器分开。插件体系结构中对此进行了详细描述。 

“ 网站隔离”项目旨在提供渲染器之间的更多隔离,该项目的早期交付成果包括在隔离的进程中运行Chrome的HTML / JavaScript内容扩展。

chrome渲染引擎blink如何工作

眨眼的工作原理

bit.ly/how-blink-works

作者:haraken @

最后更新:2018年8月14日

状态:PUBLIC

 

在眨眼上工作并不容易。对于新的Blink开发人员而言,这并不容易,因为已经引入了许多特定于Blink的概念和编码约定来实现非常快速的渲染引擎。即使对于有经验的Blink开发人员来说,这也不容易,因为Blink庞大且对性能,内存和安全性极为敏感。

 

本文档旨在提供1 万英尺的“ Blink的工作原理”概述,我希望它将有助于Blink开发人员快速熟悉该体系结构:

 

  • 该文档不是有关Blink详细架构和编码规则(可能会更改和过时)的详尽教程。相反,该文档简明扼要地描述了Blink的基本原理(短期内不太可能改变),并指出了您想了解更多信息时可以阅读的资源。
  • 该文档未解释特定功能(例如ServiceWorkers,编辑)。而是该文档解释了广泛的代码库所使用的基本功能(例如,内存管理,V8 API)。

 

有关Blink开发的更多常规信息,请参阅Chromium Wiki页面

 

眨眼做什么

流程/线程架构

工艺流程

线程数

闪烁的初始化

目录结构

内容公共API和Blink公共API

目录结构和依赖性

WTF

内存管理

任务调度

页面,框架,文档,DOMWindow等

概念

OOPIF

分离的框架/文件

Web IDL绑定

V8和闪烁

隔离,上下文,世界

V8 API

V8包装器

渲染管线

有什么问题吗

 

眨眼做什么

Blink是Web平台的渲染引擎。粗略地说,Blink实现了所有在浏览器选项卡中呈现内容的内容:

 

  • 实施Web平台的规范(例如HTML标准),包括DOM,CSS和Web IDL
  • 嵌入V8并运行JavaScript
  • 从基础网络堆栈请求资源
  • 建立DOM树
  • 计算样式和布局
  • 嵌入Chrome合成器并绘制图形

 

许多用户(例如Chromium,Android WebView和Opera)通过内容公开API嵌入了Blink 

 

从代码库的角度来看,“闪烁”通常是指// third_party / blink /。从项目角度来看,“闪烁”通常表示实现Web平台功能的项目。实现Web平台功能的代码跨越// third_party / blink /,// content / renderer /,// content /浏览器/和其他地方。

流程/线程架构

工艺流程

铬具有多工艺体系结构。Chromium具有一个浏览器进程和N个沙盒渲染器进程。闪烁在渲染器进程中运行。

 

创建了多少个渲染器进程?出于安全原因,隔离跨站点文档之间的内存地址区域非常重要(这称为Site Isolation)。从概念上讲,每个渲染器过程最多应专用于一个站点。但是实际上,当用户打开太多标签页或设备没有足够的RAM时,有时将每个渲染器进程限制在一个站点上有时会很繁琐。然后,渲染器进程可以由从不同站点加载的多个iframe或标签共享。这意味着一个选项卡中的iframe可以由不同的渲染器进程托管,而不同选项卡中的iframe可以由相同的渲染器进程托管。渲染器进程,iframe和Tab之间没有1:1映射

 

假定渲染器进程在沙箱中运行,则Blink需要要求浏览器进程调度系统调用(例如,文件访问,播放音频)并访问用户配置文件数据(例如Cookie,密码)。这种浏览器-渲染器过程通信是由Mojo实现的。(注意:过去我们使用的是Chromium IPC,但仍然有很多地方在使用它。但是,它已被弃用,并在后台使用Mojo。)在Chromium方面,服务化正在进行中,并将浏览器过程抽象为一组“服务。从Blink角度来看,Blink可以仅使用Mojo与服务和浏览器进程进行交互。

 

如果您想了解更多信息:

 

  • 多进程架构
  • Blink中的Mojo编程:platform / mojo / MojoProgrammingInBlink.md

线程数

在渲染器进程中创建了多少个线程?

 

眨眼有一个主线程,N个工作线程和几个内部线程。

 

几乎所有重要的事情都在主线程上发生。所有JavaScript(工人除外),DOM,CSS,样式和布局计算都在主线程上运行。假设主要是单线程体系结构,Blink进行了高度优化以最大化主线程的性能。

 

眨眼可能会创建多个工作线程来运行Web WorkersServiceWorkerWorklets

 

Blink和V8可能会创建几个内部线程来处理webaudio,数据库,GC等。

 

对于跨线程通信,必须使用通过PostTask API传递消息。不建议使用共享内存编程,除了出于性能原因确实需要使用它的几个地方。这就是为什么您在Blink代码库中看不到很多MutexLocks的原因。

 

如果您想了解更多信息:

 

闪烁的初始化和完成

眨眼由BlinkInitializer :: Initialize()初始化。在执行任何Blink代码之前必须调用此方法。

 

另一方面,Blink从未完成。也就是说,渲染器进程被强制退出而不进行清理。原因之一是性能。另一个原因是,通常很难以一种有序的方式清理渲染器进程中的所有内容(这是不值得的工作)。

目录结构

内容公共API和Blink公共API

内容公共API是使嵌入程序嵌入呈现引擎的API层。内容公共API必须小心维护,因为它们会暴露在嵌入程序中。

 

眨眼公共API是将// // third_party / blink /的功能公开给Chromium的API层。该API层只是从WebKit继承的历史工件。在WebKit时代,Chromium和Safari共享WebKit的实现,因此需要API层才能将WebKit的功能公开给Chromium和Safari。既然Chromium是// third_party / blink /的唯一嵌入者,那么API层就没有意义了。通过将网络平台代码从Chromium移到Blink(该项目称为Onion Soup),我们正在积极减少Blink公共API的数量。

 

目录结构和依赖性

// third_party / blink /具有以下目录。有关这些目录的更详细定义,请参阅此文档

 

  • 平台/
    • Blink的较低级功能的集合,这些功能是从整体内核中剔除的。例如,几何和图形工具。
  • 核心/和模块/
    • 规范中定义的所有Web平台功能的实现。core /实现与DOM紧密结合的功能。模块/实现更多独立功能。例如webaudio,indexeddb。
  • 绑定/核心/和绑定/模块/
    • 从概念上讲,bindings / core /是core /的一部分,而bindings / modules /是modules /的一部分。大量使用V8 API的文件被放在bindings / {core,modules}中。
  • 控制器/
    • 一组使用core /和modules /的高级库。例如devtools前端。

 

依存关系按以下顺序流动:

 

  • 铬=>控制器/ =>模块/和绑定/模块/ =>核心/和绑定/核心/ =>平台/ =>底层基元,例如// base,// v8和// cc

 

Blink仔细维护暴露于// third_party / blink /的低级基元列表。

 

如果您想了解更多信息:

 

WTF

WTF是一个“特定于眨眼的基础”库,位于platform / wtf /。我们正在尝试尽可能多地统一Chromium和Blink之间的编码原语,因此WTF应该很小。需要此库是因为确实需要针对Blink的工作量和Oilpan(Blink GC)优化许多类型,容器和宏。如果类型是在WTF中定义的,则Blink必须使用WTF类型而不是// base或std库中定义的类型。最受欢迎的是矢量,哈希集,哈希图和字符串。眨眼应该使用WTF :: Vector,WTF :: HashSet,WTF :: HashMap,WTF :: String和WTF :: AtomicString而不是std :: vector,std :: * set,std :: * map和std :: string 。

 

如果您想了解更多信息:

 

内存管理

就Blink而言,您需要关心三个内存分配器:

 

 

您可以使用USING_FAST_MALLOC()在PartitionAlloc的堆上分配一个对象:

 

类SomeObject {

  USING_FAST_MALLOC(SomeObject);

  静态std :: unique_ptr <SomeObject> Create(){

    返回std :: make_unique <SomeObject>(); //分配在PartitionAlloc的堆上。

}

};

 

由PartitionAlloc分配的对象的生存期应由scoped_refptr <>或std :: unique_ptr <>管理。强烈建议不要手动管理生命周期。闪烁禁止手动删除

 

您可以使用GarbageCollected在Oilpan的堆上分配一个对象:

 

类SomeObject:公共GarbageCollected <SomeObject> {

  静态SomeObject * Create(){

    返回新的SomeObject; //分配在Oilpan的堆上。

  }

};

 

Oilpan分配的对象的生存期由垃圾收集自动管理。您必须使用特殊的指针(例如Member <>,Persistent <>)将对象保存在Oilpan的堆上。请参阅此API参考以熟悉有关Oilpan的编程限制。最重要的限制是不允许您在油锅对象的析构函数中触摸任何其他油锅对象(因为无法保证销毁顺序)。

 

如果您既不使用USING_FAST_MALLOC()也不使用GarbageCollected,则在系统malloc的堆上分配对象。在眨眼中强烈建议不要这样做。所有Blink对象应由PartitionAlloc或Oilpan分配,如下所示:

 

  • 默认情况下使用Oilpan。
  • 仅在以下情况下才使用PartitionAlloc:1)对象的生存期非常明确并且std :: unique_ptr <>或scoped_refptr <>足够,2)在Oilpan上分配对象会带来很多复杂性,或者3)在Oilpan上分配对象会导致给垃圾收集运行时带来了不必要的压力。

 

无论使用PartitionAlloc还是Oilpan,都必须非常小心,不要创建悬空的指针(注意:强烈建议不要使用原始指针)或内存泄漏。

 

如果您想了解更多信息:

 

任务调度

为了提高渲染引擎的响应速度,Blink中的任务应尽可能异步执行。不鼓励同步IPC / Mojo和任何其他可能花费几毫秒的操作(尽管某些操作是不可避免的,例如用户的JavaScript执行)。

 

呈现器进程中的所有任务都应使用正确的任务类型发布到Blink Scheduler,如下所示:

 

//使用kNetworking的任务类型将任务发布到框架的调度程序

frame-> GetTaskRunner(TaskType :: kNetworking)-> PostTask(…,WTF :: Bind(&Function));

 

Blink Scheduler维护多个任务队列,并巧妙地对任务进行优先级排序,以最大化用户感知的性能。重要的是要指定适当的任务类型,以使Blink Scheduler能够正确,智能地调度任务。

 

如果您想了解更多信息:

 

  • 如何发布任务:platform / scheduler / PostTask.md

页面,框架,文档,DOMWindow等

概念

页面,框架,文档,ExecutionContext和DOMWindow是以下概念:

 

  • 页面与选项卡的概念相对应(如果未启用下面说明的OOPIF)。每个渲染器进程可能包含多个选项卡。
  • 框架对应于框架(主框架或iframe)的概念。每个页面可以包含一个或多个以树状层次结构排列的框架。
  • DOMWindow对应于JavaScript中的窗口对象。每个框架都有一个DOMWindow。
  • Document对应于JavaScript中的window.document 对象。每个框架都有一个文档。
  • ExecutionContext是一个抽象文档(用于主线程)和WorkerGlobalScope(用于工作线程)的概念。

 

渲染过程:页面= 1:N

 

页:框架= 1:M.

 

框架:DOMWindow:文档(或ExecutionContext)= 1:1:1在任何时间点,但映射可能随时间而变化。例如,考虑以下代码:

 

iframe.contentWindow.location.href =“ https://example.com”;

 

在这种情况下,将为https://example.com创建一个新的DOMWindow和一个新的Document 。但是,可以重复使用该框架。

 

(注意:确切地说,在某些情况下会创建一个新的Document,但是DOMWindow和Frame会被重用。甚至还有一些更复杂的情况。)

 

如果您想了解更多信息:

 

  • 核心/框架/FrameLifecycle.md

进程外iframe(OOPIF)

站点隔离使事情变得更加安全,但更加复杂。🙂站点隔离的想法是为每个站点创建一个渲染器进程。(网站是页面的可注册域+ 1标签及其URL方案。例如,https://mail.example.comhttps://chat.example.com在同一网站中,但https:// noodles.comhttps://pumpkins.com都没有。)如果一个页面包含一个跨站点IFRAME,该页面可以由两个渲染过程托管。考虑以下页面:

 

<!– https://example.com –>

<身体>

<iframe src =” https://example2.com”> </ iframe>

</ body>

 

主框架和<iframe>可以由不同的渲染器进程托管。渲染器进程本地的帧由LocalFrame表示,而不是渲染器进程本地的帧由RemoteFrame表示。

 

从主框架的角度来看,主框架是LocalFrame,而<iframe>是RemoteFrame。从<iframe>的角度来看,主框架是RemoteFrame,而<iframe>是LocalFrame。

 

本地框架和远程框架(可能存在于不同的渲染器进程中)之间的通信是通过浏览器进程进行处理的。

 

如果您想了解更多信息:

 

分离的框架/文件

相框/文档可能处于分离状态。考虑以下情况:

 

doc = iframe.contentDocument;

iframe.remove(); //将iframe与DOM树分离。

doc.createElement(“ div”); //但是您仍然可以在分离的框架上运行脚本。

 

棘手的事实是,您仍然可以在分离的框架上运行脚本或DOM操作。由于框架已经分离,大多数DOM操作将失败并引发错误。不幸的是,分离框架上的行为在浏览器之间并不能真正实现互操作,在规范中也没有明确定义。基本上,人们期望JavaScript可以继续运行,但是大多数DOM操作应该会因某些适当的异常而失败,例如:

 

无效someDOMOperation(…){

  if(!script_state _-> ContextIsValid()){//框架已经分离

    …;//设置例外等

    返回;

}

}

 

这意味着在通常情况下,当框架分离时,Blink需要执行一系列清理操作。您可以通过从ContextLifecycleObserver继承来做到这一点,如下所示:

 

类SomeObject:公共GarbageCollected <SomeObject>,公共ContextLifecycleObserver {

  void ContextDestroyed()覆盖{

    //在此进行清理操作。

}

  〜SomeObject(){

    //在这里进行清理操作不是一个好主意,因为现在进行清理已经太迟了。此外,不允许析构函数接触Oilpan堆上的任何其他对象。

  }

};

Web IDL绑定

当JavaScript访问node.firstChild时将调用node.h 中的Node :: firstChild()。它是如何工作的?让我们看一下node.firstChild的工作方式。

 

首先,您需要根据规范定义一个IDL文件:

 

// node.idl

接口Node:EventTarget {

  […]只读属性Node?第一个孩子;

};

 

Web IDL的语法在Web IDL规范中定义[…] 称为IDL扩展属性。一些IDL扩展属性是在Web IDL规范中定义的,而另一些是特定于Blink的IDL扩展属性。除了特定于闪烁的IDL扩展属性外,IDL文件应以符合规范的方式编写(即,仅从规范中复制并粘贴)。

 

其次,您需要为Node定义一个C ++类,并为firstChild实现一个C ++ getter:

 

class EventTarget:public Sc​​riptWrappable {//所有暴露给JavaScript的类都必须从ScriptWrappable继承。

…;

};

 

类Node:public EventTarget {

  DEFINE_WRAPPERTYPEINFO(); //所有具有IDL文件的类都必须具有此宏。

  节点* firstChild()const {return first_child_; }

};

 

在通常情况下,就是这样。生成node.idl时,IDL编译器会自动为Node接口和Node.firstChild生成Blink-V8绑定。自动生成的绑定是在//src/out/{Debug,Release}/gen/third_party/blink/renderer/bindings/core/v8/v8_node.h中生成的。当JavaScript调用node.firstChild时,V8会调用v8_node.h中的V8Node :: firstChildAttributeGetterCallback(),然后会调用您在上面定义的Node :: firstChild()。

 

如果您想了解更多信息:

 

V8和闪烁

隔离,上下文,世界

当您编写涉及V8 API的代码时,了解隔离,上下文和世界的概念很重要。它们分别在代码库中由v8 :: Isolate,v8 :: Context和DOMWrapperWorld表示。

 

隔离对应于物理线程。隔离:闪烁中的物理线程= 1:1。主线程具有自己的隔离。辅助线程具有其自己的隔离。

 

上下文对应于全局对象(在使用框架的情况下,它是框架的窗口对象)。由于每个框架都有其自己的窗口对象,因此渲染器进程中存在多个上下文。调用V8 API时,必须确保您使用的是正确的上下文。否则,v8 :: Isolate :: GetCurrentContext()将返回错误的上下文,在最坏的情况下,它将最终导致对象泄漏并导致安全问题。

 

World是支持Chrome扩展程序的内容脚本的概念。世界与Web标准中的任何内容都不对应。内容脚本希望与网页共享DOM,但是出于安全原因,必须将内容脚本的JavaScript对象与网页的JavaScript堆隔离。(还必须将一个内容脚本的JavaScript堆与另一个内容脚本的JavaScript堆隔离。)为了实现隔离,主线程为网页创建了一个主世界,为每个内容脚本创建了一个隔离世界。主世界和孤立世界可以访问相同的C ++ DOM对象,但是它们的JavaScript对象是孤立的。通过为一个C ++ DOM对象创建多个V8包装器来实现这种隔离。也就是说,每个世界一个V8包装器。

 

上下文,世界和框架之间有什么关系?

 

想象一下,在主线程上有N个世界(一个主世界+(N – 1)个孤立世界)。然后,一个框架应具有N个窗口对象,每个窗口对象用于一个世界。上下文是与窗口对象相对应的概念。这意味着,当我们有M个框架和N个世界时,我们有M * N个上下文(但是这些上下文是惰性创建的)。

 

如果是工人,则只有一个世界和一个全局对象。因此,只有一个上下文。

 

同样,当您使用V8 API时,应该非常小心使用正确的上下文。否则,您最终将在孤立的世界之间泄漏JavaScript对象并造成安全灾难(例如,来自A.com的扩展程序可以操纵来自B.com的扩展程序)。

 

如果您想了解更多信息:

 

V8 API

//v8/include/v8.h中定义了许多V8 API 。由于V8 API是低级的并且难以正确使用,因此platform / bindings /提供了一堆包装V8 API的帮助程序类。您应该考虑尽可能使用助手类。如果您的代码必须大量使用V8 API,则应将文件放在bindings / {core,modules}中。

 

V8使用句柄指向V8对象。最常见的句柄是v8 :: Local <>,用于从计算机堆栈指向V8对象。在计算机堆栈上分配v8 :: HandleScope之后,必须使用v8 :: Local <>。v8 :: Local <>不应在机器堆栈之外使用:

 

void function(){

  v8 :: HandleScope范围;

  v8 :: Local <v8 :: Object> object =…; // 这是对的。

}

 

类SomeObject:公共GarbageCollected <SomeObject> {

  v8 :: Local <v8 :: Object> object_; //这是错误的。

};

 

如果要从计算机堆栈外部指向V8对象,则需要使用包装器跟踪。但是,您必须非常小心,不要用它创建参考循环。通常,V8 API很难使用。如果您不确定自己在做什么,请询问blink-review-bindings @

 

如果您想了解更多信息:

 

  • 如何使用V8 API和帮助程序类:platform / bindings / HowToUseV8FromBlink.md

V8包装器

每个C ++ DOM对象(例如Node)都有其对应的V8包装器。确切地说,每个C ++ DOM对象每个世界都有其对应的V8包装器。

 

V8包装器对其相应的C ++ DOM对象有很强的引用。但是,C ++ DOM对象仅对V8包装程序具有弱引用。因此,如果您想让V8包装器存活一段时间,则必须明确地做到这一点。否则,将过早收集V8包装器,并且V8包装器上的JS属性将丢失。

 

div = document.getElementbyId(“ div”);

child = div.firstChild;

child.foo =“酒吧”;

child = null;

GC(); //如果不执行任何操作,则| firstChild |的V8包装器 由GC收集。

assert(div.firstChild.foo ===“ bar”); // …这将失败。

 

如果我们什么都不做,GC会收集child ,因此child.foo 会丢失。为了使div.firstChild 的V8包装器保持活动状态,我们必须添加一种机制,“ 只要div 所属的DOM树可以从V8到达,则使div.firstChild 的V8包装器保持活动状态”。

 

有两种方法可以使V8包装器保持活动状态:ActiveScriptWrappable包装器跟踪

 

如果您想了解更多信息:

 

渲染管线

从将HTML文件发送到Blink到在屏幕上显示像素还有很长的一段路要走。渲染管道的结构如下。

 

阅读这个出色的资料,以了解渲染管线的每个阶段的功能。(我认为我能写出比甲板更好的解释🙂

 

如果您想了解更多信息,请联系:GC收集。

 

assert(div.firstChild.foo ===“ bar”); // …这将失败。

 

如果我们什么都不做,GC会收集child,因此child.foo会丢失。为了使div.firstChild的V8包装器保持活动状态,我们必须添加一种机制,“只要div所属的DOM树可以从V8到达,则使div.firstChild的V8包装器保持活动状态”。

 

有两种方法可以使V8包装器保持活动状态:ActiveScriptWrappable和包装器跟踪。

 

如果您想了解更多信息:

 

如何管理V8包装器的生命周期:bindings / core / v8 / V8Wrapper.md

 

如何使用包装程序跟踪:platform / bindings / TraceWrapperReference.md

 

渲染管线

从将HTML文件发送到Blink到在屏幕上显示像素还有很长的一段路要走。渲染管道的结构如下。

Chrome如何显示网页

概念应用层

(此插图的原始Google文档为http://goo.gl/MsEJX,任何@ chromium.org均可开放对其进行编辑)
每个框代表一个概念性的应用程序层。任何层都不应该了解或依赖任何更高层。
  • WebKit:在Safari,Chromium和所有其他基于WebKit的浏览器之间共享的渲染引擎。该港口是WebKit的一部分,与平台相关的系统集成服务,如资源加载和图形。
  • 胶水:将WebKit类型转换为Chromium类型。这是我们的“ WebKit嵌入层”。它是两个浏览器Chromium和test_shell(允许我们测试WebKit)的基础。
  • 渲染器/渲染主机:这是Chromium的“多进程嵌入层”。它跨流程边界代理通知和命令。
  • WebContents:一个可重用的组件,它是Content模块的主要类。它很容易嵌入,以允许将HTML的多进程呈现到视图中。有关更多信息,请参见内容模块页面
  • 浏览器: 代表浏览器窗口,其中包含多个WebContent。
  • 选项卡助手:可以附加到WebContents的单个对象(通过WebContentsUserData mixin)。浏览器将其中的各种附加到它所拥有的WebContentses(一个用于收藏夹图标,一个用于信息栏等)。

WebKit

我们使用WebKit开源项目来布局网页。此代码从Apple中提取,并存储在/ third_party / WebKit目录中。WebKit主要由代表核心布局功能的“ WebCore”和运行JavaScript的“ JavaScriptCore”组成。我们仅出于测试目的运行JavaScriptCore,通常我们将其替换为高性能的V8 JavaScript引擎。我们实际上并没有使用Apple称为“ WebKit”的层,它是WebCore和OS X应用程序(例如Safari)之间的嵌入API。为了方便起见,我们通常将Apple的代码统称为“ WebKit”。

WebKit端口

在最低级别,我们有WebKit“端口”。这是我们所需的特定于平台的功能的实现,该功能可与独立于平台的WebCore代码对接。这些文件位于WebKit树中,通常位于目录中或作为带有铬后缀的文件。我们的许多端口实际上并不是特定于操作系统的:您可以将其视为WebCore的“ Chromium端口”。对于每个平台,某些部分(如字体渲染)必须以不同的方式处理。

  • 网络流量是由我们的多进程资源加载系统处理的,而不是直接从渲染过程传递给OS的。
  • 图形使用为Android开发的Skia图形库。这是一个跨平台的图形库,可处理除文本以外的所有图像和图形基元。Skia位于t hird_party / skia中。图形操作的主要入口点是/webkit/port/platform/graphics/GraphicsContextSkia.cpp。它使用同一目录以及/ base / gfx中的许多其他文件。

WebKit胶

与第三方WebKit代码相比,Chromium应用程序使用不同的类型,编码样式和代码布局。WebKit“胶水”为使用Google编码约定和类型的WebKit提供了更方便的嵌入API(例如,我们使用std :: string代替WebCore :: StringGURL代替KURL)。粘合代码位于/ webkit / glue中。胶合对象的名称通常类似于WebKit对象,但开头带有“ Web”。例如,WebCore :: Frame变为WebFrame

WebKit的“胶水”层将其余的Chromium代码库与WebCore数据类型隔离开来,以帮助最小化WebCore更改对Chromium代码库的影响。因此,Chromium永远不会直接使用WebCore数据类型。当Chromium需要戳入某些WebCore对象时,API会被添加到WebKit的“胶水”中。

“测试外壳”应用程序是一个准系统的Web浏览器,用于测试我们的WebKit端口和粘合代码。它使用与Chromium相同的粘合接口与WebKit进行通信。它为开发人员提供了一种更简单的方法来测试新代码,而无需具有许多复杂的浏览器功能,线程和进程。此应用程序还用于运行自动化的WebKit测试。但是,“测试外壳”的缺点是,它不像Chromium那样以多进程方式使用WebKit。内容模块嵌入在称为“内容外壳”的应用程序中,该应用程序将很快运行测试。

渲染过程

Chromium的渲染过程使用胶水接口嵌入了我们的WebKit端口。它不包含太多代码:它的工作主要是作为浏览器IPC通道的呈现器端。

渲染器中最重要的类是RenderView,它位于/content/renderer/render_view_impl.cc中。该对象表示一个网页。它处理往返于浏览器进程的所有与导航有关的命令。它源自提供绘画和输入事件处理的RenderWidget。所述的RenderView经由全球浏览器进程通信(每呈现进程)RenderProcess对象。

FAQ:RenderWidget和RenderView有什么区别?RenderWidget通过在称为WebWidgetDelegate的粘合层中实现抽象接口,映射到一个WebCore :: Widget对象。基本上,这是屏幕上的一个窗口,用于接收输入事件并绘制到该窗口中。甲的RenderView从继承RenderWidget并且是选项卡或弹出窗口的内容。除了小部件的绘制和输入事件外,它还处理导航命令。仅在一种情况下存在RenderWidget而没有RenderView ,这是网页上的选择框。这些是带有向下箭头的框,这些框会弹出一个选项列表。选择框必须使用本机窗口渲染,以便它们可以显示在其他所有框的上方,并在必要时弹出框。这些窗口需要绘制并接收输入,但是没有单独的“网页”(RenderView)。

渲染器中的线程

每个渲染器都有两个线程(有关图表,请参见多进程体系结构页面;有关如何编程,请参见Chromium中的线程)。渲染线程是主要对象(例如RenderView)所在的位置并运行所有WebKit代码。当它与浏览器通信时,消息首先发送到主线程,然后主线程将消息分派给浏览器进程。除其他外,这使我们能够将消息从渲染器同步发送到浏览器。发生这种情况的原因是少数操作需要浏览器的结果才能继续。一个示例是在JavaScript请求时获取页面的Cookie。渲染器线程将阻塞,并且主线程将对所有收到的消息进行排队,直到找到正确的响应为止。随后将任何同时接收到的消息发布到渲染器线程以进行正常处理。

浏览器过程

 

低级浏览器过程对象

与渲染过程的所有IPC通信都是在浏览器的I / O线程上完成的。该线程还处理所有网络通信,以防止其干扰用户界面。

在主线程(运行用户界面的地方)上初始化RenderProcessHost时,它将创建新的渲染器进程和带有指向渲染器的命名管道的ChannelProxy IPC对象。该对象在浏览器的I / O线程上运行,侦听到渲染器的命名管道,并自动将所有消息转发回UI线程上的RenderProcessHost。甲ResourceMessageFilter将被安装在该通道中,这将筛选出可直接在I / O线程上处理诸如网络请求的某些消息。此过滤发生在ResourceMessageFilter :: OnMessageReceived中

所述RenderProcessHost在UI线程上是负责分派所有视图专用消息到适当的RenderViewHost(它处理非观看专用消息本身的有限的数目)。这种调度发生在RenderProcessHost :: OnMessageReceived中

高级浏览器过程对象

特定于视图的消息进入RenderViewHost :: OnMessageReceived。大多数消息都在这里处理,其余消息转发到RenderWidgetHost基类。这两个对象映射到渲染器中的RenderViewRenderWidget(有关这些含义,请参见上面的“ Render Process”)。每个平台都有一个视图类(RenderWidgetHostView [Aura | Gtk | Mac | Win]),以实现与本机视图系统的集成。

RenderView / Widget上方是WebContents对象,大多数消息实际上最终都作为对该对象的函数调用而结束。一个WebContents代表网页的内容。它是内容模块中的顶级对象,并负责以矩形视图显示网页。有关更多信息,请参见内容模块页面

所述WebContents对象被包含在TabContentsWrapper。那是chrome /并负责制表符。

说明性例子

围绕Chromium源代码 涵盖了导航和启动的其他示例。

“设置游标”消息的寿命

设置光标是从渲染器发送到浏览器的典型消息的示例。在渲染器中,将发生以下情况。

  • 设置光标消息是由WebKit在内部生成的,通常是响应输入事件而生成的。设置光标消息将从content / renderer / render_widget.cc中的RenderWidget :: SetCursor开始
  • 它将调用RenderWidget :: Send来分派消息。RenderView也使用此方法将消息发送到浏览器。它将调用RenderThread :: Send 
  • 这将调用IPC :: SyncChannel,它将在内部将消息代理到渲染器的主线程,并将其发布到命名管道以发送到浏览器。

然后浏览器控制:

  • RenderProcessHost中的IPC :: ChannelProxy在浏览器的I / O线程上接收所有消息。它首先通过ResourceMessageFilter发送它们,后者直接在I / O线程上调度网络请求和相关消息。由于我们的消息没有被过滤掉,因此它将继续进入浏览器的UI线程(IPC :: ChannelProxy在内部执行此操作)。
  • RenderProcessHost :: OnMessageReceived内容/浏览器/ renderer_host / render_process_host_impl.cc获取相应的渲染过程的所有意见的消息。它直接处理几种类型的消息,其余的则转发到与发送消息的源RenderView对应的适当的RenderViewHost
  • 该消息到达RenderViewHost :: OnMessageReceived内容/浏览器/ renderer_host / render_view_host_impl.cc。很多消息都在这里处理,但我们是不是因为它是从发送的消息RenderWidget和处理由RenderWidgetHost
  • RenderViewHost中所有未处理的消息都将自动转发到RenderWidgetHost,包括我们设置的光标消息。
  • 内容/浏览器/renderer_host/render_view_host_impl.cc中的消息映射  最终在RenderWidgetHost :: OnMsgSetCursor中接收到消息,并调用适当的UI函数来设置鼠标光标。

“鼠标单击”消息的寿命

发送鼠标单击是从浏览器到渲染器的典型消息示例。

  • Windows消息由RenderWidgetHostViewWin :: OnMouseEvent在浏览器的UI线程上接收,然后在同一类中调用ForwardMouseEventToRenderer
  • 转发器功能将输入事件打包到一个跨平台的WebMouseEvent中,并最终将其发送到与之关联的RenderWidgetHost
  • RenderWidgetHost :: ForwardInputEvent创建一条IPC消息ViewMsg_HandleInputEvent,将WebInputEvent序列化为其,然后调用RenderWidgetHost :: Send
  • 这只是转发给拥有的RenderProcessHost :: Send函数,后者将消息提供给IPC :: ChannelProxy
  • 在内部,IPC :: ChannelProxy将消息代理到浏览器的I / O线程,并将其写入相应渲染器的命名管道。

请注意,WebContents中还会创建许多其他类型的消息,尤其是导航消息。它们遵循从WebContentsRenderViewHost的相似路径。

然后渲染器控制:

  •  渲染器主线程上的IPC :: Channel读取浏览器发送的消息,而IPC :: ChannelProxy代理到渲染器线程。
  • RenderView :: OnMessageReceived获取消息。许多类型的消息直接在这里处理。由于单击消息不是,因此它(与所有其他未处理的消息一起)进入RenderWidget :: OnMessageReceived  ,后者又将其转发到  RenderWidget :: OnHandleInputEvent
  • 将输入事件提供给  WebWidgetImpl :: HandleInputEvent,在此将其转换为WebKit PlatformMouseEvent类,并提供给WebKit 中的WebCore :: Widget类。