本文轉自:https://blog.csdn.net/itest_2016/article/details/80048398css
Angular是一個比較完善的前端MVC框架,包含了模板,數據雙向綁定,路由,服務,過濾器,依賴注入等等全部的功能。在Web開發先後端流行的今天,咱們在某個項目中也嘗試使用該框架。前端
很快按照官網上的例子搭建了一個標準工程,在項目初期工程文件不是不少的時候,編譯、打包、而後運行,訪問項目的各個頁面都很快。和傳統的模板引擎相比這種先後端分離不只工程化更加成熟(前端、後端開發人員專一本身的領域),並且各個頁面加載速度很快,但是說第一次嚐到了這種先後端徹底分離所帶來的好處。但漸漸的咱們發現了一個問題,就是首頁加載速度愈來愈慢了以下圖:nginx
耗時居然已經達到了10s,但進入首頁後各個頁面加載速度依然很快。這時候就不得不分析緣由了,其實答案很明顯,有2個文件特別大分別是:main.bundle.js(2.3M)、vendor.bundle.js(4M)。並且這2個文件在第一次訪問時必須會加載,爲何進入後訪問就很快了?進一步分析,看看編譯後這2個文件的源碼,就能發現main. bundle .js是把咱們全部模塊本身編寫的js都打包到一塊了,而後vendor.bundle.js包含了angular的公共庫。這樣隨着咱們編寫的js代碼愈來愈多,引用的公共庫愈來愈多的時候,頁面的加載速度就會愈來愈慢。因爲瀏覽器自己會緩存這些靜態資源文件,而全部的文件都在第一次訪問頁面的時候都加載了,這樣就致使第一次訪問特別慢,後續各個頁面都很快的奇怪現象。web
咱們傳統web開發時css、js文件,有一個全局和各個模塊單獨這樣劃分的。這樣等到須要的時候在加載對應css、js文件,加載時間被分攤到各個頁面因此就不會出現某個頁面加載慢的現象。其實能夠類比,在angular中也有相似的優化方法。多模塊懶加載即可以達到咱們說的這種效果。後端
優化前咱們工程就一個主模塊文件(app.module.ts),路由跳轉各頁面其實都屬於該模塊一部分瀏覽器
以下圖(路由對應各頁面其實都是子組件,因此編譯時都會被打包到同一個文件):緩存
進行多模塊拆分後以下圖:tomcat
能夠看到寫法明顯不一樣,每一個路由頁面其實都是一個單獨模塊,而後在編譯時每一個模塊都會單獨編譯成一個文件。並且路由到某個頁面時,纔會加載該模塊js文件。app
多模塊拆分以前,編譯以下圖:框架
拆分後:
關注main.bundle.js文件變成了605kb,而後多了不少chunk.js。這些chunk.js其實就是各個模塊編譯文件。
具體進行多模塊拆分方法以下:
【step1】在工程src/app 目錄下新建2個文件,root.module.ts、share.module.ts。
在root.module.ts放一些其它全部模塊都要引用的component、service、pipe。對於service須要在providers中對外暴露,其它公共組件、模塊在exports中暴露(注意:相同組件、模塊不能在多個模塊中重複引用,不然編譯會報錯,能夠經過以下方法對外暴露一次)
而後在share.module.ts模塊中import root.module.ts。此外該模塊會存放一些公共component、service、pipe等會被除了app.module.ts在外其它模塊引用。這樣作的目地是減小app.module.ts引用公共庫大小,在上面編譯圖中能夠發現vendor.bundle.js文件也很是大,這樣作的目的是減小該文件的大小(此處大概能優化個10%)。
【step2】
對各個路由模塊作以下改造:
以job-record模塊爲例,以下圖:
改造前:
改造後:
能夠明顯看到增長了2個新文件,job-record-routing.module.ts、job-record.module.ts。這2個文件的用途就是把job-record變成一個真正的子模塊。
job-record-routing.module.ts內容以下(該模塊路由配置):
job-record.module.ts內容以下(具體模塊配置):
job-record目錄下其它文件無須修改,對應其它頁面都用相似方法作模塊拆分。(注意:對於父子頁面,因爲子頁面依賴父頁面加載,因此不能這樣作拆分。)
【step3】
app.module.ts作以下改下(和原來該模塊編寫方式對比提到)
進行了多模塊拆分後發現,main.bundle.js文件確實變小了不少,已經達到咱們預期,並且也不會隨着咱們本身編寫js增長而愈來愈大了,這時候發現首頁訪問速度大概加快了30%。此時加載速度以下:
但仍是很慢,幾乎還須要5s時間,緣由是vendor.bundle.js文件仍是很大。
vendor.bundle.js都是angular自己依賴的一些公共庫,不是咱們本身編寫的,因此剛剛的多模塊優化對它的大小變化幾乎沒有影響。這是打開該文件能夠看到明顯沒有通過壓縮優化。查了一些官網文檔和百度發現angular編譯果真有優化方式。經過增長編譯參數:--prod –aot
編譯後發現,居然報了一堆錯誤。不過不要驚慌,那是優化編譯時對ts語法檢查比較嚴謹,咱們代碼中不少地方寫的不夠嚴謹,只能硬着頭皮一行行修改了,此外別無它法。
好不容易解決了上面優化報錯地方。這時優化編譯也過了,而後首頁加載速度也是很是快了。但是訪問其它頁面時會報以下錯誤:
進一步分析是代碼種以下地方報錯(壓縮後的)
原始報錯代碼位置以下圖。
但仔細分析了此處代碼,沒有看錯有問題地方。結合上面報錯,進一步調試發現map相關代碼在優化時被壓縮沒了天然報錯,咱們優化編譯方式都是官方的,並且此處代碼也並沒有問題,猜測多是該模塊沒有顯示引入。引入以下模塊:
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
優化編譯後發現問題果真解決了,如今首頁訪問速度提高了,各個頁面訪問也沒有問題了(若是發現通過優化編譯後,還會有其它相似問題,那麼極可能就是某些依賴模塊沒有顯示引入致使)。
優化後首頁加載速度以下圖:
最後部署在正式環境如nginx或tomcat下經過開啓gzip壓縮會發現靜態文件大小還會進一步變小,頁面訪問速度還會提高。