基于Webkit的网站加载过程监控系统的设计*
2013-08-09仲晓廖建新
仲晓,廖建新
(1 北京邮电大学网络与交换技术国家重点实验室,北京 100876;2 东信北邮信息技术有限公司,北京 100191)
1 引言
随着互联网的快速发展和Web应用的迅速增多,越来越多的Web服务被发布到互联网上。网站信息的海量增长,给人们的生活和工作带来了极大的便利,但网页的代码量及网页中图像、视频、动态代码等元素的增加,导致了网站加载时间变长,网页的浏览速度变慢,影响了用户的上网体验,从而降低了网站的访问量。
对于网站的开发商而言,提升网站的加载速度是非常有必要的,这不仅有利于优化搜索排名和降低运营成本,同时也能极大的提高用户的体验度。
浏览器加载一个网站,可以分为以下几个步骤:域名解析、TCP连接、上传请求、等待响应、HTML文档下载、HTML文档解析、页面资源下载。本文基于Webkit开源浏览器内核来模拟浏览器加载网站的过程,在分析Webkit的基础上,重点讨论Webkit加载页面的过程及信息的获取。
2 Webkit系统分析
Webkit是开源的浏览器引擎,其内核高效稳定、兼容性好,源代码清晰,便于维护,Apple的Safari、Google的Chrome都是基于Webkit内核开发的,并且iPhone和Android手机系统中的浏览器也是使用Webkit作为浏览器内核。
2.1 Webkit框架
Webkit的层次框架如图 1所示,分为3个层次:Webkit、WebCore和 JavaScriptCore,Webkit层主要是与操作系统的交互;WebCore层是Webkit的核心,包括页面渲染、布局、绘制、DOM绑定等功能;JavaScriptCore层包括JavaScript Engine和JavaScript脚本的执行。
图1 Webkit层次框架
2.2 Webkit加载网页
Webkit浏览器内核的功能主要包括:加载、文档解析、渲染、Style解析、布局、Script执行等。
加载是获取资源数据,包括页面加载和页面所包含资源的加载。页面加载主要由FrameLoader完成,资源的加载是由DocLoader和Cache完成,页面和资源都是用CachedResource表示,可以分为RawResource、Image、Font、Script、SVGDocument等几种资源类型。
文档解析是根据HTML或XML文档结构构建DOM树,DOM树用来描述页面的结构,节点包括Element Node、Attribute Node、CSS Style Sheets。
渲染阶段是创建Render树,在文档解析时,每增加一个DOM节点,都会调用Node类的attach方法,计算该节点style属性中display值,如果非“none”,则创建该节点的Render对象,并添加到Render树中。Render树中包含所有需要在窗口中绘制的信息,并且Render树属于DOM树。
Style解析是构建RenderStyle树,Node::attach方法中将计算结点的Style信息,添加到树中,RenderStyle树中包含CSS Style信息,并且RenderObject共享Style。
在为节点的Render对象添加到Render树时,这些对象中没有位置和大小信息,将通过执行Render::layout方法,实现对节点的布局操作。
JavaScript引擎通过扫描JavaScript源码,构建语法树,然后通过函数调用触发语法树求值。在JavaScript执行过程中,通过修改DOM树来修改文档的结构和结点的属性,并且同时反映到Render树中。
2.3 HTTP请求流程
Webkit通过WebCore和JavaScriptCore处理下载的内容,并进行文本、图片等元素的显示及JavaScript脚本的执行。一个HTTP请求在Webkit中处理的流程如下:
(1)首先进行主页面加载,Webkit将主页面的加载请求经过Webkit引擎的内部封装成CFURLRequestRef,交由Webkit引擎和底层网络库的接口ResourceHandle,进行资源的下载过程;
(2)Win32平 台 使 用 的 是CFNetwork网 络库,通过调用网络库的异步函数实现资源的下载,ResourceHandle是Webkit引擎和网络库的接口,通过调用ResourceHandle::start()来发起网络请求,当网络事件到达时,将调用注册的回调函数:
willSendRequest(CFURLConnectionRef,CFURLRequestRef, CFURLResponseRef, const void*):在发送请求之前调用,对发送的请求进行预处理;
didReceiveResponse(CFURLConnectionRef,CFURLResponseRef, const void*):收到来自服务器返回的响应时调用,主要处理接收到的HTTP响应头,如,对状态码为“304 Not Modified”资源的请求,直接从Cache中获得资源信息;
ata(CFURLConnectionRef,CFDataRef, CFIndex, const void*):收到服务器发送的数据时调用,对于主页面资源,将对接收到的HTML文本进行解析,构建DOM树、Render树等,并且在解析过程中伴随着对图片、脚本文件等其他资源的加载及解析得到的脚本片段的执行过程;
didFinishLoading(CFURLConnectionRef, const void*):服务器对请求的响应结束时调用,此时客户端已接收到服务器返回的所有数据。
(3)在HTML解析过程中,DOM将HTML文本解析成DOM树,如果请求的页面中包含图片、脚本等资源时,将同样通过ResourceHandle::start()发送对应的网络请求进行资源的下载;
(4)如果接收到JavaScript脚本或者解析到嵌入在HTML文件中的JavaScript脚本,将交由JavaScriptCore执行,并且在执行过程中对DOM树进行完善;
(5)最后通过布局管理器分析HTML中可视元素的高度、宽度和位置等信息,进行布局排版,具有CSS样式的元素通过CSS解析器进行解析,最后通过Rendering显示给用户。
3 监控系统设计
基于Webkit对HTTP请求的处理过程,网站加载过程监控系统主要由两部分组成:加载过程监控和数据存储。加载过程的监控是模拟浏览器请求HTTP页面,记录页面加载的过程各个阶段所用的时间,构成一个页面的加载过程记录;数据存储将加载过程监控产生的加载过程记录组织并存放到数据库中。
3.1 数据存储部分
网站加载过程的监控主要需要两个数据表,一个是记录需要进行监控的网站信息表monitor_item_info,另一个是存储监控所得到的结果表monitor_result。监控信息表和监控结果记录表的结构如图 2所示。
图2 monitor_item_info和monitor_result 结构图
(1) 监控信息表monitor_item_info:
item_id记录项目ID,是表的主键;
item_info记录监控项目的描述信息,允许为空;
url记录监控对象的URL地址;
gap记录监控时间间隔,表示项目监控的周期,单位是min,默认值5min。
(2) 监控结果记录表monitor_result:
operation_id记录监控项目一次监控操作的ID;
resource_no记录监控结果对应的资源在本次监控操作中的内部序号,(operation_id,resource_no)作为主键;
item_id记录监控结果属于的监控项目ID,对应monitor_item_info中的item_id;
url记录资源对应的url地址;
start_time记录本次监控操作开始时间戳;
stop_time记录本次监控操作结束时间戳;
type记录监控资源的类型,资源的类型分为:main、image、script、cssstyle、link、font、other;
send_request_time记录向服务器发送资源请求的时间戳;
receive_response_time记录从服务器接收到响应的时间戳;
finish_download_time记录从服务器下载到所有资源的时间戳;
如HTML在下载过程需要交由解析器进行解析,JavaScript脚本在下载过程需交由JavaScript Engine执行,process_start_time记录处理开始时间,process_end_time记录处理结束时间;
在资源下载过程中可能会需要经过多次服务器下载操作,data_download_times记录资源数据下载次数;
data_size记录资源数据总字节数;
error_id记录当前监控结果的错误类型,0表示无错误。
图3 主要类图
代码中定义类MonitorItemInfo用来表示一个资源的信息,MonitorResult用来表示一个资源加载结果的信息,类中各个字段分别与表monitor_item_info和表monitor_result的相应字段对应,并且定义类MonitorResultStore用来将监控结果存放到数据库中,如图 3所示。
其中方法MonitorResultStore::addMonitorResult(MonitorResult*)将监控结果保存到m_monitorResult List中,然后线程m_monitorResultStoreThread定时将结果存储到数据库中。
3.2 加载过程监控部分
根据2.2节中关于HTTP请求流程的分析,在HTTP请求的过程中记录加载过程所得到的监控结果信息。具体过程如下:方法CachedResource Lo ader::requestResource(CachedResource::Ty pe, CachedResourceRequest&)中 根 据Cached Resource::Type得到请求资源的类型,根据CachedResourceRequest得到请求资源的url;方法willSendRequest在发送请求时调用,并记录了变量m_sendRequestTime;方法didReceiveResponse在接收到服务器响应时调用,记录了变量m_receiveResponse Time,并且根据响应信息得到HTTP响应的状态码,并判断是否发生错误;方法didReceiveData中累计从服务器下载的数据大小m_dataSize和调用次数m_downloadDataTimes;方法didFinishLoading在数据全部下载完毕时调用,记录m_finishDownload Time;HTML文件和Java Script脚本的执行,在解析完毕或者脚本执行完毕时记录m_processTime,其他资源的m_processTime设为0。每次资源加载完毕之后,将得到的结果MonitorResult通 过MonitorResultStore保存到数据库中。
4 结束语
本文对Webkit浏览器内核的页面加载和HTTP请求处理流程等技术进行了研究和分析,设计并实现了基于Webkit浏览器内核的网站加载过程的监控系统,能够通过模拟浏览器来监控网站的加载过程。根据监控系统得到的结果进行分析,可得到网站在加载过程中的瓶颈,有利于改善网站的性能。本系统目前只是模拟了基于Webkit内核的浏览器加载页面的过程,其他浏览器内核的加载过程有待研究。
[1] Webkit. The Webkit Open Project[EB/OL].http://www.Webkit.org/.
[2] 赵经纬, 周余, 王自强等. 基于Webkit的嵌入式浏览器的研究与实现[J]. 电子测量技术, 2009,32(3):135-138.
[3] 倪建新. 基于Webkit的嵌入式浏览器关键技术研究与实现[J].智能计算机与应用, 2011,01(6):47-48,51.
[4] 谢立丹, 陈榕. 基于Elastos的Webkit引擎的研究与移植[J]. 计算机技术与发展,2011,21(1):12-15.
[5] 张光辉, 刘清梅, 李武等. 基于实时监控的网站反篡改系统设计[J]. 价值工程,2012,31(4):133-134.