AngularJS
User Group Taiwan
Angular 4 網站開發最佳實務
多奇數位創意有限公司
技術總監 黃保翕 ( Will 保哥 )
部落格:http://blog.miniasp.com/
AngularJS
User Group Taiwan
善用 VSCode 與 Angular CLI
https://github.com/angular/angular-cli/tree/1.3.x
AngularJS
User Group Taiwan
請認明 Will 保哥 出品
Angular Extension Pack 擴充套件
使用 Visual Studio Code 擴充套件
唯一推薦
AngularJS
User Group Taiwan
Angular Language Service
• 提供範本中所有必要的 IntelliSense 支援
angular2-switcher
• 快速鍵:Alt-o (快速切換於元件與範本之間)
• 快速鍵:F12 (移至定義) (可在範本中使用)
TypeScript Toolbox
• 建議設定: "genGetSet.spacedImportLine": true
Angular v4 TypeScript Snippets
• 大量的程式碼片段 for Angular, TypeScript 與 HTML
• 所有程式碼快捷鍵都是 a- 開頭
Angular Extension Pack 的亮點 1
AngularJS
User Group Taiwan
TSLint
• 記得將 tslint.autoFixOnSave 選項開啟 (超省時)
• 不用時可直接在 Settings 暫時關閉 TSLint 檢查
Auto Rename Tag
• 自動幫你修改頭尾的 HTML 標籤 (但有時候會出錯)
JSON to TS
• 快速鍵:Ctrl-Alt-V (轉換剪貼簿 JSON 定義)
• 快速鍵:Ctrl-Alt-S (轉換選取的 JSON 定義)
Document This
• 連按 Ctrl+Alt+D 兩次就會產生註解範本!
Angular Extension Pack 的亮點 2
AngularJS
User Group Taiwan
https://angular.io/guide/styleguide
• 每個檔案只放一個元件
• 每個檔案不超過 400 行,每個函式不超過 75 行
• 命名不要用 dash 也不要偷懶用縮寫
• ……
有空就認真看一遍
沒空就用 Angular CLI
• ng generate 產生程式碼骨架
• ng lint 檢查程式碼撰寫風格 ( codelyzer )
遵循 Angular Style Guide 指引方針
AngularJS
User Group Taiwan
更新全域 npm
• npm install -g @angular/cli
更新專案 npm
• npm install @angular/cli --save-dev
• rimraf node_modules package-lock.json
• npm install
也盡量使用最新版的 Angular 套件!
• 用上述升級 Angular CLI 的步驟就會自動升版
使用最新版的 Angular CLI 命令列工具
AngularJS
User Group Taiwan
樣板 指令 Alias 用法
Module ng g m my-module
Component ng g c my-new-component
Directive ng g d my-new-directive
Service ng g s my-new-service
Pipe ng g p my-new-pipe
Guard ng g g my-new-guard
Enum ng g e my-new-enum
Interface ng g i my-new-interface
Class ng g cl my-new-class
使用 Alias 快速建立元件
AngularJS
User Group Taiwan
--build-optimizer (Angular Build Optimizer)
• 可大幅減少 Bundle 後的檔案大小 (專案越大越明顯)
• 目前為實驗性功能 (需額外加上 --build-optimizer 選項)
• 建置過程會比 --prod 多出一倍時間
--named-chunks feat(@angular/cli): name lazy
• 讓延遲載入的子路由模組可用「模組名稱」當成檔名
• 預設在 dev 環境就是啟用的
• 這是 webpack v2.4.0 的新功能
關於 --dev 與 --prod builds 的預設值
• --dev vs --prod builds
體驗最新最酷的建置功能 ( ng build )
AngularJS
User Group Taiwan
ng build 與 ng build --prod
AngularJS
User Group Taiwan
ng build -prod --build-optimizer
AngularJS
User Group Taiwan
Angular 官網加上 --build-optimizer
AngularJS
User Group Taiwan
ng build -prod --named-chunks
AngularJS
User Group Taiwan
網站伺服器都會壓縮靜態檔案
( gzip / deflate )
實際下載大小會比看見的小很多
AngularJS
User Group Taiwan
安裝 source-map-explorer 工具
• npm install -g source-map-explorer
分析透過 webpack 打包過的檔案
• ng build
• source-map-explorer dist/vendor*.js
• ng build -prod -sm
• source-map-explorer dist/vendor*.js
• ng build -prod -sm --build-optimizer
• source-map-explorer dist/vendor*.js
分析 Bundle 過的原始碼
AngularJS
User Group Taiwan
效能調校 Angular 應用程式
Performance Optimization
AngularJS
User Group Taiwan
Angular 應用程式是由元件組成的
每一個元件裡儲存著許多內部狀態 ( 狀態就是屬性 )
內部狀態可以是任何類型的物件 (原始型別/物件型別)
元件的內部狀態經常與網頁的 使用者介面 (View) 相關
關於 Angular 應用程式狀態
AngularJS
User Group Taiwan
先獲取應用程式內部狀態
判斷出應用程式狀態是否發生變更
將新的應用程式內部狀態反應到 View 上
在瀏覽器中就是將應用程式狀態反映到 DOM 物件上
變更偵測的基本任務
AngularJS
User Group Taiwan
常見的狀態變更原因
• DOM 事件 - click, change, input, …
• XMLHttpRequest - 從遠端伺服器抓取資料
• Timers - setTimeout(), setInterval()
這些都是 非同步操作 (async)
每當非同步操作執行完成,應用程式狀態就可能發生改變
此時就需要通知 View 更新 (DOM Update)
觸發變更偵測的情境
AngularJS
User Group Taiwan
每個元件都可以定義自己的變更偵測策略
• ChangeDetectionStrategy.Default
• 變更偵測會在每一次非同步事件發生時執行
• ChangeDetectionStrategy.OnPush
• 變更偵測會在當元件中有 @Input() 屬性資料變更時執行
每次變更偵測作業都會從根元件開始執行
關於 Angular 的變更偵測策略
AngularJS
User Group Taiwan
變更偵測樹 (Change Detection Tree)
AngularJS
User Group Taiwan
ChangeDetectionStrategy.Default
AngularJS
User Group Taiwan
ChangeDetectionStrategy.OnPush
AngularJS
User Group Taiwan
元件中的 @Input() 屬性有變更才會進行變更偵測
若屬性參考沒有任何改變,則會跳過變更偵測
包含所有子元件都會跳過變更偵測
多利用 OnPush 變更偵測策略
AngularJS
User Group Taiwan
http://bit.ly/stackblitz-angular-debug
避免在 Angular 範本中執行函式 (包含 getter 函式)
• {{ debug() }}
• 計算 Angular Expression 的執行次數
• 實驗 document.onmousemove 如何影響效能
正式環境記得呼叫 enableProdMode(); 函式
• 變更偵測次數會從 2 降到 1 (效能提升)
計算變更偵測次數
AngularJS
User Group Taiwan
http://bit.ly/stackblitz-angular-pure-pipes
所有 Pipes 元件預設為 Pure Pipes
• 唯有屬性參考發生改變,才會執行 Pipes 轉換
• 考慮使用 Immutable.js
若將 Pipe 元件改為「不純」的 Pipe 元件
• 每次變更偵測都會執行一遍 Pipes 轉換
謹慎使用 Pipes 元件
AngularJS
User Group Taiwan
http://bit.ly/stackblitz-angular-ngfor-trackby
使用 *ngFor 跑迴圈時
• 可利用 trackBy 選項減少 DOM 更新次數 (效能提升)
• 這裡的 trackBy 只能接受一個函式 (簡稱 trackByFn 函式)
• 自訂的 trackByFn 函式可以接受兩個參數
• index
• item
• 只要有提供 trackBy 設定,就會依據 trackByFn 函式的
回傳值才決定是否更新該筆資料在頁面上的 DOM 物件
使用 TrackBy 避免不必要的 DOM 操作
AngularJS
User Group Taiwan
constructor(private cd: ChangeDetectorRef) {
this.cd.detach();
setInterval(() => {
this.cd.detectChanges();
}, 5000);
}
關閉變更偵測
AngularJS
User Group Taiwan
模組化 Angular 應用程式
Modularization
AngularJS
User Group Taiwan
1. 全部載入 (預設)
• 將所有模組打包成 1 個 JS 檔案
2. 延遲載入
• 將部分模組拆解成可延遲載入的程式片段 (chunks)
• 主動擊進入特定路由,延遲載入的模組才會即時載入
3. 預先載入
• 將部分模組拆解成可延遲載入的程式片段 (chunks)
• 預先載入的過程透過非同步背景下載所有子路由模組
• 下載過程不影響畫面顯示或使用者操作
多利用子路由模組達成延遲載入
AngularJS
User Group Taiwan
把用不到的模組通通移除
• FormsModule, HttpModule, …
所有的路由頁面都透過延遲載入,確保首頁載入最快!
• Lazy loading
把需要在第一頁顯示的 Components 封裝在一個模組裡
• 要避免元件重複註冊
規劃模組載入的三個原則
AngularJS
User Group Taiwan
錯誤示範
• import 'rxjs';
正確寫法
• import { Observable } from 'rxjs/Observable';
• import 'rxjs/add/operator/switchMap';
• import 'rxjs/add/operator/map';
不要 import 用不到的 JS 模組
AngularJS
User Group Taiwan
反面模式
Anti-Patterns
AngularJS
User Group Taiwan
http://bit.ly/stackblitz-angular-async-pipe
多利用 AsyncPipe 自動訂閱傳入元件的觀察者物件
• {{ data | async | json }}
• {{ obj | json }}
不要在頁面元件中訂閱觀察者物件
AngularJS
User Group Taiwan
http://angular.tw (Angular User Group Taiwan)
https://forum.angular.tw/ ( 台灣 Angular 技術論壇 )
Angular Extension Pack - Visual Studio Marketplace
Angular Best Practices - August 2017 Edition
Optimizing the Performance of Your Angular Apps
Best Practices - STEPHEN FLUIN - YouTube
angular-cli/build.md at 1.3.x · angular/angular-cli
相關連結
AngularJS
User Group Taiwan
Thank you
AngularJS
User Group Taiwan
The Will Will Web
記載著 Will 在網路世界的學習心得與技術分享
• http://blog.miniasp.com/
Will 保哥的技術交流中心 (臉書粉絲專頁)
• http://www.facebook.com/will.fans
Will 保哥的噗浪
• http://www.plurk.com/willh/invite
Will 保哥的推特
• https://twitter.com/Will_Huang
聯絡資訊

