主题:【原创】漫谈浏览器大战 -- (构架篇) -- Highway
最近工作之余稍有闲暇,于是就跟踪了一下最近IT方面的热点新闻。感觉着现在最火爆的两个战场就是手机OS和新一代的浏览器了。可惜我于手机知之甚少,只好避开这个话题谈谈浏览器了。
其实就浏览器而言,我也是业余,也就是自己在家里的PC上鼓捣几下,再结合一点专业上的common sense,如是而已。
浏览器这个领域原先是Netscape Navigator的天下(大家还记着吗),后来微软看着Netscape一夜蹿红怒不可遏,调兵遣将推出免费的IE。经过几个回合的较量,Navigator不敌IE,落草成了寇。再后呢,IE一统天下,市场份额超过了90%。一旦垄断形成,微软就再也没有前进的动力了。所以在很长的一段时间里浏览器这个领域基本上是死水一潭,没有任何创新。
真正意义上打响反IE第一枪的应该算是Firefox了,自推出以后不断的攻城略地从IE的手里抢市场。从技术上看,Firefox还是有一定建树的。首先文件很小,下载和安装都很快。另外,程序质量很高,比当时的IE更快捷更安全。还有,Firefox上的Add-on非常丰富,极大的增强和扩展了Firefox的功能。最后还应该指出的是Firefox支持其他OS,比如说Linux。
眼看着浏览器市场从一手遮天就演变到两强争霸了。没想到Google又半路杀出,非要来个Threesome。现在呢,除了这三巨头抢镜以外,苹果的Sarafi和Opera也搅了进来要分一杯羹。所以最近一段时间每个把星期就有一款浏览器推出新版本,并都会大言不惭的宣布是“天下第一快”。
如果仔细一点看的话,就会发现这下一代浏览器争夺的主战场有三个
1)浏览器平台的构架
2)JavaScript虚拟机
3)图形图像的硬件加速
这第一篇呢,就说说新一代浏览器在结构方面的变化。(由于时间有限,所以只能就最有代表性的IE, FF和Chrome来说了,其他浏览器就不赘述了)
新一代的浏览器,清一色的采用了所谓的多进程构架(Multi-process Architecture)。网上的朋友们都常说是Google的Chrome领风气之先。但事实上呢,IE8的Beta版是最早采用这一构架上市的浏览器,从时间上看比Chrome还要早一些。所以呢Chrome首创这一构架的说法有些谬赞了。
有人会问了,怎么一下子大家都玩“多进程构架”了,早干嘛去了?原先的单进程构架怎么了?
早先的浏览器呢,都算是一个“程序”,所以都是传统的“单进程多线程”设计。也就是从任务管理器上看,只有一个进程(当然你可以启动多个浏览器了搞出来多个进程,那不是我们要讨论的问题)。浏览器内部呢,有很多的线程(thread),它们各司其职一同完成复杂的任务。这种设计线路中规中矩,程序开销小,效率高,没有什么不对的地方。
问题出在了“人民群众日益提高的文化物质要求”上。现在的浏览器已经不是一个传统意义上的“程序”了,已经演化成了一个“平台”。浏览器上搭载了无穷多的add-on,plug-in等等。人民群众要在浏览器上看新闻,听广播,点高清视频,玩3D游戏。。。
除了浏览器的任务变得复杂以外,人们使用浏览器的习惯也变了很多。浏览器上开十个八个Tab同时光顾数家网站已经是家常便饭,并且可能浏览器开了就不带关的,除非是出了问题。
开发浏览器的程序员们都渐渐的认识到,面对这样的任务和要求,原先的单进程构架已经不再适用了。原因很简单。因为单进程构架所以的东西都在一个进程里运行,一个地方出问题可能就会使整个浏览器全部歇菜。浏览器Vendor不管多么严格的控制程序质量,多么苦心积虑的进行测试,还是不能解决这一问题。因为浏览器面对的一个“Open ended world”,你永远无法控制第三方的add-on或是plug-in。这些程序如果出了问题,马上就会波及浏览器。
于是乎,多进程的构架就成为了不二之选。说到底,这种构架的核心就是把浏览器的各大功能块分开,运行在各自的进程里面。一个地方出了问题只会是局部的影响,不会造成整个系统的崩溃。现在的操作系统(Windows, Linux, Mac OS)中各个进程都运行在“保护模式”中,一个进程出了问题操作系统会将其的危害控制在该进程之内,不会对其他进程造成影响。这是浏览器采用多进程构架的基本前提。
这种构架为什么以前不用呢?因为这种构架要比单一进程的那种程序复杂很多。多个进程间的通信要解决好,并且要把开销压缩到最小。就现在的技术水平而言,这个问题已不再是什么大问题了。另外,现在大多的计算机都装配有多个CPU(多核),内存也都比较大,多个线程一起运行的硬件资源也不再是一个制约因素了。
虽然在战略上各个公司所见略同,但是在战术实施上还是相差甚远的。Google的Chrome看起来似乎革命最彻底,FF好像只是现有技术的一点点改良,而微软的IE呢,则是另辟蹊径,又搞了一套。
先看最简单的Firefox.
FF把所有的东西还是留在了主进程内。所以当你启动FF的时候还只是一个进程。当进入到一个网站的时候,如果网站比较简单,那么FF自己就料理了,不会产生任何新的进程。如果这个网站要求Plug-in的支持,比如说Flash,那么FF就生成一个进程(叫做plugin-container.exe),在这个进程里运行Plug-in。如果你又开一个Tab去了又一家网站并且这个网站也需要Flash,那么FF就会共用现有的这个plugin-container为两家网站的网页提供Flash服务。所以说呢,FF的进程数量很好计算,那就是一个主进程 + 零到多个个plugin-container。plugin-container的数量取决于运行的Plug-in的种类有多少。
"C:\Program Files (x86)\Mozilla Firefox 4.0 Beta 7\plugin-container.exe" --channel=2572.bd74660.1358250153 "C:\Windows\SysWOW64\Macromed\Flash\NPSWF32.dll" "Mozilla.Firefox.4.0b7" -omnijar C:\Program Files (x86)\Mozilla Firefox 4.0 Beta 7\omni.jar 2572 \\.\pipe\gecko-crash-server-pipe.2572 plugin
有趣的是如果你离开了或是关闭那些需要plug-in的网站,FF并不销毁plugin-container进程。这呢,算是程序设计中一个常见的手段,就是你一旦使用了某个功能的话,那么很可能你还会再次使用。所以呢,那个plugin-container就给你留着,下回来的时候就是现成的,省事儿不是。但是呢,这种设计也有问题,因为plugin-container的数量只增加不减少,对用户而言,FF的内存越占越多。最后不得不把它干掉从新再来。
好,再来看Chrome
Chrome的做法是一个主进程(称为浏览器进程,就是我们看到的东西),1到N个渲染进程(Renderer进程),0-N个Plug-in进程(多少种plug-in就需要多少个plug-in进程,这点和FF一样),0-N个add-on进程(如果你的Chrome有3个add-on,那么就会多出三个相应的线程),一些服务进程(比如新的GPU process, Rundll32进程)。
对细节感兴趣的朋友,可以用Chrome自带的Task Manager去看看Chrome工作时界面之下后台进程生生灭灭的过程,很有意思。Google的这款浏览器就像一个茶馆一样,门帘永远在哪儿(主进程),客人们(Renderer进程)进进出出换了一茬又一茬。
Chrome的这种设计有两个突出的优越性。一是浏览器职能划分的很细,每一个功能体都在自己的进程中,一个进程的问题影响只是局部性的。第二,由于Renderer进程不停的产生销毁,所以即使程序有memory leak或是memory fragmentation也不要紧,因为过不多久进程就走人了,新进程又会从头再来,一切都是崭新的。
有网上的大拿说,Google的进程模式是Per process per site,不是Per process per tab。其实这句话之对了一半。比说你你到西西河来,Chrome马上生成一个Renderer进程来负责这个网站的Render工作(包括JavaScript的运行)。你点击几个link多出几个Tab来,Chrome并没有多出新的进程来。看起来那些大拿的话是对的。但是如果你手工增加一个Tab并敲入西西河的地址,只时候Chrome就会忘记已有的这个西西河Renderer进程,而重新在来一个(见下图)。
和FF不同的是,如果一种plug-in没人用的话,Chrome会保留它一会儿。如果过了这个时间段还是idle,那么Chrome就将它回收了,如果在保留期间有什么网站需要这种plug-in了,那么就延长它的寿命让它继续工作。
另外Chrome9.0 Beta版在运行Plug-in进程的时候,多了一个Rundll32进程.
C:\Windows\system32\rundll32.exe C:\Users\Somebody\AppData\Local\Google\Chrome\APPLIC~1\90597~1.19\gcswf32.dll,BrokerMain browser=chrome。
这个进程感觉是在主进程和plug-in进程间起什么沟通作用的,但现在的Chrome 8版本没这个东西。另外Chrome会不知在什么时候冒出一个叫做GPU process的进程来。感觉是用GPU来做硬件加速用的,但是并没感觉到任何的不同,它的激活机制我还没有搞清楚。所以这个还有待于进一步观察。
OK,最后来看IE
IE的进程结构比较不直观。从外观上看,有些像Chrome的Per process per site(和Chrome一样也不是那么严格)。但是呢,IE不把Plug-in或是Add-on拿出去。除了主进程以外就是Renderer进程了,只有两种类型,而不是Chrome那样的五种类型。这个Renderer进程除了html, CSS, JavaScript任务之外,Add-on和plug-in的程序也在其中。所以说是一个heavy-duty的Renderer。
和Chrome不同的一点是,IE并不是急于创建或是销毁Renderer进程,它试图重新利用他们。比如你当前是在西西河,如果你在address bar输入另外一个网站的地址离开西西河到别的网站的话,IE会重用当前这个Renderer进程。而Chrome呢,是重新为新的网站生成一个新的Renderer进程,然后马上销毁西西河的这个Renderer进程。
看到这里大家肯定有些晕了,不禁会问“你罗哩叭嗦的说了半天,到底哪种方案最好?”
这个很难说了,要看情况。比如说现在正是2012年伦敦奥运会,你开了三个Tab同时看三场比赛(Tab可以扯到桌面上铺开来看)。一个是中国转播的乒乓球,一个是美国转播的篮球,还有一个英国转播的足球。每个网页上呢是Flash转播的高清视频,另外还有HTML5技术提供的网友实时评论和场外花絮等等。
比方说,英国方面转播的足球出了问题,造成了Flash崩溃。那么用FF的用户和Chrome一样,什么图像都没了(因为Flash进程是共用的)。但是三场球的实时评论和场外花絮还能看得到。IE用户呢,情况不太一样,乒乓球和篮球还能看道视频,实时评论和场外花絮也完全正常,但是足球那个TAB就全歇菜了。
再比方说,美国网站HTML5提供的场外花絮部分出了问题,那么FF用户最惨,整个FF歇菜了,什么都没了。Chrome和IE的用户一样,乒乓球和足球还看着很好的,只不过是篮球那个Tab宕掉了。因为FF是用主进程来处理HTML5的,Chrome和IE都是独立的Renderer进程处理HTML5,出了问题之影响那一个具体的Process,别的Tab一点没事儿。
就我个人而言,有这么几点看法
1)FF的保护机理太过简单了。主线程任务太重,那里面一出问题整个浏览器就宕了。另外,Plug-in process重来不回收也是一个问题。
2)Chrome的进程显然太多了。如果你装了七八个个Add-on,再去几个网站的话,那么整个进程数可能就是十好几个了。对于那些内存少并且less powerful的机器可能就会是一个问题了。不知道在手机平台上Chrome浏览器是不是也用的同样的策略。
3)IE的想法不错,想把进程数量压缩在一个适当的范围内,不给OS太多麻烦。但是不把plug-in和add-on从Renderer进程分离出去,就每个Tab而言,保护程度和可靠性就自然下降了。在实践中的具体效果还有待于检验。
三种浏览器的新一代Beta版本我都用过,似乎Chrome给end-user的感觉最好。那么多进程间的通讯效果很好,进程不停的生成和销毁也没有任何停顿的感觉,界面上始终很流畅,很少有滞后感。(Chrome的程序员们本来开始是要用微软的COM技术来进行进程间通讯的,但发现COM不能满足他们对Async通讯的要求,于是就改用named pipe。虽然麻烦了一点,但看起来效果很不错。不过呢,在Linux平台上,又变成了Socket,不知道有什么原因。)
==============================================
待续。。。
本帖一共被 2 帖 引用 (帖内工具实现)
- 相关回复 上下关系8
🙂【原创】漫谈浏览器大战 -- (构架篇)
🙂热门社交游戏厂商Zynga收购浏览器开发商Flock 1 素里太守 字215 2011-01-06 18:51:34
🙂不是我不明白,这世界变化快啊! 3 Highway 字477 2011-01-06 20:06:57
🙂【原创】乱弹浏览器大战(1.2.3......) 43 素里太守 字3164 2010-12-30 01:57:28
🙂写的很好,可惜我无法通宝推荐 3 Highway 字404 2010-12-30 06:47:20
🙂你找到手机用户的痛点了。 3 素里太守 字231 2010-12-30 15:15:41
🙂【原创】关于构架,补充一点 14 Highway 字1025 2010-12-27 20:02:15
🙂【原创】漫谈浏览器大战 -- (硬件加速篇) 68 Highway 字5567 2010-12-26 19:42:14