首頁  >  文章  >  web前端  >  再談前端HTML範本技術

再談前端HTML範本技術

不言
不言原創
2018-06-19 21:03:182026瀏覽

這篇文章介紹的內容是關於再談前端HTML模板技術,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

在web2.0之前,寫jsp的時候雖然有es和JSTL,但還是堅持jsp。後面在外包公司為了快速交貨,還是用了php Smart技術。

web2.0後,前端模板技術風行。

代表有以下三大類別:

String-based範本技術(基於字串的parse和compile過程)

DOM -based模板技術(基於Dom的link或compile過程)

Living template (基於字串的parse 和基於dom的compile過程)

# String-based templating

這是一種基於字串的模板技術,以字串和資料為輸入,透過用正規表示式將佔位符替換為所需資料的方式,建構出完整的HTML 字串。


String-based templating基本原理.png

字串範本引擎主要依賴這幾個dom API:createElement,appendChild,innerHTML。

在這些api中,innerHTML有最佳的可讀性與實用性,成為事實上的主要標準,雖然其他API可能在效能上更勝一籌,但原生js的字串產生方案中,最常用的還是innerHTML。

再談前端HTML範本技術

基於字串的模板引擎最大的功勞就是把你從大量的夾帶邏輯的字串拼接中解放出來了,由於它的完全基於字串的特性,它擁有一些無可取代的優勢。

It is essentially a way to address the need to populate an HTML view with data in a better way than having to write a big, ugly string concatenation expression.

  • #快速的初始化時間: 很多angular的簇擁護者在奚落String-based templating似乎遺漏了這一點。

  • 同構性: 完全的dom-independent,即可作為用伺服器端和瀏覽器端(客官先不要急著搬phantomjs哈).

  • 更強大的語法支援:因為它們都是不是自建DSL就是基於JavaScript語法,Parser的彈性與受限於HTML的Dom-based範本技術不可同日而語

由於基於字串的範本方法依賴innerHTML的渲染,所以會帶來以下問題。

  • 安全性問題:使用innerHTML 建構DOM具有安全隱患,用於渲染的動態資料可能存在安全漏洞,如果沒有經過特定的轉義處理,就有可能造成XSS攻擊或CSRF攻擊。

    因為innerHTML具有安全隱憂.,例如:,我知道像你這樣優秀的程式設計師不會寫出這樣的程式碼,但當html片段不完全由你來控制時(例如從遠端伺服器中),這會成為一個可能引爆的*。

  • 效能問題:使用innerHTML 取代DOM效率較低,即使僅取代DOM 的一個屬性或文字內容,也必須透過innerHTML 取代整個DOM ,從而導致瀏覽器的重排和重繪。

  • 開發效率問題:由於是透過正規表示式匹配後在特定函數中拼接字串,所以容易造成重複計算,而且完全移除現有的DOM,再重新渲染一遍,掛載在DOM 上的事件和狀態都將不復存

  • 有可能會創建出意料之外的節點:由於html的parser非常的“友好”, 以至於它接受並不規範的寫法,從而創建出意料之外的結構,而開發者得不到錯誤提示。

代表:

  • mustache及其衍生handlebar等: 弱邏輯

  • Dust.js: 強邏輯(推薦)

  • #doT.js: 超快速

DOM-based模板技術

這是一種基於DOM 節點的模板技術,透過innerHTML獲取初始DOM 結構,再透過DOM API層級從原始DOM 屬性中提取事件、指令、表達式和過濾器等資訊,編譯成LivingDOM,從而完成資料Model和View 的雙向綁定。 AngularJS就是 DOM-based模板技術的代表。

再談前端HTML範本技術

Dom-based的模板技術事實上並沒有完整的parse的過程(先拋開表達式不說),如果你需要從一段字符串創建出一個view,你必然通過innerHTML來獲得初始Dom結構.然後引擎會利用Dom API(attributes,getAttribute,firstChild… etc)層級的從這個原始Dom的屬性中提取指令、事件等信息,繼而完成數據與View的綁定,使其”活動化」。

所以Dom-based的模板技術比較像是資料與dom之間的「連結」與*「改寫」*過程。

注意,dom-based的模板技術不一定要使用innerHTML,例如所有模板都是寫在入口頁面中時, 但是此時parse過程仍然是瀏覽器所為。

