打造Chrome的平行世界:从Chrome到Chromium for Application

互联网浏览器改变了软件世界

         毋庸置疑,互联网浏览器深刻的改变了世界,Google Chrome奠定了浏览器事实上的标准。

(互联网浏览器,深刻的改变了人们获得内容的方式,也促使软件形成了Web软件与应用软件之间的界限……)

当我们具体考察浏览器软件行为的时候,我们看到了如上图体现的基本事实。如果我们将目光投向浏览器之外的软件,我们看到完全不同的场景,其他类型的软件,缺乏浏览器内容区域的灵活性以及“网络申请内容”的模式,人们很难想象如下的场景:

(浏览器使得人们有了思维惯性,似乎让我们忽略了什么,其实“网络浏览”是软件的共性……)

如果我们进一步脑洞大开,我们更加难以想象:

WebOffice文档听起来非常离谱,其实有一张遮挡视线的“黑幕”,一旦拉开,一个全新的软件世界将浮现……)

当我们将目光投向普通的应用软件,那么就会与浏览器特征形成了极大的反差:灵活与笨拙、内容丰富与功能局限、基于网络的获取途径与本地加载的制约、……,互联网浏览器用页面的方式,以有限的规则、以及一组简单的DOM元素,创造了一个丰富的Web世界,这一点,应用软件领域确实显得相形见绌,这些现象是今天软件界的一个缩影,有没有一个合理的方案来弥补网络浏览器与应用软件系统之间的偏差?

Chromium for Application

Chromium for Application是面向Windows应用的运行时架构,允许开发者在自己的应用系统中支持Chromium的全部功能,其本质是允许开发者重构Chromium的主进程(Browser进程),充分发挥Win32与Web的双重优势,Chromium for Application的目的是建立应用软件与互联网浏览器基础功能之间搭建一个衔接“桥梁”,以此来弥补应用软件互联网基础的不足,确保开发者可以构造符合现代互联网特性的应用系统。

        我们先看一幅图:

         (这是一个Chromium Project定制版本的运行时截图)

这是演示的是一个实验性的Chromium版本,其中包含一些Google官方版本以及Microsoft Edge不包含的元素:

  1. 包含Win32元素;
  2. 包含Microsoft .NET Framework支持;

3、包含完整Chromium。

我们还可以提供进一步的信息,如下图所示:

我们看到,被Chrome浏览器屏蔽的.NET、Win32等组件完全可以在Chromium意义下重新回归。Google的策略是确保Web内容的整洁,所以在Chrome内部将Win32部分在运行环节以及GUI环节都做了严格的限制,这一做法客观上确保了Chrome浏览器的相对简洁、安全,同时也牺牲了浏览器的可编程特征,从开发者的角度看,限制了开发者的创造力,是对软件生产力的一种极大的制约。我们能否将IE的优点以及Chromium的优点都继承下来?如果可以,那么具备Chromium以及IE双重优势的浏览器模型就可以变成现实了。

Chromium GPU子进程,拨开迷雾的关键所在

所有的一切,从详细的剖析Chromium浏览器窗口开始。当我们尝试对Google Chromium做一些修改,会发生什么?先看一下标准的Chrome浏览器默认的新浏览窗口,我们考虑先这样一个问题:如何缩小、偏移Web页面的显示矩形,给其他东西让出“空间”?如下图所示

     (我们能否修改Web页面的实际显示矩形,在浏览器窗口内部让出部分空间?)

让我们设想一下,其中的部分“网格”里面可以放一个“组件”,例如一个.NET Usercontrol,会怎么样?当实际写代码实现上面描述的场景的时候,令人震惊的一幕出现了,Chromium会“拉黑”你创建的一切,我们看到了如下的场景:

                             (Chromium会“拉黑”你创建的所有对象,除非你按照它的规则,在它规定的几何区域内工作)

经过无数次的实验,我们发现:所有的Win32对象,无一例外的都被Chromium“拉黑”了。这一切与浏览器的主进程完全没有关系,每个对象都正常创建了,可以正常的进行代码交互、组件间的互操作完全正常,就是不能正常的显示,这一切的始作俑者就是Chromium GPU子进程,这个子进程让Chrome浏览器变成了“黑洞”,所有其他人创建的对象,都被这个黑洞吞噬了,其结果是浏览器里面用户所看到的一切只能是按照google预设规则创建的对象,通过这类子进程分工的模式,Google成功的将那些成熟的技术框架,例如.NET、COM、Java等等成熟运行时创建的UI对象,排斥在浏览器运行环境之外。

