复杂网络代码_据报道称“浏览器内核有上千万行代码”,浏览器内核真的很复杂吗?...

3bd451db717ad0fc7bac3442df63e39d.png

浏览器的复杂程度,称之为IT界的火星计划都不为过。

连微软都没有能力再维护一套“跟得上最新标准”的内核而使用Chromium内核。

准确地说,是指没有把握在有限的资源内(远超出其他小厂),纯粹通过自身的力量,开发出一套比Chromium更具有竞争力和商业价值的内核。

浏览器的复杂,涉及几个方面,稍稍点一下,不作展开:

1、排版与渲染。这一方面的设计,最早最早可以追溯回去Knuth老爷子的《The TeX Book》,

诸如px、em、inch、baseline、vbox、hbox这些概念,

最早最早都是为 TeX 排版创造出来的,用于字母的定位。

CSS 3.0 那些变幻、动画,就更不提了。

2、多媒体,包括声频视频。

在 Fabrice Bellard 大神的 ffmpeg 之上,还做了非常非常多的工作。

需要处理各种播放格式的解码工作,这部分又分为硬件实现和软件实现。

3、JavaScript引擎。这里涉及编译原理、JIT优化、垃圾回收。

4、图形学。WebGL,底层D3X、OpenGL 适配,现在还多了一个 Mac 的 Metal。

还要绕开NVidia、AMD、Intel显卡对各种驱动的可能出现的坑。

5、网络。包括完整实现HTTP协议、WebSocket协议、WebRTC协议,还有新协议诸如HTTP2、HTTP3等。

对比与渲染与多媒体,这部分反倒是最不困难的,也是确定性最强的。

6、与OS的交互与优化。这部分至少3套代码,MacOS、Windows、Linux 各不同。

7、要实现好上万页的W3C标准,通过兼容性测试。

8、安全性。各平台实现的SandBox环境。

e67f58116a7a123e8002f262c28c7bb5.png

另一浏览器Firefox内核源代码,都还保留着Netscape浏览器的遗产,有些部分一行都没改过(或者说没有能力读懂,就没改),但还能跑还能用。

很多人会混淆“难”与“复杂”2个维度,用浏览器这个例子就很能说明这2个维度的差异。

难。需要硬功夫去啃,强调的是特定领域的深度。

复杂。涉及面广,强调的是多个领域相互配合。

对于浏览器前面说的几点,你把每一点单独抽出来,啃个3年5年,总能啃出点成果。

例如V8 JS引擎里头的语法解析部分,至少可以理解他怎么运作的。

而对浏览器而言,你需要把上述不同领域的都摸一遍,摸清楚难点在那里,摸清楚与其他组件如何配合,可能3-5年也只能知道个大概。

一个浏览器,涉及了操作系统、图形学、编译原理三座大山的各个方面,需要各个组件精密地配合运作起来,

否则就是排版错乱、音频视频变噪音等问题,直接导致产品不可用。

我们来看chromium。源码拉下来就有十多G。

我们不禁好奇,chromium到底有哪些玩意,为啥平时感觉只是显示个网页、几句HTML而已,怎么会需要这么多代码。

e0001c21721ac480bf83c9ec01bef4ab.png

第一眼从目录结构上,chromium包含这些东西:

  • base,通用代码,基础组件,包含字符串、文件、线程、消息队列等工具类集合。

  • cc,Chromium compositor 的缩写,负责渲染合成。

  • chrome,Chromium 浏览器外壳实现。

  • content,多进程沙盒浏览器的核心代码,管理进程架构和线程架构。

  • gpu,OpenGL 封装代码,包含 CommandBuffer 和 OpenGL 兼容性支持等。

  • net,网络栈实现。

  • ipc,进程间消息通信实现。

  • media,多媒体封装代码,包含了媒体内容捕获和播放的组件集合。

  • mojo,类似于 Android 的 AIDL,提供了跨语言(C++ / Java / JavaScript)跨平台的进程间对象(Object)通信机制;。

  • skia,图形库,这里存放的是 Chromium 对 skia 的 配置和扩展代码,另有 third_party/skia 目录存放原生的 skia 代码。

  • third_party,网页排版引擎。第三方库

  • ui,UI 框架。

  • v8,V8 JavaScript 引擎库。

看起来还好吧?但实际上,这里面每一个展开来讲,都是一本厚厚的工具书的容量。

960f56e3bb764e831923ebc9d6446133.png

比如net,看起来只是个网络库,然而里面包含主机解析,cookies,网络改变探测,SSL,资源缓存,ftp,HTTP, OCSP实现,代理 (SOCKS和HTTP) 配置,解析,脚本获取(包括各种不同系统下实现),QUIC,socket池,SPDY,WebSockets……里面每一项展开来讲,就是一本书。

