Chromium加载网页的过程,需要Browser进程和Render进程协作完成。加载网页的过程由Browser进程发起,向服务器请求网页内容的过程也是由Browser进程完成。Render进程负责对下载回来的网页内容进行解析,解析之后得到一个DOM Tree。有了这个DOM Tree之后,Render进程就可以对网页进行渲染了。本文接下来就对上述过程涉及到的重要概念进行简要介绍以及制定学习计划。
《Android系统源代码情景分析》一书正在进击的程序员网(http://0xcc0xcd.com)中连载,点击进入!
第一个涉及到的重要概念是Chromium的模块划分及其层次关系,如图1所示:
图1 Chromium模块划分及其层次关系
这个图来自官方文档:How Chromium Displays Web Pages。从下往上看:
1. WebKit:网页渲染引擎层,定义在命令空间WebCore中。Port部分用来集成平台相关服务,例如资源加载和绘图服务。WebKit是一个平台无关的网页渲染引擎,但是用在具体的平台上时,需要由平台提供一些平台相关的实现,才能让WebKit跑起来。
2. WebKit glue:WebKit嵌入层,用来将WebKit类型转化为Chromium类型,定义在命令空间blink中。Chromium不直接访问WebKit接口,而是通过WebKit glue接口间接访问。WebKit glue的对象命名有一个特点,均是以Web为前缀。
3. Renderer/Renderer host:多进程嵌入层,定义在命令空间content中。其中,Renderer运行在Render进程中,Renderer host运行在Browser进程中。
4. WebContents:允许将一个HTML网页以多进程方式渲染到一个区域中,定义在命令空间content中。
5. Browser:代表一个浏览器窗口,它可以包含多个WebContents。
6. Tab Helpers:附加在WebContents上,用来增加WebContents的功能,例如显示InfoBar。
我们可以将第1层和第2层归结为WebKit层,第3层和第4层归结为Content层,第5层和第6层归结为浏览器层。如果以进程为边界,Tab Helpers、Browser、WebContents和Renderer host运行在Browser进程中,Renderer、WebKit glue和WebKit运行在Render进程中。
Content层是Chromium的核心模块,它实现了Chromium的多进程架构。Content层主要向外提供的接口是WebContents,浏览器层通过这个WebContents接口就可以将一个HTML网页渲染在一个区域上。例如,Chrome就是通过Content层提供的WebContents接口实现一个浏览器的。同样我们也可以通过Content层提供的WebContents接口实现一个与Chrome类似的浏览器,甚至我们也可以通过Content层提供的WebContents接口实现一个嵌入在应用程序的浏览器控件,例如Android 4.4的WebView。
在Content层中,一个用来渲染网页的区域称为RenderView。一个RenderView也称为一个RenderWidget。RenderView与RenderWidget的区别是,前者是描述的是一个用来显示网页内容的控件,后者描述的是一个可以接收用户输入的控件,但是它不一定是用来显示网页内容的。例如,点击网页上的选择框弹出来的窗口,是一个RenderWidget,它里面显示的内容与网页无关。
我们可以将RenderView和RenderWidget看作是一个接口。Browser进程和Render进程都需要实现这个接口。其中,Browser进程分别实现RenderView和RenderWidget接口的两个类是RenderViewHostImpl和RenderWidgetHostImpl,Render进程分别实现RenderView和RenderWidget接口的两个类是RenderViewImpl和RenderWidgetImpl。Browser进程的每一个RenderViewHostImpl对象和每一个RenderWidgetHostImpl对象在Render进程中都分别对应有一个RenderViewImpl对象和一个RenderWidgetImpl。RenderViewHostImpl对象与RenderViewImpl对象、RenderWidgetHostImpl对象与RenderWidgetImpl对象可以通过Browser进程与Render进程建立的IPC通道进行通信。
WebKit层的WebView和WebWidget相当于Content层的RenderView和RenderWidget。我们注意到,WebKit层还有一个称为WebFrame的对象。事实上,Content层也有一个类似的对象,称为RenderFrame。WebFrame和RenderFrame都是用来描述网页的。既然已经有了RenderView和RenderWidget,为什么还需要WebFrame和RenderFrame呢?这与Chromium的Out-of-Process iframes(OOPIFs)项目有关。关于Chromium的Out-of-Process iframes(OOPIFs)项目的详细信息,可以参考官方文档:Out-of-Process iframes (OOPIFs)。
当网页使用window.open在另外一个Tab打开一个新的网页,或者通过iframe标签嵌入另外一个网页时,源网页和目标网页有可能在同一个Render进程中,也有可能在不同的Render进程中,这取决于它们是否来自同一个站点。在HTML5规范中,源网页和目标网页组成了一个浏览上下文单元(Browsing Context)。当源网页和目标网页不在同一个Render进程时,源网页如何通过HTML5规范中的window.postMessage接口发消息给目标网页呢?如图2所示:
图2 HTML5的window.postMessage实现
在图2中,网页A通过window.open打开了网页B,它们分别在两个不同的Tab中,这两个Tab又是在不同的Render进程中。在Browser进程中,网页A和网页B分别对应有一个WebContents对象。也就是Browser进程会为每一个网页创建一个WebContents对象,如前面的图1所示。为了让网页A能够通过window.postMessage接口给网页B发送消息,负责渲染网页A的Render进程会为网页B创建一个代理对象,这个代理对象知道如何发送消息给网页B(通过Chromium的IPC消息发送、接收和分发机制分析一文分析的Routing机制)。同样,负责渲染网页B的Render进程也会为网页A创建一个代理对象,这个代理对象负责接收从网页A发送过来的消息,并且分发给网页B处理。注意,代理对象在图2中均通过虚线框表示。通过这种代理对象方式,就实现了不在同一个Render进程中的两个网页的相互通信。
Chromium是如何实现上述代理对象的呢?我们通过图3所示的例子进行说明,如下所示:
图3 在同一个Browsing Context中的网页
网页A在一个Tab显示,并且它通过iframe标签包含了网页B和网页C。网页C通过window.open在另外一个Tab中打开了另外一个网页C实例。新打开的网页C通过iframe标签包含了网页D,网页D又通过iframe标签包含了网页A的另外一个实例。
这时候Browser进程会分别为图3的两个Tab创建一个WebContents对象,如图4所示:
图4 RenderFrameHost/RenderFrameProxyHost
每一个WebContents对象都关联有一个Frame Tree。Frame Tree中的每一个Node代表一个网页。第一个Tab的Frame Tree包含有三个Node,分别代表网页A、B和C。第二个Tab的Frame Tree也包含有三个Node,分别代表网页C、D和A。
代表网页B的Node关联有一个RenderFrameHost对象和三个RenderFrameProxyHost对象,其中,RenderFrameHost对象描述的是网页B本身,另外三个RenderFrameProxyHosts对象描述的是网页A、C和D。也就是说,在Browser进程中,代理对象是通过RenderFrameProxyHost类描述的。
图3所示的网页A、B、C和D分别在不同的Render进程中渲染,如图5所示:
图5 RenderFrame/RenderFrameProxy
在负责渲染网页A的Render进程中,有两个RenderFrame对象,分别代表图3所示的两个网页A实例。负责渲染网页A的Render进程还包含有四个RenderFrameProxy对象,分别代表网页B、C和D。在负责渲染网页B、C和D的Render进程中,也有类似的RenderFrame对象和RenderFrameProxy对象。其中,RenderFrameProxy对象就是前面描述的代理对象。
每一个RenderFrame对象和RenderFrameProxy对象在图1所示的WebKit glue层中,分别对应有一个WebLocalFrame对象和WebRemoteFrame对象,如图6所示:
图6 WebLocalFrame/WebRemoteFrame
注意,WebLocalFrame类和WebRemoteFrame类都是从图1的所示的WebFrame类继承下来的,它们都是属于WebKit glue层的。前面我们提到,WebKit glue层是用来封装WebKit层的,WebLocalFrame对象和WebRemoteFrame对象封装的便是WebKit层中的LocalFrame和RemoteFrame对象。Chromium将WebKit glue层和WebKit层统称为Blink模块。这意味着在Blink模块中,前面描述的代理对象是通过WebRemoteFrame和RemoteFrame描述的。
从前面的分析我们就可以看到,在Chromium中,为什么一个网页既要使用RenderView、RenderWidget,又要使用RenderFrame、WebFrame来描述,它们的作用是不一样的,总结来说,就是:
RenderView描述的是一个用来显示网页内容的RenderWidget。
RenderWidget描述的是一个UI控件。
3. RenderFrame用来建立网页之间的消息通道。
在WebKit层中,每一个LocalFrame对象都关联有一个LocalDOMWindow对象,这个LocalDOMWindow对象又关联有一个Document对象。这个Document对象描述的就是一个要在当前Render进程进行加载和渲染的网页。
在WebKit层中,每一个RemoteFrame对象都关联有一个RemoteDOMWindow对象。但是由于RemoteFrame对象描述的是一个代理对象,因此它关联的RemoteDOMWindow对象是不关联有Document对象的,只是作为一个Place Holder存在当前Render进程中。
LocalDOMWindow对象和Document对象描述的就是HTML规范的DOM Window和Document,它们是在网页的加载和解析过程中创建的。其中,Document对象包含有一个DOM Tree,如图7所示:
图7 DOM Tree和Layer Tree
这个图来自官方文档:GPU Accelerated Compositing in Chrome。DOM Tree中的每一个Node对应的就是网页中的每一个HTML标签。每一个HTML标签都对应有一个Render Object,这些Render Object又形成一个Render Object Tree。Render Object知道如何绘制其描述的HTML标签。
具有相同坐标空间的Render Object都绘制在同一个Render Layer中,这些Render Layer又形成了一个Render Layer Tree,这意味着并不是所有的Render Object都有自己的Render Layer。Render Layer Tree的根节点一定对应有一个Render Layer,其余的子节点如果不需要使用单独的Render Layer,那么就会与父节点使用相同的Render Layer。因此,Render Object与Render Layer是多对一的关系。典型地,设置有透明属性、CSS Filter的Render Object有单独的Render Layer,标签canvas和video对应的Render Object也有单独的Render Layer。Layer是图形渲染引擎普遍使用的一个技术,是为了方便绘制一组具有某些相同属性的图形而生的,这样就不会为每一个图形都单独执行相同的绘图操作。
在图形渲染引擎中,Layer会对应有一个Backing Surface。在软件方式渲染中,Backing Surface就是一个内存Buffer。在硬件方式渲染中,Backing Surface就是一个FBO。为了减少Buffer和FBO开销。WebKit不会为每一个Render Layer都分配一个Backing Surface,而是让某些Render Layer共用同一个Backing Surface。这意味着Render Layer与Backing Surface是多对一的关系。在WebKit中,具有Backing Surface的Layer称为Graphics Layer,这些Graphics Layer又形成了一个Graphics Layer Tree。每一个Graphics Layer都关联有一个Graphics Context。这个Graphics Context是由Chromium提供给WebKit的,它知道如何绘制Render Layer的内容。Graphics Context绘制出来的内容最后会通过合成器(Compositor)渲染在屏幕上。
上面描述的Render Object Tree、Render Layer Tree和Graphics Layer都是与网页渲染相关的,是我们下一个系列的文章要分析的内容。在这个系列的文章中,我们主要是分析DOM Tree以及前面描述的Frame Tree。
Frame Tree由Browser进程创建,DOM Tree由Render进程创建。Frame Tree是在网页内容下载回来前就创建出来的,并且在后面网页的解析和导航时增加或者移除子节点。DOM Tree是在网页内容下载回来后进行创建的,并且是根据网页的内容进行创建的。当一个网页的DOM Tree创建出来之后,它的加载过程就完成了。
注意,网页内容下载是由Browser进程执行的。Browser进程再将下载回来的网页通过共享内存交给Render进程处理。为什么不直接由Render进程下载呢?这是为了安全起见,Render进程按照最小权限原则创建,它不具有网络访问权限,因此就不能从服务器上下载网页内容回来。
为了更好地理解网页加载过程,以及这个过程中涉及到的各种对象,接下来我们将按照以下三个情景分析网页的加载过程:
1. Frame Tree的创建过程;
2. 网页下载过程;
3. DOM Tree的创建过程;
将网页抽象为Graphics Layer Tree之后,WebKit就可以将网页元素绘制在对应的Graphics Layer 之上了。最后,Graphics Layer又会由WebKit的使用者,即Chromium,进行渲染,也就是最终显示在屏幕上。网页渲染是我们下一个系列文章的关注点,同时也是浏览器的核心所在,因为评价一个浏览器是否流畅就取决于它渲染网页的速度够不够快。因此敬请关注这个系列的文章!更多的信息也可以关注老罗的新浪微薄:http://weibo.com/shengyangluo。
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。