从软件设计角度看Chromium,GPU子进程是无沙箱约束的,Chromium相关的一切可见的对象,都是GPU进程负责绘制,这个进程的职责非常明确。我们认为排斥Win32的UI机制,不应该是出于互联网“安全”的考虑,而是Google刻意制造的规则,或许Google认为,庞大复杂的Win32技术资源会冲击Chromium项目的规范性结构、或许是不希望那些面向应用的庞大的技术群体会打乱Chrome的软件规范,因此,GPU进程在这里从技术复杂度的方面建立了一个“隔离墙”,我们无法知道真实的原因,然而一个客观事实是,这个环节极大的制约了软件的生产力。Chromium for Application的策略是让GPU子进程的绘制工作“合理化”,给其他技术框架的UI组件留有独立绘制的余地,这样的考虑,确保了所有Win32对象可以独立的呈现,同时也不会影响Chromium本身的绘制机制。

让开发者重新布局浏览器窗口是一个全新的起点

         开发者重新布局浏览器窗口,是一个直观的想法,如果可行那么后续的一切就会顺其自然。我们重新看一下标准的浏览器窗口:

页面独占了几乎全部的客户区,看起来没有缝隙,没有余地。

         如果可以重新调整Web页面的显示的几何位置,那么开发者就可以重新对浏览器内部进行布局,我们的设想是如果可以重新布局,那么布局就应该是可以描述的、多样化的。突破DOM的约束,是Chromium for Application面临的一个新挑战。现代互联网发展到今天,各类开发者都能够接受html页面的表达方式、开发标准。Chromium for Application按照Web的规则,扩展了DOM元素,同时确保Renderer干净、安全,这一点非常重要。我们认为,一个矩形区域,基本上可以容纳两种结构:1、网格化结构;2、标签化结构。由于具有多个标签的“标签”结构,可以认为是“1行n列”的网格,所以原则上只有网格化结构,更复杂的矩形内布局基本就是网格结构的“复合结构(网格嵌套)”。我们将“1行1列”的网格称之为“node”,那么一个m行n列的网格,就包含m*n个node对象,网格是可以递归嵌套的,因此可以用xhtml标准直接在页面里面“写”从来。一个node对象里面可以描述一个Win32对象,Chromium for Application会将其创建在主进程,这样就与Renderer合理的隔离了。Win32是用消息与Renderer通讯的,Renderer可以不响应消息,Win32与Renderer之间的互操作是一种“跨进程委托”,我们给开发者提供了“JavaScript Callback”的处理方案,开发者可以将主进程的一种请求转化为JavaScript回调,可以给回调提供足够的“参数”,类似但不同于.Net Delegate, 差异是这种委托是跨进程的,主要是确保Web不能被Win32“污染”。

         如图,一个4行3列的网格结构:

         一旦浏览器窗口的内容区域可以重新布局,一种新的Web页面结构就具体化了,Chromium for Application既然立足于包容Chromium的全部功能,那么Chromium操作的主体对象WebPage就是应用程序的基本对象,如果Web页面没有实质性的改进,那么包容Chromium就毫无意义,充分利用Web页面,是一个核心话题。一旦应用系统建立在Chromium基础之上,事情就会发生根本性的改变。我们给出了两个方面的具体变化,第一:Web页面的变化;第二:JavaScript方面的变化。WebPage增加了node元素,最简单的node写法如下:

<node nodetype="clrctrl" cnnid="TangramWinApp1.UserControl1,host"></node>

这里,nodetype标记node的类型,可以是“clrctrl”、“activex”、“splitter”等等,具体参考我们的技术文档,根据需要,node可以是一个.NET Control、ActiveX、C++ View以及各种复合结构,cnnid是具体对象的id,取决于实现的语言,允许页面开发者编写更加复杂的node网格结构,这里不做细节介绍。不同于IE浏览器,node对应的具体对象在页面上仅仅提供“结构描述”,实际的创建发生在Browser进程以避免污染“Web”的Renderer进程。JavaScript方面的变化,我们会在后续的文章中做详细介绍。