v8层,看起来功能很单一,只是实现一下js嘛,但里面包括字节码解析器,JIT 编译器,多代GC,inspector (调试支持),内存和 CPU 的 profiler(性能统计),WebAssembly 支持,两种 post-mortem diagnostics 的支持,启动快照,代码缓存、代码热点分析……里面每一项展开来讲,又是一本书,还是难坑的编译原理和优化方向。

Skia,看起来只是个图形库嘛,用点画出各种图。然而里面包括十几种矢量的绘制,文字绘制、GPU加速、矢量的指令录制以及回放(还要能支持线程安全)、各种图像格式的编解码、PDF的生成(这个是个隐藏的很深的功能,但很有趣。Skia支持把矢量图绘制成pdf)、GPU渲染优化(既以上部分功能需要用gpu来渲染)……里面每项展开来讲,又是一本书。另外值得一提的是,skia是谷歌收购的。不知道谷歌是觉得自己没实力做,还是太费功夫。总之谷歌选择了直接买别人的代码来完成这些功能。

ui,看起来只是一套UI 框架嘛。然而chromium需要一套全平台适配的ui库,还要能支持gpu加速。不过可惜的是里面没实现richedit。ui库的设计,深入来做,其实可以说又是个浏览器了。

等一下,以上这些,看起来只是浏览器的外层。

362e857601e4c88b0072d9c21ccbd78a.png

我们最关心的网页排版呢?

这个难道不是浏览器的核心嘛。

是的,神奇的是,chromium把排版引擎blink放到了third_party下,而且架构上真的当成了一个第三方库一样对待。

据谷歌的员工说,这是历史原因……好吧姑且信了。

然而这个第三方库,成了当之无愧的最复杂,功能最重要的第三方库。

blink的工作包括:

  • 实现web平台的规范(例如,HTML标准),包括DOM,CSS和Web IDL

  • 配合V8运行JavaScript

  • 从底层网络堆栈请求资源

  • 构建DOM树

  • 计算样式和布局

  • 请求chrome compositor(上文提到的cc层)并绘制图形。

说起来简单。看一下现在的HTML、CSS规范,各种细节加起来……有快上万页。

除了chromium layout组、firefox的开发人员等,我想没几个人会去仔细阅读并一个个的实现这些规范吧。

光是看目录和文字描述,就头大了,更别说要完整的实现出来。

往往一个简单的display:gird\flex背后就是庞大复杂的计算,而且还要充分考虑性能上如何优化,滚动时如何更快的展示…

另外排版还需要支持世界各国的奇奇怪怪的文字。

例如从右往左写、规则复杂无比阿拉伯文。

相比之下,汉字这种方块字的排版简直就是弟弟。还有各种奇怪的unicode字符。

【转】奇怪的unicode字符

542f1ca269dfbdd59f7eaf757c299308.png

怎么能处理好这些字符和语言,并配合几千页的html、css排版规则正确显示出来……这是个极度烧脑的事情。

我们再从排版这个大泥坑里跳出来看看外面别的东西。这时候你会发现……外面的泥坑好像更大。
随便说几个,比如:

  • 多进程框架。嗯,你需要更多的进程来渲染更多的网页,这样才能崩溃了也不影响其他网页。

    注意,chromium把渲染排版放在渲染进程,但绘制到窗口又是主进程。

    这里面少不了各种跨进程通信、同步。对于代码的编写以及调试,是个很考验编程功底的事情。

  • webrtc。网络视频相关。又是一个被收购的库。关于webrtc,

    你需要知道它能实现多人实时语音、降噪、网络传输视频、摄像头的捕获,音频算法实现(比如 fft),视频算法实现(比如 h264 协议格式), Socket、线程、锁等基础库(是的,webrtc也造了套自己的轮子)。又是个庞大的组件。

  • 密码管理、下载管理、扩展管理。

  • 一套调度整个多进程框架以及blink的核心层。

    在chromium被称之为content层,负责处理一切繁琐的细节。例如各种系统、平台的鼠标键盘消息派发,历史栈(前进后退),页面缓存。

  • 沙箱机制。负责隔离以及降低子进程的权限。沙箱的实现上,在不同系统做了诸多hook操作。

  • chrome相关的外壳及应用。例如我们常见的标题栏、url栏,webui如设置页、历史记录页。对,其实chrome单词的原意就是这个。

  • Clound_Print,谷歌云打印相关,提供谷歌浏览器页面预览打印清单。

  • Courgetter,谷歌提供的二进制文件对比核心算法,用于比较不同版本的二进制差异。谷歌为了方便升级,搞了套升级策略和算法。

  • 神奇的syzygy优化。是的,谷歌也嫌chrome太大了、加载太慢了。于是他们开发了一套工具链,优化重排布PE二进制文件的算法来达到优化程序。

    Chrome浏览器应用了Syzygy优化之后,程序冷启动的页面调度(paging traffic)优化了80%,加载的Image的Working Set优化了40%。

    简单的说,谷歌为了优化启动性能,从编译器上对exe、dll开始做手脚了。

  • Media,Chrome的多媒体模块,支持音频播放和录音等功能。

    这里用到了ffmpeg。

    但在ffmpeg外,为了和blink配合,又是包裹了厚厚的一层,用来处理好渲染管线。另外MSE API也花了不少功夫。

  • swiftshader。很有趣的一个模块,用纯软件的代码,完整实现了opengl的接口。

    可以在没有硬件加速的机器上跑起opengl。

    这也是个庞大的库,而且也是被收购的。

    看起来谷歌对图形学方面的很多工程似乎不擅长?

    还不是想觉得应该交给更专业的团队去做。

  • gn、gyp、ninja。chromium为了更方便的管理编译,自己撸了三套轮子。

    类似makefile、cmake,然后底层调用ninja再到vs或者clang负责具体编译

