由於angular中使用了大量自訂標(biāo)籤,所有會在瀏覽器端做很多的計算工作,有沒有一種工具可以將這件事情在發(fā)布前先編譯好,這樣就可以避免大部分瀏覽器的計算工作,有這樣的工具嗎?
其實這是一個很大的話題,不過我不打算在這裡展開講,因為太費勁了──要搞清楚這裡面的全部細節(jié),只懂 Angular 是不夠的。
重點概述我就說兩點:
模板的預(yù)編譯不難(此處指的是把靜態(tài)的模版緩存至 $templateCache
,從而在應(yīng)用加載的時候直接把模版載入內(nèi)存),但是對 Angular 這樣重度依賴數(shù)據(jù)綁定的框架來說,編譯模版那點工作量不值一提。除非說你的項目無比龐大,模版多的管理不過來——但此時更嚴(yán)重的是本地開發(fā)時模版預(yù)編譯的時間損耗——所以把巨型應(yīng)用模塊化分割才是正途;這就有點跑題了。像 ng-repeat
這類的指令會是我們想“減輕瀏覽器負擔(dān)”的目標(biāo),也就是在瀏覽器載入之前就把此類指令展開,填充 DOM;而像 ng-if
這類的指令則不能預(yù)先處理,因為它們很多時候都依賴「資料綁定」。
我給你舉個例子,比如說頁面上有一個部分由 ng-if
控制,根據(jù)當(dāng)前用戶是否有權(quán)限來判斷,但是是否有權(quán)限這個狀態(tài)必須得等用戶登錄(或者別的預(yù)置條件)之后才能獲取到——我們要如何在瀏覽器之外預(yù)處理 ng-if
?它會涉及到 DOM 操作,它也會影響到瀏覽器性能,你說是預(yù)處理還是不預(yù)處理?如果所有這樣的標(biāo)簽都要作一番權(quán)衡才能決定是否預(yù)處理,那這個代價也太大了,不如不用 Angular。Angular 做不到完全的靜態(tài)化(順便一提,ESNext 的 Object.observe()
將是解決的鑰匙),而半靜態(tài)化則是可以的,但往往不是因為瀏覽器性能的緣故。
實際上你要相信現(xiàn)代瀏覽器的性能是很強的,客戶端渲染並非很多人想像中的“性能瓶頸”,很多在服務(wù)端渲染的嘗試(對於Angular 來說)反而主要是為了搜索引擎優(yōu)化而不是性能提升。我給你一些關(guān)鍵字去研究吧,這是一個學(xué)習(xí)的好機會(用英文搜尋引擎,中文的沒什麼有用的結(jié)果):
總結(jié)一下。對於基於「資料綁定」為主的JS 應(yīng)用來說(如Angular),由於目前語言與環(huán)境層面的支援還不到位(如前面提到的Object.observe()
等),因而無法在DOM 層面實現(xiàn)完整的預(yù)編譯或靜態(tài)化。在進入瀏覽器之前,透過其他方式預(yù)處理部分DOM 是可能的,但是對應(yīng)用的整體性能提升或/及瀏覽器的性能提升並沒有天差地別的影響,並且實現(xiàn)這些預(yù)處理本身的代價並不小;除非你是做對性能嚴(yán)苛至極的應(yīng)用(例如淘寶這樣的?),否則還是斟酌而定吧。
從搜尋引擎優(yōu)化角度看,這麼做也是很有意義的。適合AngularJS 的現(xiàn)成工具有
prerender.io
angularjs-server
淘寶的中途島應(yīng)該也是相近的出發(fā)點