构造Chrome浏览器的“平行世界”

         我们看到,Chromium for Application使得一个浏览器窗口内部的结构可以用Web页面“重新布局“,这一步是一个重要的起点,从应用程序窗口的角度看,浏览器窗口仅仅是众多窗口类型的一种,从更加广泛的意义上看,每个窗口都有内部布局,与浏览器窗口并没有太大的区别。当我们用看待浏览器窗口的想法看待其他窗口的时候,事情会怎么样?我们以Excel为例,看下图:

上面的场景一旦与我们曾经描述的下图的场景做对比:

我们发现Web浏览器内部发生的一切在Excel里应该被“复现”了,这说明什么?是不是一个(与浏览器)完全一致的通道露出了蛛丝马迹?

Chromium for Application 允许你用一致的Web化思路看待那些结构完全不同的应用体系,如果我们从几何的视觉角度看,每个窗口都有可能基于“几何布局的”角度重新规划:

           (寻找浏览器窗口的“平行世界”,我们面对的是一个完全不同的、丰富多彩的世界……)

都需要一个规范一致的“页面描述”方式,那么就需要解决几个关键的问题,第一个问题是页面化的标准是什么?第二个问题是页面“存储在哪里”?第三个问题是怎样解析页面以适应不同的软件?

第一个问题:页面的标准依然是Web页面。Web页面做为一种通用的方案,是考虑到一个基本的事实,即Web页面已经大量存在了,同时也培养了用户的习惯以及开发者的习惯。Chromium for Application的一个基本出发点是,让更多的窗口都具有Web特征,一旦应用窗口满足一定的条件,那么我们都可以将其视为一种浏览器窗口,那么它们应该都具有”浏览行为“,也就是说存在一类Web页面适配对应的窗口,那么这类窗口的行为就可以通过Web页面进行规划、控制。由于Chromium是开源的,有庞大的社区支持,所以,我们经过充分的研究,将Chromium项目编译成一组公共软件服务,不同于那些基于“控件”的方案,我们保留了chromium全部的功能,做到最大限度的适配性。一旦Chromium变成公共组件,就具备了“Runtime”特征,那么其他软件就可以以一致的方式与之衔接。Chromium变成运行时,意味着开发者可以以任何目的为出发点去访问“URL”,可以用与Chrome相同的方式获得html页面。

第二个问题:页面的存储方式不变,这样考虑可以实现应用软件功能最合理的剥离,从本地迁移到服务端,使得软件可以实现从单一软件提升为软件服务,开发者对待后端的做法没有任何改变。

第三个问题:我们允许开发者按照标准的方式显示页面,当然,也支持“子窗口”的显示方式,Chromium for Application给开发者更大的自由度,允许开发者基于自己的目标使用页面,这样的话,页面里面的一些元素,就可能不同于标准页面,例如,可以解析为一个WinForm、一个Office文档、一个特别结构的Window等等,取决于开发者的需求,就是说,需要开发者将任何其他的元素都看做DOM,需要一个思维上的突破,从数学的角度看,相当于从“实数”扩张到“复数”。我们给出了非常”弱“的条件,使得绝大多数应用窗口都可以通过Web方式赋予新的软件行为,用Web的观点对待应用软件窗口,是对窗口概念的一个极大的颠覆。事实上,一旦我们用看待浏览器窗口的方式看待其他窗口,一个有待我们用Web思路重新规划的软件世界就会变得现实了。

结果我们发现,在互联网模式下,大多数软件看起来几乎是一样的:都可以通过在Web后端组织页面来描述具体的应用形态,只不过对应的页面承担的使命不一样,浏览器显示页面可能是用来“看”的,其他应用html的表现方式可能因应用不同而不同,有可能页面不是用来“看”的,而是用来确定不同的应用结构,其中的javascript脚本可能用于应用软件的行为控制……。

         上述设想可以进一步拓展一下,我们可以调整一下Chromium Project,允许开发者做更多的事情:

                1、允许开发者创建自己的Browser进程;

                2、保留Renderer进程的干净、整洁性,允许开发者按照Web规则扩展DOM;

                3、允许开发者在Browser进程之内合理使用Win32组件;

                4、不允许Win32直接与Renderer交互,确保Chromium架构的完整性;