Angular 4 網站開發最佳實務 (Modern Web 2017)

Editor's Notes

  • #5 https://pixabay.com/zh/%E5%A5%B3%E5%AD%90-%E6%9E%84%E6%88%90-%E7%94%B5%E5%AD%90%E5%AD%A6%E4%B9%A0-%E5%A5%B3%E6%80%A7-%E5%A5%B3%E5%AD%A9-%E4%BA%BA-%E9%AB%98%E5%8A%A0%E7%B4%A2-%E5%85%B4%E5%A5%8B-1401616/
  • #6 https://pixabay.com/zh/%E5%A5%B3%E5%AD%90-%E6%9E%84%E6%88%90-%E7%94%B5%E5%AD%90%E5%AD%A6%E4%B9%A0-%E5%A5%B3%E6%80%A7-%E5%A5%B3%E5%AD%A9-%E4%BA%BA-%E9%AB%98%E5%8A%A0%E7%B4%A2-%E5%85%B4%E5%A5%8B-1401616/
  • #10 https://github.com/angular/angular-cli/issues/5244
  • #18 https://netbasal.com/optimizing-the-performance-of-your-angular-application-f222f1c16354
  • #19 https://netbasal.com/optimizing-the-performance-of-your-angular-application-f222f1c16354
  • #21 Default Default means that the change detector’s mode will be set to CheckAlways during hydration. OnPush OnPush means that the change detector’s mode will be set to CheckOnce during hydration.
  • #22 https://netbasal.com/optimizing-the-performance-of-your-angular-application-f222f1c16354
  • #23 https://netbasal.com/optimizing-the-performance-of-your-angular-application-f222f1c16354
  • #24 如果元件中套用 @Input() 的屬性沒有任何改變,Angular 會跳過變更偵測 (含所有子元件都會跳過) https://netbasal.com/optimizing-the-performance-of-your-angular-application-f222f1c16354
  • #26 The problem is, because Angular needs to re-run your function in every change detection cycle, if the function performs expensive tasks, it can be costly. Angular Guide - Pipes https://angular.io/guide/pipes
  • #27 The problem is, because Angular needs to re-run your function in every change detection cycle, if the function performs expensive tasks, it can be costly. Angular Guide - Pipes https://angular.io/guide/pipes
  • #28 https://stackoverflow.com/questions/36322829/how-to-use-track-by-inside-ngfor-angular-2
  • #34 https://zh.wikipedia.org/wiki/%E5%8F%8D%E9%9D%A2%E6%A8%A1%E5%BC%8F