【译】Angular 开发44条“军规”
Angular是一個很棒的框架,非常適合開發大型應用程序,以便在網絡上獲得最高性能。但有時我們作為開發人員最終會做一些導致應用程序性能不佳的事情。
在這篇文章中,我將Angular特定的最佳實踐放在一起,以獲得最佳的加載時間和運行時性能.此外,除了Angular之外,我還提到了Web開發中的一些一般最佳實踐。
加載性能 (Load Time Performance)
1. AOT: 與在瀏覽器中完成編譯的JIT編譯相反,AOT在構建過程中編譯了大部分代碼(也稱為脫機編譯),從而減少了客戶端瀏覽器上的大部分處理開銷。使用angular-cli只需指定“aot”標志(如果存在prod標志,則不需要aot標志)并啟用AOT。
2. Tree-shaking: 這是刪除未使用的代碼的過程,從而導致較小的構建大小。如果使用angular-cli,則默認啟用Tree-Shaking。
3. Uglify: 這是使用各種代碼轉換(如修改,刪除空格,刪除注釋等)來減少代碼大小的過程。對于webpack,使用uglify插件和angular-cli指定“prod”標志來執行uglification過程。
4. Google Closure Compiler: 這是Google用于其產品的編譯器,與Webpack uglify相比,通過執行更具侵略性的縮小,可以產生更小的捆綁包大小。即使Angular團隊沒有正式支持,您也可以使用閉包編譯器來查看此實現。
5. Webpack 4: 與Webpack 3相比,使用Webpack 4(及更高版本)進行angular-cli或自定義webpack構建會產生更小的構建大小.Webpack 4具有模式選項,允許您指定優化類型(生產或開發),而無需編寫任何顯式配置為您提供目標環境的最佳結果。此外,Webpack 4的構建時間比早期版本快得多(60%到98%),從而縮短了開發時間。
6. Prod flag: 對于產品,build時在angular-cli應用程序中指定“prod”標志。它將啟用各種構建優化,如uglify,AOT,刪除源映射,服務工作者(如果啟用)生成更小的構建大小。
7. Build-optimizer flag: 如果您使用angular-cli,請確保為生產版本指定“build-optimizer”標志。這將禁用供應商塊,并將導致更小的代碼。
8. Lazy loading: 延遲加載是一種機制,我們只加載當前所需的模塊,而不是加載完整的應用程序,從而減少初始加載時間。簡單來說,它意味著“不要加載你不需要的東西”。
9. Server side rendering: 在服務器上渲染應用程序的第一頁(使用Node.js,.Net,PHP)并將其作為靜態頁面提供,可以實現即時渲染,從而大大提高了感知性能,速度和整體用戶體驗。您可以使用Angular Universal執行服務器端呈現。
10. Progressive Web App: PWA使您的應用程序加載速度更快,它為您的應用程序提供了離線功能,并提供接近原生的應用程序體驗,從而大大提高了用戶的整體感知性能。
11. Ivy Render Engine: Angular團隊最近宣布了一個名為Ivy的新渲染引擎。與現有引擎相比,它的捆綁尺寸小得多,具有改進的調試體驗。雖然它仍然沒有生產就緒,但你仍然可以在你的應用程序中嘗試它。您可以查看此ng-conf主題演講以獲取更多詳細信息。
12. Updating Angular and angular-cli: 定期更新Angular和angular-cli可以為您帶來許多性能優化,錯誤修復,新功能,安全性等優勢。
13. RxJS 6: RxJS 6使整個庫更具tree-shakable 特性,從而減少了最終的束大小。但是,它有一些突破性的變化,例如操作符鏈接是不可能的,管道()函數(有助于更好的樹搖動)被引入以添加運算符。他們還重命名了一些運營商。
14. Service worker cache: 如果您已將應用程序配置為支持Progressive Web App,請確保在PWA配置JSON中指定所有必需的靜態資源。這些靜態文件將緩存在客戶端的瀏覽器中,使第二次加載速度更快。
15. Cache-control header: Cache-control header控制誰在什么條件下緩存響應以及多長時間,從而消除了緩存資源的網絡往返的需要。
16. Third party packages: 查看您正在使用的第三方軟件包,看看是否有更好和更小的替代方案,因為它可能會減少構建的最終大小。
17. Unnecessary use of third-party packages: 如果您包含第三方軟件包只是為了實現一個小功能,可以使用JavaScript或Angular本地輕松完成,那么您將為您的應用程序添加不必要的大小開銷,這可能很容易保存。例如,如果你只是為了做一個簡單的對象過濾而包含Lodash那么完全沒必要,因為你可以在JavaScript中本地做同樣的事情。
18. defer attribute: 添加defer屬性到script 標簽中將推遲加載腳本(同步),直到文檔未被解析,從而使您的網站更快地交互。對于angular-cli app,目前無法在構建期間自動添加,您必須在構建后手動執行此操作。
19. async attribute: 就像defer屬性一樣,異步延遲了腳本的加載,直到文檔沒有被解析,但沒有遵守腳本的加載順序。將其與谷歌分析腳本一起使用的最佳示例,該腳本通常獨立于任何其他腳本。
20. Gzip compression: Gzip壓縮可以大大減小響應主體的大小,從而提高Web應用程序的速度。確保在后端啟用了gzip壓縮。對于express.js,您可以添加壓縮中間件。
22. Preload and Prefetch attributes: 這些屬性有助于盡快加載靜態資源,從而縮短第一次有意義的繪制時間。Preload和Prefetch幾乎相似,唯一的區別是Preload資源具有更高的優先級。因此,對于初始呈現必不可少的資產使用Preload,并對站點加載后所需的資源使用Prefetch(將來需要跨頁面)。您可以在此處詳細了解這些屬性。
23. Updating Third Party Packages: 確保您定期更新第三方軟件包。很多時候,較新的軟件包可能包含許多性能改進,包括較小的體積和其他構建時性能優化(例如RxJS 6)。此外,通過定期更新軟件包,您可以獲得許多與錯誤修復,安全漏洞修復,與軟件包兼容性相關的修復等相關的改進。
24. Compressing images: 在不損失大部分質量的情況下壓縮圖像是一個好主意,從而節省了通過網絡傳輸的字節,從而縮短了構建時間。有許多工具可以實現這一目標。名為TinyPNG的VS Code擴展可用于壓縮Jpeg和PNG圖像,而不會損失太多質量。
25. Remove unused fonts: 刪除的未使用的字體文件,可以減少網絡請求。
26. Slow DNS and SSL: 有時您的DNS和SSL提供商可能是加載時間緩慢的原因。因此,請確保DNS和SSL正確配置。
運行時性能 (Run Time Performance)
27. Change Detection: 默認情況下,對每個異步事件,Angular通過對整個組件樹執行更改檢測來執行臟檢查。對于大中型應用程序來說,這種臟檢查可能會耗費大量計算量。您可以通過將“ChangeDetectionStrategy”設置為“OnPush”來大幅減少更改檢測。 OnPush策略促進了不可變數據結構的使用。
28. Detach Change Detector: 我們可以完全從變化檢測中分離組件,從而使開發人員能夠通知Angular何時何地執行變更檢測。
import {AfterViewInit, ChangeDetectorRef} from '@angular/core'; @Component(…) class AppComponent implements AfterViewInit {constructor(private cdr: ChangeDetectorRef) {}ngAfterViewInit() {// We only want to detach the change detectors after change detection has been// performed for the first timethis.cdr.detach();}update() {// Run change detection only for this component when update() method is called.this.cdr.detectChanges();} }29. Web Workers: 所有瀏覽器中的JavaScript實現都是單線程的,從而使整個應用程序在單個線程上運行。這種單線程執行大大降低了復雜應用程序的幀速率,因為UI繪制和JS執行都由同一個線程處理。由于Angular默認避免直接DOM操作,因此可以在單獨的Web工作線程中運行整個Angular應用程序,從而保持主線程可以自由處理UI呈現。查看這篇文章,了解如何在web worker中運行angular-cli應用程序。但是,有許多npm包試圖直接訪問DOM,從而在工作進程中運行整個應用程序時產生問題。如果您只想在Web工作線程下運行一段代碼,請查看此npm包。
30. Webassembly: Webassembly是一種低級程序集,就像一種支持接近原生性能的語言。 WebAssembly旨在通過利用各種平臺上可用的通用硬件功能以本機速度執行。您可以利用Webassembly使用Webassembly運行一些Web應用程序代碼。看一下使用angular-cli和wasm創建的這個演示應用程序。但是,您應該意識到ism仍然是新的并且使用它有時可能會很棘手,因為現在它只有4種支持的數據類型(2個浮點和2個整數點)。到目前為止,對于大多數情況來說,與內聯JS相比,使用它來執行一小段代碼時,wasm的性能優勢并不是那么大。正確評估您想要移動到哪個代碼。
31. trackBy: 默認情況下,* ngFor通過引用標識對象唯一性。如果通過更新對象的內容來破壞對象引用,Angular將完全刪除相關的DOM節點并再次重新創建它,即使所需的實際更改僅適用于DOM節點的一小部分。使用trackBy可以輕松解決此問題。
@Component({selector: 'app', template: `<ul><li *ngFor="let item of items; trackBy: trackById">{{item.name}}</li></ul>` }) class AppComponent {Items = [{id: 1,name: 'item 1'}, {id: 2,name: 'item 2'},...];trackById(index, item) {return item.id;} }32. Pure Pipes: 在“@Pipe”裝飾器中,您可以將“pure”標志指定為true。此標志表示管道不依賴于任何外部或全局狀態,并且沒有副作用。這使Angular能夠緩存管道已被調用的所有輸入參數的輸出,從而允許重用值而不是重新計算。這可以導致在許多情況下執行的重復操作的大量減少,從而極大地改善了性能。
33. Avoid complex computations in the template: 避免在HTML模板中進行復雜的計算(在模板中調用一些組件方法),而是利用純管道,從而利用Angular緩存,從而避免重復操作或者如果無法使用管道,請參閱機會預先計算值,然后直接綁定值,而不是在模板中調用組件方法。
34. enableProdMode: 調用“enableProdMode()”可避免Angular對變更檢測執行其他檢查。
35. AOT Compilation: AOT不僅可以提高構建時間性能,還可以提高應用程序的運行時性能。
36. Optimize Events: 較慢的DOM事件會阻止更改檢測,直到事件未完成。例如,如果模板中的click事件在組件中處理,并且組件本身正在調用服務方法來處理它,則在從服務返回控件之前,更改檢測將不會完成。如果您的服務花費更多時間來執行預期的操作,那么它最終會減慢更改檢測的速度。查看優化邏輯的機會以改善持續時間,或者如果可能,嘗試將服務邏輯移動到單獨的Web工作線程或在需要時使用wasm。
37. Unsubscribing Observables: Observable可能會造成內存泄漏問題。所以最好在不再需要時取消訂閱它們。但是,您不必取消訂閱所有使用的可觀察對象。在可觀察完成之前銷毀的組件內創建訂閱時,需要顯式取消訂閱。
38. Observable share() operator: 如果您已在多個位置/組件訂閱了observable,則即使數據重復,每個訂閱也會嘗試生成數據。我們可以使用“share()”運算符避免跨訂閱處理重復數據。
import {Injectable} from '@angular/core'; import {HttpClient} from '@angular/common/http'; import {Observable} from 'rxjs'; import {share} from 'rxjs/operators'; @Injectable() export class AppService {data: Observable < any >;constructor(private http : HttpClient) {this.data = this.http.get<any> ('apiUrl').pipe(share());}getData() {return this.data;} }39. Progressive Web Apps: PWA不僅為您提供加載時間優化,還提供運行時優化,使您的應用程序更具響應性,交互性,快速,流暢的動畫,離線支持等。
40. Updating Third Party Packages: 再次定期更新您的第三方軟件包也可能會帶來更好的運行時性能。
41. console.log(): 在生產代碼中使用console.log()語句可能是一個壞主意,因為它會降低應用程序的性能,并且還使用console.log()記錄對象會產生內存泄漏問題。當瀏覽器的控制臺窗口打開時,console.log()執行速度會進一步降低很多倍,從而顯著影響網站的性能。最好從生產代碼中完全刪除console.log()語句,或者至少具有特定于環境的條件日志記錄。
42. Global Variables: 使用全局變量有許多缺點,其中之一就是內存泄漏。在重新加載窗口或關閉選項卡之前,不會清除全局范圍中定義的變量,因此如果不打算在整個應用程序中使用全局變量,則會導致內存泄漏。如果由于某種原因你想擁有全局變量,那么在Angular中有更好的方法。
43.Event listeners: 向DOM節點添加事件偵聽器可能會造成內存泄漏問題。如果您忘記在指令的$ destroy事件中刪除偵聽器,它將保留對DOM節點的引用,即使它已從文檔中刪除。然后,DOM樹將成為“分離的DOM樹”并將泄漏。現代JS引擎能夠為您找出大部分情況并刪除偵聽器,但更復雜的樹層次結構甚至可以挑戰最佳GC。
44. Bad Third Party Packages: 如果一個糟糕的第三方軟件包有性能問題(內存泄漏,昂貴的js執行,安全性等)將最終影響您的應用程序的性能。因此,建議在使用前正確審查任何第三方包。
所以這些是編寫高性能Angular應用程序時應該遵循的所有提示。希望這可以幫助您微調您的Angular應用程序。另外,請確保使用Chrome / Edge / Firefox JavaScript分析工具,堆快照比較,Chrome Lighthouse等不同工具對您的應用進行適當的性能分析和審核,以正確判斷究竟是什么原因導致問題。
原文
轉載于:https://www.cnblogs.com/hxling/articles/11252239.html
總結
以上是生活随笔為你收集整理的【译】Angular 开发44条“军规”的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tp5 引入 没有命名空间的类库的方法(
- 下一篇: delphi之找色和色块