DOM-based模板技術比String-based模板技術更加靈活,功能也更加強大,達到了一定意義上的資料驅動。

  • 是活動的完成compile之後,data與View仍然保持聯繫,即你可以不依賴與手動操作Dom API來更新View

  • 是執行階段高效率的可以實作局部更新

  • 指令等強大的附屬物幫助我們用宣告式的方式開發APP

但其存在以下問題:

  • #資訊冗餘:資訊承載於屬性中,這個其實是不必要且冗餘的。

    由於 DOM-based模板技術透過innerHTML 取得 DOM 編譯節點,資訊承載於屬性中,造成了不必要的冗餘,同時也會影響閱讀,提升開發難度。一種解決辦法就是透過讀取屬性後再進行刪除處理,諸如removeAttribute的方式移除它們,其實這個不一定必要,而且其實並無解決它們Dom強依賴的特性,還會影響性能,降低用戶體驗。

  • 初始節點取得問題:透過innerHTML取得初始節點,沒有獨立的語法解析器或詞法解析器,與 HTML是強依賴關係。初次進入 DOM 的內容是模板,渲染需要時間,所以會造成內容閃動——FOUC(Flash of unstyled content)這個無需多說了,只怪它初次進入dom的內容並不是最終想要的內容。

  • 沒有獨立的Parser,必須透過innerHTML(或首屏)來取得初始節點,即它的語法是強依賴與HTML,這也導致它有潛在的安全性問題

代表:

  • AngularJS: 都28000star了還需多說麼

  • #Knockout: 在此領域內,對Web前端而言是鼻祖級的

Livingtemplate技術

Livingtemplate技術與String-based、DOM-based模板技術的最大區別是不依賴innerHTML來渲染和提取所需資訊。其主要思想是:首先,結合資料綁定技術,使用成熟的詞法解析和語法解析

技術,將輸入的字串解析成抽象語法樹AST,而不是僅僅通過簡單的正則表達式匹配特定語法,再進行字串拼接;其次,透過對AST進行編譯,創建具有資料動態綁定功能的Living DOM,從而避免使用innerHTML,解決了瀏覽器的元素閃動問題,提高了應用的安全性,其原理如圖1所示。

Screen Shot 2018-04-19 at 18.38.17.png

從圖1可知,輸入的字串透過詞法解析器Lexer,產生對應的詞法區塊。詞法塊透過語法解析器 Parser,建構抽 象 語 法 樹 AST。然 後 將 AST編譯成具有動態資料綁定功能的LivingDOM,從而實現 View 和 Model的雙向綁定。

與Dom-based 模板技術利用Dom節點承載資訊不同的是,它的中間產物AST 承載了所有Compile過程中所需的資訊(語句, 指令, 屬性…等等). 

我們可以發現Living templating幾乎同時擁有String-based和Dom-based模板技術的優點

利用一個如字串模板的自訂DSL來描述結構來達到了語法上的靈活性,並在Parse後承載資訊(AST)。而在Compile階段,利用AST和Dom API來完成View的組裝,在組裝過程中,我們同樣可以引入Dom-based模板技術的諸如Directive等優良的種子。

living template's 近親—— React

React當然也可以稱之為一種模板解決方案,它同樣也巧妙規避了innerHTML,不過卻使用的是截然不同的策略:react使用一種virtual dom的技術,它也同樣基於髒檢查,不過與眾不同的是,它的髒檢查發生在view層面,即發生在virtual dom上,從而可以以較小的開銷來實現局部更新。

  • 輕量級, 在Dom中進行讀寫操作是低效率的.

  • 可重用的.

  • 可序列化, 你可以在本地或伺服器端預處理這個過程。

  • 安全, 因為安全性不需要innerHTML幫我們產生初始Dom

代表:

  • htmlbar: 運行在handlebar之後的二次編譯

  • #ractivejs: 獨立

  • Regularjs獨立

此文還需進一步整理,以及自訂範本引擎思考方向與工程實務內容補充。這方面需要下的功夫還是需要蠻多的,敬請期待。

本文轉載自原文:https://www.zhoulujun.cn/html/webfront/SGML/htmlBase/2018_0419_8098.html

相關推薦:

#一個簡單的HTML模板引擎

以上是再談前端HTML範本技術的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn