Chromium设计原则总结

文档的思路从需求决定设计开始展开Chromium主要设计特点。从来没有复杂的设计,它们都可以转换为简单的描述。期望能从学习中解开Chromium设计要点。

(文章还在完善中......)

需求的分类

Chormium将页面浏览类的应用需求分为两类(参考文中第一段说明: Content Module):
  .Web Platform Features
     a. 多进程下解析、渲染页面的能力。
     b. HTML/HTML5/CSS3
  .Application Features (对应于Chrome,即为Chrome Features)
    a. Extensions
    b. Autofill
    c. Pre-render
    d. Safe-Browsering
    e. Translate

Chromium的架构分工

从Chromium项目来看,负责提供Web Platform Features的Content是其核心,在其上可以建构出一个完整的浏览器应用。上层的调用者被称为Embedder, 是一个应用层,它提供了Application Features。不同的应用,针对各自不同的用户场景,会有不同的需求。除了典型的浏览器,还有其它应用内置的页面浏览功能,如帮助,预览,甚至是游戏等。它们都会有不同的应用类需求(Application Features)。

下面展现了Chromium项目几个典型Embedder,前三个都是Google的产品。 

Chromium架构的要点

Chromium架构特征除了多进程外,最明显的就是解决依赖问题,不断的发展高内聚、低耦合的层次和组件,并且使用DEPS进行保障。
以下概括Chromium架构的要点:

1. 层次化设计

目前层次化的设计是演进出来,并非一步到位。主要包括了两个阶段:
   i. 第一阶段, 为了最大化的兼容WebKit, 在Chormium自有的业务逻辑与WebKit之间引入一个Glue层,用来隔离WebKit与Chromium自己实现的业务,比如多进程架构。后面改WebKit为Blink,独立演进后,Glue层又改名为Blink Public API。
          
  ii. 第二阶段,当Chromium的业务逻辑越来越多后,为了避免引入不必要的依赖,破坏原本的设计,另外还要为第三方应用提供页面浏览的功能,Chromium将需求分为两类,并将负责Web Platform Features的功能抽离出来成为Content层。(参考Content Module)
          
  下面就是目前Chrome完整的层次架构:
          

2. 多进程架构

多进程架构是由Content层实现的,它内部就会成为两个进程交互的界面:
          
  RenderWidgetHost/RenderWidget就是分处两个进程(Browser & Renderer)代表,他们之间就是通过IPC连接。
  子进程都由Browser进程创建出来,相互间以IPC&Shared memory的方式进行交互。
     

3. 组件化设计

组件化在四处表现最为明显:
     a. Extension

b. Browser Components
      它的目标是持续地对Chrome层级的代码(即Chrome Features)进行组件化,其中提取出content层就是它的一项成果。
     c. Layered Component (组件化中的模块化)
     算是Browser Components中的一种特别类型。这是迫于iOS限制使用第三方的浏览器内核,Chromium为了让Chrome Features使用的各种组件可以兼容iOS, 避免那部分功能的重复开发,从而引入了Layered Component的模式。其基本的思路就是将Component分为不依赖于Content层的Core (content free), 和负责与Content或者iOS下UIWebView交互的Driver。详情请参考: Layered Components Design Document。

      d. Blink Componentization 
         为了优化其内部的依赖关系,不断提炼功能.... 详见: Core/Module Componentization.
 但还不止于此,下步配合Blink完全合并到Chromium,其依赖关系还会再进一步变化。详见Blink componentization after Chromium-Blink repository merge

4. Blink向着微内核发展

以下为Chromium的描述:
If core has too many code and too complex dependencies, it is very difficult to understand and update (including maintaining existing features, fixing bugs, adding new features and so on) core.


   Blink的目标不断向着微内核的方向不断内聚,观察到的两个比较大的变化是: 
     . 借助Blink Platform API,抽离H5特性的实现。
     . 借助Slimming Paint,将渲染中的合成事务进一步集中到Content的Chromium Compositor (cc)上处理。
  这样Blink负责的都是核心的逻辑控制,排版,输出一些中间结果,再与其它模块协作做进一步的处理。

Chromium Android WebView架构的要点

层次上的差异

基于Content层的核心功能,提供一个替代Android之前使用的WebKit WebView,就是所谓的Chromium Android WebView, 简称CAW。
如下图所示, AOSP WebView是属于Android代码中的一部分,而Chromium Android WebView则属于Chromium项目。

从下至下:
android.webkit.WebView 仍然是基于WebView定义的实现。
WebView Glue是将WebView的实现桥接到Chromium Android WebView之上。这些都是Java的实现。
Chromium Android WebView提供了对Content的封装,兼有了一些Embedder的行为。
Android WebView还集成了部分Browser Components, 比如AutoFill, 甚至是PDF Exporter.

进程及渲染架构上的差异

Chromium Android WebView目标是向外提供一个WebView的能力,符合Android View的标准实现。这些也限制了它只能使用单进程架构,并且对渲染架构上做了变化。

GPU进程变为InProcGpuThread, 而Renderer进程则变为InProcRendererThread. (InProc -> In Process, 表示单进程.)

可见GPU上的变更最为明显,Chromium专为单进程架构做了两个核心的变更:

Compositor

*另外Compositor Main Thread与Impl Thread的交互中引入了SingleThreadProxy,也是为配合这个变更.

GPU

设计上的决策要点

目的是降低开发成本、提高生产力,包括:
  a. 开发者对设计和代码的理解要清晰。
  b. 降低变更的代价, 更好地支持功能演进及多团队合作。
  c. 降低犯错的可能性。
  d. 加快编译。

设计上的要点

1. 高内聚,低耦合。简化依赖,同时避免错误的依赖

Blink Componentization是典型的代表. 首先不要出现环形依赖(cyclic dependencies),然后再简化依赖关系。
  Chromium特别为此引入了DEPS, 帮助团队进行管理。

2. 避免接口的膨胀

Bloating! Chromium反复强调保持精简的接口,不要轻易的去增加接口, 多使用Chromium提供的扩展机制。详情见:
如何扩展Chromium的各层接口

3. 传递必要的数据

参照Law of Demeter,也是有利于简化依赖关系,降低耦合。所谓LoD, 就是只和必要的类做必要的交互,这样可以减少相互依赖的类,以及它们对外提供的接口。

4. 不要让一个类做太多事(SRP)

也不要让一个接口函数做太多事情。

5. 明确功能,避免曲解

一个类、一个模块、一个层次的功能职责都必须是要明确的,避免二义性。这是一个设计问题,也是一个管理问题。

6. 中间层  何时需要Wrapper

  “任何一个计算机问题都可以引入一个中间层来解决。”
中间层应用很广,Bridge, Wrapper, Adaptter, Glue, Proxy, COM+都在此列。但增加一层的成本也是有的,并不是所有的场景都要增加一层来解决。比如Chromium在Layered Compontents的设计选用的适配方式是增加交互的Driver, 而没有让Content API去实现一个Wrapper进行兼容处理,可能性是有的,但现在不会做。(详见:http://www.chromium.org/developers/design-documents/layered-components-design  FAQ:Will there be a wrapper API around the content API and the iOS API?)

这里有一个增加层的决策问题。层的架构设计分离不同的业务实现,降低相互间的依赖,也有利于团队对架构的理解,从而避免一些错误实现。但层的缺点是加长了执行路径,甚至可能出现不必要的数据转换。比如OSI为网络架构定义了7层协议,而真正广泛应用却是4层结构。
或许引入中间层可以解决任何问题,但代价有时是很高的。详细参考关于层的反模式讨论

7. 面向接口

Content API就是最好的例子。为了封装内部的变化,将上层开发者的负担降低,增加接口层进行隔离。这也是中间层的一种应用。

8. 策略与能力的分离

对于Content而言,blink提供的是能力, 完成核心的业务逻辑,是一个真正的引擎。而Content则负责为其提供上下文环境(提供Blink需要的依赖的扩展能力),并进行业务决策,即做什么。而Content又是Embedder的核心,对外提供HTML页面呈现和GPU渲染的能力,Embedder则负责基于这种能力构建本身的应用。
 如同下图这样一层层包裹,里面的模块向上提供能力,上面的模块驱动内部的模块做事。
      

9. 平衡维护成本

推荐简洁有效的方案。

持续重构

Chromium无论在Blink Componentization, Layered component cookbook, 或者Warden Project,都在体现持续重构的思想。
这是一个开发问题,也是一个管理问题。

当新功能依赖于一个功能时,或者一个功能在累积Bug时,都是重构的好时机。比如Chromium了解到Blink-Chromium合并代码仓库的规划后,已经开始规划重构Content-Blink的接口层设计.详见Blink componentization after Chromium-Blink repository merge

转载请注明出处: http://blog.csdn.net/horkychen

参考

Blink componentization after the Chromium-Blink repository merge
  Browser Components Design Document
  Layered Components Cookbook

时间: 2024-10-26 16:38:54

Chromium设计原则总结的相关文章

Java程序员应该了解的10个面向对象设计原则

面向对象设计原则: 是OOPS(Object-Oriented Programming System,面向对象的程序设计系统)编程的核心,但大多数Java程序员追逐像Singleton.Decorator.Observer这样的设计模式,而不重视面向对象的分析和设计.甚至还有经验丰富的Java程序员没有听说过OOPS和SOLID设计原则,他们根本不知道设计原则的好处,也不知道如何依照这些原则来进行编程. 众所周知,Java编程最基本的原则就是要追求高内聚和低耦合的解决方案和代码模块设计.查看Ap

Hbase中rowkey设计原则

Hbase中rowkey设计原则 1.热点问题 在某一时间段,有大量的数据同时对一个region进行操作 2.原因 对rowkey的设计不合理 对rowkey的划分不合理 3.解决方式 rowkey是hbase的读写唯一标识 最大长度是64KB. 4.核心原则 设计必须按照业务需求进行设计 5.长度原则 经验:10~100字节可以 官方:16字节,因为操作系统时8字节进行存储 6.散列原则 划分region是按照rowkey的头部进行划分. 有几种方式: )组合字段 id+timestamp )

