席文強
摘 要 在眾多開源源瀏覽器引擎中,當(dāng)屬Webkit的代碼結(jié)構(gòu)框架較為清晰,因此對于webkit內(nèi)核源碼的研究顯得尤為基礎(chǔ)和重要。本文對webkit內(nèi)核工作運行中調(diào)用的幾個重要方法和模塊進行了分析,介紹了內(nèi)核加載模塊Loader、網(wǎng)頁解析模塊Parser和JScore模塊的運行流程和方法。
關(guān)鍵詞 WebKit;Javascriptcore;瀏覽器;網(wǎng)絡(luò)爬蟲
引言
Webkit是一個開源的Web瀏覽器引擎。對于一個完整的瀏覽器,需要能夠發(fā)出特定格式的HTTP請求,接收到響應(yīng)數(shù)據(jù)后解析,并將解析后的數(shù)據(jù)顯示的屏幕上。webkit僅僅關(guān)注頁面排版,對于網(wǎng)絡(luò)層和圖形界面等需要第三方庫的支持。webkit主體的實現(xiàn)不依賴于某種特定的庫,便于移植到各種環(huán)境中。
1Loader
Webkit在發(fā)起一個頁面請求時,首先會調(diào)用FrameLoader的load方法。FrameLoader對象是Frame的一個成員,負責(zé)頁面的加載。之后會調(diào)用到DocumentLoader的一些方法,顧名思義DocumentLoader是負責(zé)頁面中的文檔的加載的。這個過程中會檢查加載策略(PolicyChecker負責(zé)),并通過回調(diào)等方式調(diào)用FrameLoaderClient中的方法,這個類中的方法主要是與外層交互,如可以詢問用戶是否真的要加載[1]。
然后會調(diào)用DocumentLoader中的startLoadingMainResource,在這個方法里生成一個資源請求CachedResourceRequest,并調(diào)用CachedResourceLoader的requestMainResource方法。
為了節(jié)省在網(wǎng)絡(luò)加載上耗費的時間,webkit使用了cache機制,它會把請求的資源緩存在一個singleton類,MemoryCache中。所有加載請求都會先在其中查找是否已保存有這個資源,是的話會直接取出。CachedResourceLoader類的主要作用就是負責(zé)查找要請求的資源是否在MemoryCache中。如果不存在,會生成一個代表這個資源的CachedResource,將其加入MemoryCache,并調(diào)用它的loader方法。之后會到ResourceLoader這個資源加載類的start方法中,在ResourceHandle這個與底層網(wǎng)絡(luò)庫打交道的類中開始真正的網(wǎng)絡(luò)請求。
2Parser
這部分主要是拿到源碼后到dom樹的生成。在有數(shù)據(jù)到來時,會調(diào)用到網(wǎng)絡(luò)庫的回調(diào)函數(shù),里面又會調(diào)到ResourceLoader的didReceiveData方法,一級級將數(shù)據(jù)往上提交,到達DocumentWriter類。DocumentWriter類主要有兩個成員,分別是TextResourceDecoder和DocumentParser,前者負責(zé)對拿到的源碼根據(jù)需要解碼,后者負責(zé)dom樹的生成。HTMLDocumentParser又有兩個成員變量,HTMLTokenizer負責(zé)詞法分析,里面有一個重要的函數(shù)nextToken,維護著一個狀態(tài)機,不停的讀取字符并生成一個個token。另一個成員HTMLTreeBuilder,在constructTree方法里調(diào)用processToken方法處理上面生成的token,通過HTMLConstructionSite的createElement等方法生成Node節(jié)點后,再用insertHTMLElement等將Element插入生成dom樹[2]。
3Javascriptcore
Jscore要為webcore服務(wù),需要一層binding。jsbinding的作用可以理解為,對于一些內(nèi)置函數(shù),如document.write,它的實現(xiàn)在webcore內(nèi),但webcore不認識這些js語句中的函數(shù),所以需要jscore認出這些函數(shù),然后調(diào)用webcore中它的實現(xiàn)。在webkit編譯過程中,會自動生成一些代碼。對于每種webcore中的Node類型,會生成響應(yīng)的JSNode類型的定義,對于上述的接口,會通過表記錄映射關(guān)系,在jscore初始化的時候生成。
實時編譯JIT用來將頻繁使用的那些字節(jié)碼編譯成本地機器碼,然后棧上替換之前的字節(jié)碼,執(zhí)行本地碼。
參考文獻
[1] 段虎才,倪宏,鄧峰,等.WebKit內(nèi)核的嵌入式瀏覽器磁盤緩存方法[J]. 計算機工程與設(shè)計,2015(3):624-629.
[2] 劉慶平,任寰.一種基于Webkit內(nèi)核提供網(wǎng)頁瀏覽的方法及裝置[P]. 中國:CN102681850A,2012-9-19.