由於angular中使用了大量自訂標籤,所有會在瀏覽器端做很多的計算工作,有沒有一種工具可以將這件事情在發布前先編譯好,這樣就可以避免大部分瀏覽器的計算工作,有這樣的工具嗎?
某草草2017-05-15 16:52:43
其實這是一個很大的話題,不過我不打算在這裡展開講,因為太費勁了──要搞清楚這裡面的全部細節,只懂 Angular 是不夠的。
重點概述我就說兩點:
模板的預編譯不難(此處指的是把靜態的模版緩存至 $templateCache
,从而在应用加载的时候直接把模版载入内存),但是对 Angular 这样重度依赖数据绑定的框架来说,编译模版那点工作量不值一提。除非说你的项目无比庞大,模版多的管理不过来——但此时更严重的是本地开发时模版预编译的时间损耗——所以把巨型应用模块化分割才是正途;这就有点跑题了。像 ng-repeat
这类的指令会是我们想“减轻浏览器负担”的目标,也就是在浏览器载入之前就把此类指令展开,填充 DOM;而像 ng-if
這類的指令則不能預先處理,因為它們很多時候都依賴「資料綁定」。
我給你舉個例子,比如說頁面上有一個部分由 ng-if
控制,根据当前用户是否有权限来判断,但是是否有权限这个状态必须得等用户登录(或者别的预置条件)之后才能获取到——我们要如何在浏览器之外预处理 ng-if
?它会涉及到 DOM 操作,它也会影响到浏览器性能,你说是预处理还是不预处理?如果所有这样的标签都要作一番权衡才能决定是否预处理,那这个代价也太大了,不如不用 Angular。Angular 做不到完全的静态化(顺便一提,ESNext 的 Object.observe()
將是解決的鑰匙),而半靜態化則是可以的,但往往不是因為瀏覽器性能的緣故。
實際上你要相信現代瀏覽器的性能是很強的,客戶端渲染並非很多人想像中的“性能瓶頸”,很多在服務端渲染的嘗試(對於Angular 來說)反而主要是為了搜索引擎優化而不是性能提升。我給你一些關鍵字去研究吧,這是一個學習的好機會(用英文搜尋引擎,中文的沒什麼有用的結果):
總結一下。對於基於「資料綁定」為主的JS 應用來說(如Angular),由於目前語言與環境層面的支援還不到位(如前面提到的Object.observe()
等),因而無法在DOM 層面實現完整的預編譯或靜態化。在進入瀏覽器之前,透過其他方式預處理部分DOM 是可能的,但是對應用的整體性能提升或/及瀏覽器的性能提升並沒有天差地別的影響,並且實現這些預處理本身的代價並不小;除非你是做對性能嚴苛至極的應用(例如淘寶這樣的?),否則還是斟酌而定吧。
ringa_lee2017-05-15 16:52:43
從搜尋引擎優化角度看,這麼做也是很有意義的。適合AngularJS 的現成工具有
prerender.io
angularjs-server
淘寶的中途島應該也是相近的出發點