Chrome的平行世界,意味着拥有与Chrome一样的对待Web的底层机制,每个与Chrome平行的软件,可以拥有自己的解析页面的原则,这方面就与Chrome形成差异,平行意味着结构的类似但又完全不同,在支持标准Web页面的方面看,Chrome与“平行系统”拥有公共的基础,每个Chromium for Application为基础的应用都会有自己的对象模型。除标准Web页面之外,还支持与Win32组件(COM、.NET、Java……)与标准DOM合成的新页面,这一点确保这类应用拥有比Chrome、Microsoft Edge更加丰富的页面组织形式。在Chromium for Application支持下,每个具体的窗口都可能是一个Web页面或者是一个Web页面元素,就是说,页面的含义被延申了,这一点也是标准页面的一种进化。

安全是Web的底线

       在与Microsoft的浏览器竞争过程中,Chrome成功的定位了Microsoft IE的诟病。在IE6.0的世界里,每个IE浏览器窗口运行在一个独立的线程里面,其中包含各种基于COM、.NET的插件以及Web页面,由于浏览器窗口中COM、.NET代码与Web页面里的脚本代码都在同一个线程之内运行,特别,IE系列的Web DOM API是COM技术实现的,线程内的COM代码可以直接操作Web页面里面的一切,Web内容完全暴露给外界,这一点给开发者带来极大的透明度,也给Web内容带来最大限度的“污染”,同时安全性的诟病凸显出来了。我们认为Google正是发现了这些问题,才将Chrome设计成多进程架构。在Chromium的世界里,每个页面运行在一个独立的Renderer子进程里面,Chrome利用操作系统沙箱确保每个Renderer子进程不能执行与GDI有关的任何操作、不能创建窗口对象、无法操作文件系统,只能调用有限的API,Renderer的职责就是解析页面、执行JavaScript脚本,除有限的这些操作之外,不做任何事情,从这个角度看,Renderer内部是一个安全、无污染的环境。Renderer子进程对用户而言是完全不可见的,用户真实看见的事实上是GPU子进程绘制出来的“几何映像”。Chromium内部将大量的用于浏览器的元素转化为“干净”的JavaScript元素以及DOM元素体现在Web页面上,允许开发者通过脚本方式,安全的进行软件互操作。Renderer子进程提供给开发者的是简单的脚本运行模式,与外界是通过IPC消息进行通讯的,这一点与微软IE形成了鲜明的差异。

毋庸置疑,对浏览器软件结构而言,Renderer的出现是一次变革,美中不足的是,这个变革仅仅限于浏览器本身。如果让我们选择现代浏览器最大的突破在哪里,我们认为Renderer进程的引入是一个重要的突破。我们的构想是必须完整的保留Renderer的全部特色,这样Web的安全性就会得以保障。借助于IPC消息,Chromium for Application走出了被Chrome屏蔽的关键一步,这一步就是允许Win32组件以跨进程的方式与Renderer子进程对话,其实Chrome内部就是这样做的,我们允许Win32对象与Renderer对象之间合理的建立映射关系,明确规定Win32不允许直接操作、修改Web内容,如同Chrome不允许Renderer直接操作文件系统一样,这样的做法可以确保Win32与Web同时发挥作用,让开发者获得最大的自由度。Chromium for Application使得Renderer突破浏览器的边界,允许其他应用系统具备安全的支持Web页面的能力。

突破浏览器窗口的制约

重构意味着开发者可以选择自己熟悉的技术架构,可以是Java、.NET、COM或者C++、允许自己的组件系统运行在Browser进程,给开发者带来更大的自由度,例如开发者可以用自己的窗口替换部分浏览器窗口,将浏览器窗口看做自己应用系统的一部分,如下图:

          (重构Browser进程,意味着开发者有更大的自主权)

事实上,这个构想就是让Chromium Project可以做为一个具体应用的新起点。Chromium for Application的策略是:将Chromium编译成一组动态链接库,使开发者可以规避Chromium Project带来的复杂度问题,同时也避免了用户的代码“污染”Chromium项目本身,就是说,用户构建自己的工程结构、解决方案,不直接与Chromium项目打交道,从这个意义上说,Chromium for Application是一个“代码隔离墙”,确保了Chromium项目的规范性与独立性。由于Chromium是开源的,所以我们可以做得更加彻底。Win32技术的完整回归,意味着浏览器技术突破了浏览器的局限进入应用领域,这一点非常重要。

Chromium for Application的使命

Chromium for Application的宗旨就是浏览器核心功能应该是软件公共基础的一部分,不仅仅是浏览器本身所独有。从技术架构上看,无论Chrome与MSEdge怎么发展,这两款浏览器与Chromium的本质差异不会太大,我们认为Chromium已经包含了Chrome与MSEdge 95%以上的功能,个别的差异以及体验的提升肯定是存在的,然而Chromium for Application重新定义了应用软件的基础结构,使得:

  1. 基于Windows的应用软件可以有与Chrome完全相同的多进程架构,每个应用的主进程可以具备完整的Chromium Browser进程的功能结构,软件开发者可以运用自己熟悉的技术框架开发主进程,拥有Chromium提供的浏览器窗口(包括浏览器子窗口),主进程支持所有主流软件运行时,包括Java、COM、.NET以及C++;
  2. 页面即应用,每个应用可以拥有自己的具有应用特征的Web页面
  3. 每个应用都内置一款现代浏览器;
  4. 每个应用都有自己的Web后端,进而使得软件可以提升为软件服务,每个应用的Renderer子进程与Chrome Renderer子进程完全等价,拥有完全相同的沙箱机制;
  5. Win32与Renderer之间拥有IPC通讯的交互方式、完备的JavaScript回调机制;
  6. 应用系统可以有自己的不同于标准浏览器方式的页面解释行为;

Chromium for Application将浏览器的概念延申到更加一般的应用系统之中,用一种全功能、Web-Desktop混合的方式突破浏览器的功能边界,以此适应互联网模式带来的变化。

每个应用系统都有自己的应用页面体系,进而有自己的页面生态

重新布局意味着浏览器窗口内部的页面是“多样化”的,例如开发者可以开发应用化的Web页面:

  (应用系统可以定义基于页面的应用,用来灵活方便的定义自己的功能单元,页面可以有效控制每个功能的具体行为)

应用化的页面,就是一种标签化的应用,Web页面控制着应用对象的操作逻辑,许多软件行为可以迁移到服务后端。这种组织非常有利于软件功能的中心化。应用页面可以体现为更一般化的窗口:

   (chromium for app 通过解析HTML中的WinForm元素构建出对应的WinForm窗口)

应用系统的具体功能可以体现为一个一个具体的Web页面,一旦应用是基于页面组织的,应用系统的功能组织“站点化”了。

         Chromium for Application定义了标准html页面的一个“超集”,使得应用系统不仅仅支持标准html页面,还支持一个更加庞大的“应用页面”集合。每个页面相当于对应应用的一个“子应用”。事实上,Chromium for Application重新定义的应用系统的结构,使得应用系统从以“二进制”元素“为核心提升为以”应用页面“为核心。

         一旦你的应用系统与Chromium for Application对接,你的应用系统就天然存在一个基于Web页面的“生态系统”,可以用庞大的Win32组件与标准DOM合成形态各异的页面服务于你的用户,当然,你可以让页面的显示不同于标准的浏览器窗口,可以是你自定义的UI“壳”,在公共页面体系上看,每个这类应用都有一个巨大的外延,事实上,Chromium for Application不仅仅将Chromium项目编译成一组公共软件服务,对.NET、Eclipse等等成熟框架都编译成对应的运行时库,这一点使得应用系统可以支持Web的同时,可以用类似的观点对待.NET Framework以及Java,这意味着,即使你的应用是一个.NET或者MFC程序,你不仅可以在你的应用里面构造浏览器窗口,你还可以直接使用SWT窗口、Eclipse Workbench,所有这些都是页面化的,都可以用统一的Web机制一致化处理,进而彻底改变了应用程序的结构。

Chromium for Application是一个开放的项目

可以在https://marketplace.visualstudio.com/items?itemName=TangramDev.tangram-wizard 下载Chromium.NET Wizard。Chromium for Application包含开源、商业两个环节,我们本着开放、多赢的角度,欢迎各界朋友参与到这个工作之中,不限于个人、团队、公司、投资合作。

联系我们:

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页