对于这次内核升级,我们花了很大的精力,也有很多感触。下面简单分享一下,希望与同行一起探讨。
为什么要基于Chromium做二次开发?
肯定会有很多人好奇,为什么国内的双核浏览器都是无一例外地基于 Chromium 开源项目做二次开发。其实,根本原因在于,以 Google 员工为主的 Chromium 团队在该项目上做了大量的技术创新。像 DNS Prefetch、SPDY、QUIC、预渲染、多进程架构、PPAPI、v8 JavaScript 引擎等都是很好的技术创新例子。
二次开发的策略使得能借助这些技术创新给用户带去更好的上网体验,同时又避免了“重新发明轮子”这种劳命伤财之事。
即便如此,我们团队对于二次开发的实施理念与其他厂商有着明显的差异。有的厂商只考虑国内市场,有的则考虑全球市场,所以我们在二次开发时还需要考虑语言本地化等诸多跨国因素。
为什么要快速跟进 Chromium 项目的发展?
我们团队将快速跟进 Chromium 项目的发展作为重要的技术开发战略。从用户层面来看,Chromium 每一个大版本的出现都会在性能、软件结构和安全上做优化,且会修复一些严重影响稳定性和安全性的缺陷,快速跟进其发展步伐意味着能让用户尽早享用到这些益 处。从技术层面来看,快速跟进也有极大的益处,在此列举四点:
第一点是能逐步提升软件的开发效率。由于 Chromium 项目的规模非常庞大,因此不断提升开发效率是该项目的一个永恒话题。为此,Chromium 团队一直致力于改善项目的编译效率问题。比如,在采用 Chromium M32 的时期,我们只能用 Visual Studio 2010 进行编译,当我们升级到了 Chromium M35,我们就完全采用 ninja 这一更高效的工具完成编译工作。
还有,现在我们全是采用 gyp 来实现跨平台的工程源文件管理,按 Chromium 团队的规划,今年年底会用更为高效的 gn 取代它,如果我们不能快速跟进就没有办法尽早分享这一好处。
第二点是有助于提高解决软件缺陷的效率。一旦发现 Chromium 的缺陷后,我们除了自己立即着手修复外,还会向 Chromium 社区报告缺陷,通过与开源社区协作的形式加速解决问题。如果内核版本不快速跟进的话,就会因为 Chromium 社区不理会老版本中的缺陷而无法获得他们的协助。
我们团队所修复的一些缺陷会通过告知解决方案或直接 upstream 的形式提交给 Chromium 开源社区。这不仅帮助社区解决了问题,更方便了我们下次的内核升级工作,因为如果不将这些代码提交到 Chromium 的代码库,下次升级到新版本做代码合并时就可能面临新的冲突点。
第三点有助于持续优化代码质量。Chromium 项目的每个新版本较前一个版本的代码变更量都很大,其中很重要的内容是对代码质量持续改善。假设一开始我们的软件设计是基于 Chromium 老版本中的技术方案的,当 Chromium 在新版本中对该技术方案进行了优化后,升级上去就意味着我们得调整原始设计以适应新的技术方案。这就迫使我们跟着 Chromium 的脚步对自身代码持续改善,一定程度上有助于避免“技术债”高筑。
第四点好处在于,通过快速跟进有助于帮助网站的建议者在他们的网站中尽早运用上新的技术。某种程度上这也是帮助推进新技术的普及。
尽管快速跟进 Chromium 的发展步伐能带来诸多好处,但并非每个厂商都能很好地实施这一技术开发战略。原因在于,快速跟进是需要从技术层面以出色的软件设计做保障。
比如,我们在 Chromium 的原生代码中做了超过 3600 处改动、增加了超过 2500 个文件,如果不通过出色的软件设计将这些变更与 Chromium 的原生代码做很好的解耦的话,那每一次内核升级对开发团队都会是一次灾难,因为工作量实在是太大了。
Chromium 35 的另一大飞跃是实现了图形界面的全面 Aura 化。Aura 是一个窗口管理框架,用于实现界面上的像按钮、滚动条和对话框等界面控件。在没有 Aura 之前, Chromium 针对每个操作系统都做了封装,然后上层应用直接建立在这个封装之上去构建,以便实现跨操作系统的功能。
有了 Aura 之后,Aura 被设计成跨操作系统的,上面的应用转而构建于 Aura 之上。更为重要的是 Aura 在软件设计上做了很大的简化,且实现了使用显卡的 GPU 对界面进行绘制。利用 GPU 进行绘制所带来的好处在于,我们可以在界面上高效地实现一些更炫的效果。
在快速跟进 Chromium 项目中我们走过的一些弯路
其实,在从事浏览器电脑版的开发历程中,我们也走了一些技术弯路。这些弯路,使我们非常苦逼的停留了一段时间,但也让我们实现了质的突破。在此我想分享几则:
首先,最大的一个弯路在于忽视 Chromium 的软件架构。结果使得工程师在修改代码和增加文件时很混乱,程序的可维护性很差。这一痛苦经历让团队深刻地认识到维护清晰的软件架构有多重要。目前整个团队在日常工作中都非常重视这一点,对这类问题的敏感度很高。
另一个弯路体现在我们之前的做事方法上。在进行软件功能开发时,工程师以前很容易一拿到需求就根据自己的理解立马上手开干,以至于做了不少“重新发 明轮子”的事。后来我们发现,开发新功能所需的不少基础模块 Chromium 中已有,于是我们在 UC 浏览器电脑版 1.0 版的开发过程中不断地将“自己发明的轮子”给去除,用 Chromium 项目中现成的取而代之。
我们团队现在养成的习惯是先看一看 Chromium 中是否存在可复用的部分,之后再干。这种做事方法表面上看起来慢了,因为要花时间去学习和研究,但长远看来利大于弊,除了通过该方法能不断加深对 Chromium 项目的熟悉外,所编写出的代码更容易升级至新内核。
最后我想分享的一个弯路是软件设计的解耦方法。我们以前所采用的解耦方法一是很难规范化,二是难以与 Chromium 的新内核进行合并。现在的解耦方法除了规范化很容易做到外,使得在合并代码过程中对于各冲突点总是存在“明亮的灯塔”在指引。
实际上,我们所采用的解耦方法很简单,用一句话总结是“无论在 Chromium 之上是增加、调整或去除功能,我们在代码层面总是做加法”。这句话不好理解,但我也只能透露到这个层面。
我的角色转变及对技术管理的一些看法
过去的日子,我个人也在这个项目上也完成了一些角色转变。我当初应聘阿里巴巴时,在简历上写的是希望将来成为互联网行业的技术专家,当时杨过面试我时问了一个问题——“如果需要你做管理怎么办?”我当时回答说:“只要能更大程度地发挥自己的作用就会考虑”。
加入淘宝浏览器团队之初,虽没有定义我的管理角色,但一开始我就有意识主动承担部分技术管理工作,只是当时给自己的定位是架构师。如今,我在团队中官方地正式承担管理责任,这完全是因为团队的需要,因为这能从更大层面发挥我的影响力。
技术管理工作有不少琐碎的事,使得工作时间被更多地碎片化了。在我看来,要做好基层技术管理工作必须对技术细节有很好的掌握,否则难以发挥管理效能。另外,只有了解技术细节,才能更好地理解工程师的开发工作,否则很容易犯那种一谈技术就说“这个实现起来很简单”的毛病。
对于我来说,掌握技术细节是了解和欣赏工程师的关键途径。最近我在做 Chromium M36 的内核升级工作时碰到一个问题,在解决它的过程中发现我们团队的小盘同学在之前己解决,而且他实现的技术方案极其简单,简单到只需注释掉 grit 工具中的一行代码就实现了一个很重要的功能。我一了解这一细节后,立马起身走到他的工位上,告诉他这个技术方案真的很精彩!
如果不是因为我关注技术细节,光从他最终只改了一行代码就很可能得出“这个实现很简单”这一结论,这种片面结论除了抹杀他在被后可能花了数小时研究最优方案的努力外,更让我失去了一次欣赏他的机会。
作为一名还算资深的工程师,我深深地知道真正能培养出好工程师的方法不是采用股票、工资就能实现,也不是给他们“打鸡血”,而是让他们在工作中体会 到成就感、在专业水准上不断有进步,从管理层面理解和欣赏他们是非常关键的一环。正因如此,我在整个开发团队中明确规定,基层技术管理者必须在工作中持续 地有技术贡献。
做技术管理最大的乐趣在于看到团队在不断地进步、感受到大家对自己的信任、听到自己的理念被他们用于讨论问题、看到自己的工作方法在发挥作用,这种 感觉真的很棒、很享受,一点都不比解决技术难题所带来的“爽”逊色。当然,过程中也会碰到困难和压力,但在这种相互欣赏与理解的团队氛围中能得到克服。
作为技术管理者,我认为身上最重的担子是责任。我衷心地希望工程师在这个团队中能不断地进步,这样在以后职业生涯中无论他们在哪一个团队都更具竞争 力。要实现这样的目标,一定需要技术管理者在工作中不断地为他们的成长提供环境和给予帮助,这也促使我在工作中不断地有所作为。