高效能JavaScript模板引擎原理解析
隨著 web 發展,前端應用變得越來越複雜,基於後端的 javascript(Node.js) 也開始嶄露頭角,此時 javascript 被寄予了更大的期望,與此同時 javascript MVC 思想也開始流行起來。javascript 模板引擎作為資料與介面分離工作中最重要一環,越來越受開發者關注,近一年來在開源社群中更是百花齊放,在 Twitter、淘寶網、新浪微博、騰訊QQ空間、騰訊微博等大型網站中均能看到它們的身影。
本文將用最簡單的示例程式碼描述現有的 javascript 模板引擎的原理,包括新一代 javascript 模板引擎 artTemplate 的特性實現原理,歡迎共同探討。
artTemplate 介紹
artTemplate 是新一代 javascript 模板引擎,它採用預編譯方式讓效能有了質的飛躍,並且充分利用 javascript 引擎特性,使得其效能無論在前端還是後端都有極其出色的表現。在 chrome 下渲染效率測試中分別是知名引擎 Mustache 與 micro tmpl 的 25 、 32 倍。
除了效能優勢外,除錯功能也值得一提。模板偵錯程式可以精確定位到引發渲染錯誤的模板語句,解決了編寫模板過程中無法除錯的痛苦,讓開發變得高效,也避免了因為單個模板出錯導致整個應用崩潰的情況發生。
artTemplate 這一切都在 1.7kb(gzip) 中實現!
javascript 模板引擎基本原理
雖然每個引擎從模板語法、語法解析、變數賦值、字串拼接的實現方式各有所不同,但關鍵的渲染原理仍然是動態執行 javascript 字串。
關於動態執行 javascript 字串,本文以一段模板程式碼舉例:
這是一段非常樸素的模板寫法,其中,”” 為 closeTag (邏輯語句閉合標籤),若 openTag 後面緊跟 “=” 則會輸出變數的內容。
HTML語句與變數輸出語句被直接輸出,解析後的字串類似:
語法分析完畢一般還會返回渲染方法:
渲染測試:
在上面 render 方法中,模板變數賦值採用了 with 語句,字串拼接採用陣列的 push 方法以提升在 IE6、7 下的效能,jQuery 作者 john 開發的微型模板引擎 tmpl 是這種方式的典型代表,參見: http://ejohn.org/blog/javascript-micro-templating/
由原理實現可見,傳統 javascript 模板引擎中留下兩個待解決的問題:
1、效能:模板引擎渲染的時候依賴 Function 構造器實現,Function 與 eval、setTimeout、setInterval 一樣,提供了使用文字訪問 javascript 解析引擎的方法,但這樣執行 javascript 的效能非常低下。
2、除錯:由於是動態執行字串,若遇到錯誤偵錯程式無法捕獲錯誤源,導致模板 BUG 除錯變得異常痛苦。在沒有進行容錯的引擎中,區域性模板若因為資料異常甚至可以導致整個應用崩潰,隨著模板的數目增加,維護成本將劇增。
artTemplate 高效的祕密
1、預編譯
在上述模板引擎實現原理中,因為要對模板變數進行賦值,所以每次渲染都需要動態編譯 javascript 字串完成變數賦值。而 artTemplate 的編譯賦值過程卻是在渲染之前完成的,這種方式稱之為“預編譯”。artTemplate 模板編譯器會根據一些簡單的規則提取好所有模板變數,宣告在渲染函式頭部,這個函式類似:
這個自動生成的函式就如同一個手工編寫的 javascript 函式一樣,同等的執行次數下無論 CPU 還是記憶體佔用都有顯著減少,效能近乎極限。
值得一提的是:artTemplate 很多特性都基於預編譯實現,如沙箱規範與自定義語法等。
2、更快的字串相加方式
很多人誤以為陣列 push 方法拼接字串會比 += 快,要知道這僅僅是 IE6-8 的瀏覽器下。實測表明現代瀏覽器使用 += 會比陣列 push 方法快,而在 v8 引擎中,使用 += 方式比陣列拼接快 4.7 倍。所以 artTemplate 根據 javascript 引擎特性採用了兩種不同的字串拼接方式。
artTemplate 除錯模式原理
前端模板引擎不像後端模板引擎,它是動態解析,所以偵錯程式無法定位到錯誤行號,而 artTemplate 通過巧妙的方式讓模板偵錯程式可以精確定位到引發渲染錯誤的模板語句,例如:
artTemplate 支援兩種型別的錯誤捕獲,一是渲染錯誤(Render Error)與編譯錯誤(Syntax Error)。
1、渲染錯誤
渲染錯誤一般是因為模板資料錯誤或者變數錯誤產生的,渲染的時候只有遇到錯誤才會進入除錯模式重新編譯模板,而不會影響正常的模板執行效率。模板編譯器根據模板換行符記錄行號,編譯後的函式類似:
當執行過程遇到錯誤,立馬丟擲異常模板對應的行號,模板偵錯程式再根據行號反查模板對應的語句並列印到控制檯。
2、編譯錯誤
編譯錯誤一般是模板語法錯誤,如不合格的套嵌、未知語法等。由於 artTemplate 沒有進行完整的詞法分析,故無法確定錯誤源所在的位置,只能對錯誤資訊與原始碼進行原文輸出,供開發者判斷。
開源節流
artTemplate 基於開源協議釋出,無論是商業公司還是個人都可以免費在專案中使用,歡迎共同完善。
下載地址:
線上預覽:
反饋: