研究一个超级开源工程是一件极其有挑战的事情,把自己研究的过程文档化记录,也是一种能力的锻炼,希望同时也能帮到需要的人。此文档记录本人学习和研究firefox的过程,鉴于能力有限,其中必定存在错误和疏漏,欢迎指正。
目标
面对浩瀚如烟的源代码,怎样才算完全掌握。对于程序最高的要求就是从零可以手工完全实现出来,若是超级工程,个人显然不可能做到,面对千万行代码,完全读完也是一项旷日持久的任务,何况从零码出来。那么目标就改为对于bug能够手到擒来,新需求能够快速完成,可以任意重构代码,任意修改子模块或者孙模块。这是对于项目的总体的目标,也是一个很笼统的目标,定性的目标。
接着就要有具体的目标,或者说定量的目标,这里涉及到对程序的认识,自己开发程序是个正向工程,而学习别人的代码是个逆向工程。所谓正向是指首先开发是一个针对需求的任务,我们会据此来分析和设计怎么完成,选用什么开发工具,需要划分哪几个子模块,模块内的类图,关键处理流程等等。而逆向则不然,直接拿到的是一个成品实现,需要理解的是作者是怎么做的,为什么这么做的问题。话到这里就很明显了,需要整理出模块的关系图,模块内部的类图,流程图,UML里面那些状态图,序列图等等,反正只要能把怎么做描述清楚就行。给出这些就解决了怎么做的问题,然后再解决为什么这么做的问题,这个问题比较麻烦,因为一般这个问题涉及到比较,也就是肯定还有另一个做法,但是采用了现在的做法,主要是为了显示出现在这种做法的优点。在这里先不考虑为什么的问题,因为为什么涉及到更高的层次,连是什么都不知道是不可能解决为什么的。
方法
其实我的具体目标就是实现最终目标的方法,把每个子模块的设计文档整理出来,并完全消化理解。具体采用的方法那就多了去了,可以直接查看mozilla的开发者文档,可以去chat room向人请教,可以使用搜索引擎查找各种需要的资料,也可以使用调试器跟踪调试代码,还可以使用其他代码阅读工具例如source insight来阅读代码,总之只要是有效的方法均可以采用。我采用正逆向结合的方式,首先针对问题,自己思考给出一个实现方案,然后再研究作者的实现方案,这样结合起来分析。这里说明下,由于本人属于浏览器开发小白,自己的实现方案肯定是有问题的,只是为了加深学习。那么具体的文档需要整理成什么样子?整理出怎样的文档才算真正的理解和掌握了呢?细细思考了下,首先应该是该模块怎么用,可以用和外围模块的关系来描述,画出和外围模块的调用图即可,然后是模块内部的结构,这个主要是画出静态类图,最后的话把处理的流程画出来,有这三个方面的描述可以认为已经完全掌握了该模块。
现在开始思考问题,浏览器是什么?是用来浏览网页的一个程序。网页是什么?HTML文本文档。我们是怎么浏览网页的?输入网址,然后根据里面的链接访问。那么从输入一个网址开始后面浏览器到底做了什么?从DNS获取服务器IP地址,连接服务器获取html,解析html,渲染显示。这里的获取和解析html显然不仅仅是一个简单的html文件,应该是css,js,html的集合。这么考虑后可以认为浏览器包含的网络模块,可以分为两个部分,一个是与DNS通讯的,一个是与webserver通讯的。获取到数据后就是解析数据了,这里面会包括对css,js的解析,这个模块里面应该包括了spidermonkey,虽然相对于v8名气弱,不过研究透应该对自身提高有不少帮助。最后就是渲染了,在firefox里面模块貌似叫做gecko,代码应该是在layout目录中,我理解的渲染应该是提供什么drawtext,drawImage等等绘制方法的类。这块代码也需要好好研究,对于一个给定的html,firefox是怎么安排他们的位置大小的呢?我先按自己的想法来思考和学习,分为网络,数据解析,和渲染三个模块,然后再看源码是如何划分和处理的,后续会从网络开始入手分析研究。