其他的点还有很多很多,以后想到了再补充。

总之,以上随意一个点,要正确的实现,都是一个团队的工作量,都可以写成一本书。

90c6f0bde708c20a731f5f9a6e2c1004.png

然而chromium把他们全部实现了,而且还在不停的加入新的功能。

看到这里,大家应该明白为啥强如微软,也放弃维护他们自己的浏览器内核了。

因为需要投入的人力财力实在是太恐怖了。

chromium团队,光是开发人员,都已经上千了。

假如每个人员年薪是100w 人民币,持续投入十年,这个支出就是几十亿,这还不算周边的测试、产品、UI。

最关键的是,就算微软愿意投入十亿,能保证做到chromium相同的功能吗?

就算能做到相同的功能,还不是另外一套chromium,能做出其他优势吗?

于是最后微软也放弃了,干脆直接从开源的chromium上改起,把微软需要的功能融入chromium。

所以,chromium的霸权就是这么来的。看似开源免费,实则把所有开发者和对手,紧紧的捆绑在自己周围。

好了,现在吐槽开始了。

17c9b67afb6e0e953782a9dbcde39965.png

chromium称霸浏览器界以来,看起来开源,谁都可以拿去改。

然而比起它的前辈,我觉得从“道德”上,chromium要“差”很多。

最让我受不了的一点是,chromium在无尽的往里面塞功能的时候,很少想过是否别人可以轻易的移除它们。

chromium代码号称模块化、高内聚低耦合,然而如果你想砍掉一些不需要的东西,对不起,没有宏控制,手动删代码吧。

有几个人能有精力一点点的去掉里面这些繁琐的功能呢?

这就导致一个问题,需要chromium某一部分功能的人,必须被强塞进一堆谷歌认为你需要的东西。

对比之下,为啥我说比起chromium的前辈要差很多呢,其实我指的正是webkit。

webkit最让人欣赏的一点就是它在专注实现内核的同时,大部分功能都是可“拆卸”的。

有宏可以关闭。甚至连svg这种排版上的小功能都有宏可以关闭。

9ece9a87385f886bfb5ce2e9d525a2b8.png

而chromium,

如果我需要排版、音视频,但不需要多进程呢?

如果我需要音视频但不需要webrtc呢?

对不起,谷歌没这考虑。

要带就全都带上吧,不带你自己砍代码吧。

等你辛苦几个星期砍完代码,谷歌告诉你,我都更新了2、3个版本啦,你要不要更新下代码?哦?新版本chromium架构又大改了?哭了……

这也就造成现在基于chromium的一堆开发框架,如electron、cef、nwjs,全都动不动100多M的大小。

因为从chromium的框架设计上,就很难把那些极其庞大复杂的细节功能排除掉。

这些功能对于谷歌作为一个浏览器来说,当然是必要的。

然而回到本问题,“浏览器内核”真的需要这么复杂吗?浏览器需要这么复杂,这是真的;

然而作为一个浏览器内核提供给一些sdk给别人用,也需要这么复杂吗?

我们用electron写一套进供销管理系统的客户端,你会需要带上几十M的webrtc、webgl、多媒体播放、天城文支持吗?

最后打破这个疑问的,是我很多年后进入了QQ浏览器的移动端组(其实就是x5内核,微信上被大家吐槽最多的那个)。

当年的x5内核其实是基于webkit改造的。

从chromium回到webkit,我突然有种豁然开朗的感觉。

回到问题开头,从浏览器内核的角度,其实没那么复杂,只要做好网络、排版、渲染,就足以应付大部分使用场景了。

这让我想起浏览器早期年代,群雄争霸的时代,那时候浏览器内核很小。

从几百K到几M的浏览器都有。

我记得早年的移动设备上跑的浏览器,css支持的都不好,不过特别小巧,有的才几百K而已。

然而后来组里架构调整,x5内核为了跟上时代,从webkit最终还是切回了chromium。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值