高性能JavaScript模板引擎原理解析

隨着 web 發展,前端應用變得愈來愈複雜,基於後端的 javascript(Node.js) 也開始嶄露頭角,此時 javascript 被寄予了更大的指望,與此同時 javascript MVC 思想也開始流行起來。javascript 模板引擎做爲數據與界面分離工做中最重要一環,愈來愈受開發者關注,近一年來在開源社區中更是百花齊放,在 Twitter、淘寶網、新浪微博、騰訊QQ空間、騰訊微博等大型網站中均能看到它們的身影。javascript

本文將用最簡單的示例代碼描述現有的 javascript 模板引擎的原理,包括新一代 javascript 模板引擎 artTemplate 的特性實現原理,歡迎共同探討。前端

artTemplate 介紹

artTemplate 是新一代 javascript 模板引擎,它採用預編譯方式讓性能有了質的飛躍,而且充分利用 javascript 引擎特性,使得其性能不管在前端仍是後端都有極其出色的表現。在 chrome 下渲染效率測試中分別是知名引擎 Mustache 與 micro tmpl 的 25 、 32 倍。java

速度對比

除了性能優點外,調試功能也值得一提。模板調試器能夠精肯定位到引起渲染錯誤的模板語句,解決了編寫模板過程當中沒法調試的痛苦,讓開發變得高效,也避免了由於單個模板出錯致使整個應用崩潰的狀況發生。git

artTemplate 這一切都在 1.7kb(gzip) 中實現!github

javascript 模板引擎基本原理

雖然每一個引擎從模板語法、語法解析、變量賦值、字符串拼接的實現方式各有所不一樣,但關鍵的渲染原理仍然是動態執行 javascript 字符串。web

關於動態執行 javascript 字符串,本文以一段模板代碼舉例:chrome

這是一段很是樸素的模板寫法,其中,」」 爲 closeTag (邏輯語句閉合標籤),若 openTag 後面緊跟 「=」 則會輸出變量的內容。後端

HTML語句與變量輸出語句被直接輸出,解析後的字符串相似:數組

語法分析完畢通常還會返回渲染方法:瀏覽器

渲染測試:

在上面 render 方法中,模板變量賦值採用了 with 語句,字符串拼接採用數組的 push 方法以提高在 IE六、7 下的性能,jQuery 做者 john 開發的微型模板引擎 tmpl 是這種方式的典型表明,參見: http://ejohn.org/blog/javascript-micro-templating/

由原理實現可見,傳統 javascript 模板引擎中留下兩個待解決的問題:

一、性能:模板引擎渲染的時候依賴 Function 構造器實現,Function 與 eval、setTimeout、setInterval 同樣,提供了使用文本訪問 javascript 解析引擎的方法,但這樣執行 javascript 的性能很是低下。

二、調試:因爲是動態執行字符串,若遇到錯誤調試器沒法捕獲錯誤源,致使模板 BUG 調試變得異常痛苦。在沒有進行容錯的引擎中,局部模板若由於數據異常甚至能夠致使整個應用崩潰,隨着模板的數目增長,維護成本將劇增。

artTemplate 高效的祕密

一、預編譯

在上述模板引擎實現原理中,由於要對模板變量進行賦值,因此每次渲染都須要動態編譯 javascript 字符串完成變量賦值。而 artTemplate 的編譯賦值過程倒是在渲染以前完成的,這種方式稱之爲「預編譯」。artTemplate 模板編譯器會根據一些簡單的規則提取好全部模板變量,聲明在渲染函數頭部,這個函數相似:

這個自動生成的函數就如同一個手工編寫的 javascript 函數同樣,同等的執行次數下不管 CPU 仍是內存佔用都有顯著減小,性能近乎極限。

值得一提的是:artTemplate 不少特性都基於預編譯實現,如沙箱規範與自定義語法等。

二、更快的字符串相加方式

不少人誤覺得數組 push 方法拼接字符串會比 += 快,要知道這僅僅是 IE6-8 的瀏覽器下。實測代表現代瀏覽器使用 += 會比數組 push 方法快,而在 v8 引擎中,使用 += 方式比數組拼接快 4.7 倍。因此 artTemplate 根據 javascript 引擎特性採用了兩種不一樣的字符串拼接方式。

artTemplate 調試模式原理

前端模板引擎不像後端模板引擎,它是動態解析,因此調試器沒法定位到錯誤行號,而 artTemplate 經過巧妙的方式讓模板調試器能夠精肯定位到引起渲染錯誤的模板語句,例如:

debug

artTemplate 支持兩種類型的錯誤捕獲,一是渲染錯誤(Render Error)與編譯錯誤(Syntax Error)。

一、渲染錯誤

渲染錯誤通常是由於模板數據錯誤或者變量錯誤產生的,渲染的時候只有遇到錯誤纔會進入調試模式從新編譯模板,而不會影響正常的模板執行效率。模板編譯器根據模板換行符記錄行號,編譯後的函數相似:

當執行過程遇到錯誤,立馬拋出異常模板對應的行號,模板調試器再根據行號反查模板對應的語句並打印到控制檯。

二、編譯錯誤

編譯錯誤通常是模板語法錯誤,如不合格的套嵌、未知語法等。因爲 artTemplate 沒有進行完整的詞法分析,故沒法肯定錯誤源所在的位置,只能對錯誤信息與源碼進行原文輸出,供開發者判斷。

開源節流

artTemplate 基於開源協議發佈,不管是商業公司仍是我的均可以避免費在項目中使用,歡迎共同完善。

下載地址:

https://github.com/aui/artTemplate

在線預覽:

http://aui.github.com/artTemplate/

相關文章
相關標籤/搜索