设计原则之接口隔离原则

segregate   v.隔离 se 蛇  gre green格林  gate门 蛇被格林用门隔离了. 设计原则之接口隔离原则 动机:         客户不应该被强制实现他们不用的方法.应该用多个小的接口代替庞大功能全的接口. 结论:        该原则在代码设计的时候就要考虑.可以使用适配器模式将胖接口隔离. Bad Example:    缺点:         1.如果新增一个robot机器人工人,那么eat方法就是多余的了. // interface segregation pri

设计原则之单一职能原则

设计原则之单一职能原则 动机:         一个职能被考虑成为只有唯一理由去改变,如果我们有两个理由去改变一个类,我们要把这两个功能分成两个类.每个类只控制一个职能,如果在未来有一天我们做某个改变,去改变对应的类就行了. 目标:        一个类应该只有一个被改的理由. Bad Example:缺点:     1.新增一个新的协议将会带来一个新需求,要为每种域序列化内容.     2.内容不一定是string,也会有html等其他形式. // single responsibility 

设计原则之里氏代换原则

设计原则之里氏代换原则 substitute  = replace 替换 sub 下 st石头 i我  tu土 te特别 我用石头替换下土,造了特比坚固的房子 hierarchy  ['harɑk] = level 等级 hi海豹  er儿子  ar are是  ch成龙 海豹儿子的雷霆战机等级是比成龙高 derive [di'raiv]  起源,派生 de德国  rive river河 德国的莱茵河起源于阿尔卑斯山 动机:         当我们创建类的层级(继承),我们继承一些类,创建一些派

设计模式2 面向对象设计原则

面向对象设计原则  原则的目的 面向对象设计原创表  单一职责原则案例 开闭原则 案例 依赖倒转原则 案例 面向对象设计原则  对于面向对象软件系统的设计而言,在支持可维护性的同时,提高系统的可复用性是一个至关重要的问题,如何同时提高一个软件系统的可维护性和可复用性是面向对象设计需要解决的核心问题之一.在面向对象设计中,可维护性的复用是以设计原则为基础的.每一个原则都蕴含一些面向对象设计的思想,可以从不同的角度提升一个软件结构的设计水平.  面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含

设计模式——设计模式与设计原则

设计模式--设计模式与设计原则 一.设计模式  1.设计模式简介 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石. 模式的经典定义:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心,通过这种方式,我们可以无数次地重用那些已有的解决方案,无需再

面向对象设计原则

七大原则:开闭原则.里氏代换原则.依赖倒转原则.合成/聚合复用原则.迪米特法则.接口隔离原则,单一职责原则. 开闭原则是面向对象的可复用的基石.其他六种原则是手段和工具. 各规则详细(本部分为转载) http://kb.cnblogs.com/page/214010/ 正如牛顿三大定律在经典力学中的位置一样,“开-闭”原则(Open-Closed Principle)是面向对象的可复用设计(Object Oriented Design或OOD)的基石.其他设计原则(里氏代换原则.依赖倒转原则.合

软件设计原则和方法通俗理解

网上有很多关于软件设计原则的说法,很精确,很官方,但是对于有些初学者来说可能是不知所云,到最后把自己给郁闷到了,学习软件应该是一件愉快的事情. 那么软件设计原则有哪些呢? (1)可靠性 做出一个可靠的软件,跟女人找一个可靠的男人一样,女人找男人,需要男人品质好,人品好,靠谱,可信赖,可依靠,身材高大,等等.软件设计也是一样,在软件的设计阶段就要非常注意软件的可靠性,不要等到最后用的时候发现软件这里不行那里不行,或者说在使用软件过程中一旦发现问题还是可以恢复使用,不能直接崩溃. (2)健壮性 这个