91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Angular變更檢測機制怎么進行性能優化

發布時間:2022-05-13 17:38:59 來源:億速云 閱讀:232 作者:iii 欄目:web開發

本篇內容介紹了“Angular變更檢測機制怎么進行性能優化”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

Angular變更檢測機制怎么進行性能優化

什么是變更檢測(Change Detection)?

變更檢測的概念

組件內的數據狀態變化以后,需要對應更新視圖。這種將視圖和數據同步的機制,就叫變化檢測。

變更檢測的觸發時機

只要發生了異步操作(Events, Timer, XHR),Angular 就會認為有狀態可能發生變化了,然后就會進行變更檢測。

  • Events::click,mouseover,mouseout,keyup,keydown 等瀏覽器事件;

  • Timer:setTimeout/setInterval;

  • XHR:各類請求等。

既然都是對異步操作進行變更檢測,那么Angular是如何訂閱異步請求,進行變更檢測的呢?

這里介紹下NgZone以及它的fork對象Zone.js

Zone.js 用于封裝和攔截瀏覽器中的異步活動、它還提供 異步生命周期的鉤子統一的異步錯誤處理機制。

Zone.js 是通過 Monkey Patching(猴子補丁) 的方式來對瀏覽器中的常見方法和元素進行攔截,例如 setTimeoutHTMLElement.prototype.onclick。Angular 在啟動時會利用 Zone.js 修補幾個低級瀏覽器 API,從而實現異步事件的捕獲,并在捕獲時間后調用變更檢測。

Angular通過forkZone.js并拓展出一個自己的區域NgZone,讓應用中的所有異步操作都會運行在這個區域中。

Angular的變更檢測如何工作的?

Angualr會為每一個組件生成一個變化監測器changeDetector ,記錄組件的變化狀態。

我們在創建了一個Angular 應用后,Angular 會同時創建一個 ApplicationRef  的實例,這個實例代表的就是我們當前創建的這個 Angular 應用的實例。 ApplicationRef 創建的同時,會訂閱 ngZone 中的 onMicrotaskEmpty  事件,在所有的微任務完成后調用所有的視圖的detectChanges()來執行變更檢測。

變更檢測的執行順序

  • 更新所有子子組件綁定的屬性

  • 調用所有子組件生命周期的鉤子 OnChanges, OnInit, DoCheck,AfterContentInit

  • 更新當前組件的DOM

  • 調用子組件的變更檢測

  • 調用所有子組件的生命周期鉤子 ngAfterViewInit

舉個栗子,我們在開發模式的時候可能會遇到這種報錯:

Angular變更檢測機制怎么進行性能優化

這是由于變更檢測遵循從根組件開始,從上到下,執行每個組件的變更檢測,直到最后一個組件達到穩定狀態。而在下一次變更檢測之前,子孫組件都不允許去修改父組件里的屬性。

情況1 在開發模式下,Angular會進行二次檢測 (生產環境下調用enableProdMode(),檢測次數會降為1)。一旦我們在 第4步 完成后,在子孫組件里修改父組件的屬性,那么,Angular在執行第二次檢測的時候,發現兩次的值不一致,就會出現上述錯誤。

情況2 只要父組件對子組件做了屬性綁定,那么不管是在OnChanges,OnInit,DoCheck,AfterContentInit 和 AfterViewInit 中的任意一個生命周期鉤子中執行下述代碼,也會報錯。

// #parent
{{data}}
<child [data]="data"></child>

// in child component ts, execute:
this.parent.data = 'new Value';

變更檢測的執行策略

  • Default 策略

    每次事件觸發變化檢測(如用戶事件、計時器、XHR、promise 等)時,此默認策略都會從上到下檢查組件樹中的每個組件。這種對組件的依賴關系不做任何假設的保守檢查方式稱為 臟檢查,這種策略在我們應用組件過多時會對我們的應用產生性能的影響。

  • OnPush 策略

    修改組件裝飾器的changeDetection,設置為 OnPush 策略后,Angular 每次觸發變化檢測后會跳過該組件和該組件的所以子組件變化檢測。

    OnPush 策略下,只有以下這幾種情況才會觸發組件的變化檢測:

    • detectChanges(): 它會觸發當前組件和子組件的變化檢測

    • markForCheck(): 它不會觸發變化檢測,但是會把當前的OnPush組件和所以的父組件為OnPush的組件 標記為需要檢測狀態 ,在當前或者下一個變化檢測周期進行檢測

    • ApplicationRef.tick() : 它會根據組件的變化檢測策略,觸發整個應用程序的更改檢測

    • setTimeout()

    • setInterval()

    • Promise.resolve().then()

    • this.http.get('...').subscribe()

    • 輸入值(@Input)更改(入input的值必須是一個新的引用)

    • 當前組件或子組件之一觸發了事件 (但在onPush策略中,以下操作不會觸發變更檢測)

    • 手動觸發變更檢測(每個組件都會關聯一個組件視圖ChangeDetectorRef)Angular變更檢測機制怎么進行性能優化

    • async pipe

對于Angular的變更檢測如何優化?

由于組件默認執行 Default策略 ,任何異步操作都會觸發整個組件數從上到下的檢查。即使Angular團隊不斷提升性能,可以在毫秒內完成上百次檢測,但是當應用拓展至百上千個組件組成時,龐大的組件樹對應的變更檢測也會達到性能瓶頸。

此時,我們就需要開始分析并減少不必要的檢測次數。

如何減少檢測次數

  • 區域污染(Zone Pollution)

    一般我們在生命周期鉤子里使用第三方庫,比如chart類庫初始化,會自帶requestAnimationRequest/setTimeout/addEventListener,我們可以將初始化方法寫入NgZonerunOutsideAngular方法中。

Angular變更檢測機制怎么進行性能優化

  • OnPush 策略

    對于不涉及更新操作的視圖可以剝離出組件,使用onPush策略,以通知更新的方式刷新視圖(見上方 變更檢測的執行策略 部分)。

Angular變更檢測機制怎么進行性能優化

  • 用 pure pipe 代替 {{function(data)}}

    在html文件內,{{function(data)}}的寫法會導致每次變更檢測發生時,所有數值都會重新被計算。(?:當一個1000條的列表,你只修改了其中一條數據,但另外另外999條無需更新的數據也會被重新運算。)

    此時,我們可以使用pipe的方式,只有變更的值會觸發運算,更新部分視圖。

Angular變更檢測機制怎么進行性能優化

  • 面對大量數據的渲染,選擇虛擬滾動/分頁請求數據

    以上4點解決方案,來源于Angular團隊的視頻介紹,視頻中以Angular devtool運算次數,來分析問題解決問題。所以,如果你的Angular是9+,請繼續看下去吧,如何安裝Angular devtool和運行。

插件:Angular devtool使用介紹

  • Angular 9+, 支持Ivy。

  • Guide和下載地址

  • 保證運行環境為開發環境

    // environment.dev.ts
    ...
        production: false
    ...
  • angular.json > dev配置項 > "optimization": false

    projects > your-project-name > architect > build > configurations > dev > "optimization": false

“Angular變更檢測機制怎么進行性能優化”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

共和县| 宁阳县| 蒲江县| 日土县| 车险| 花垣县| 汉阴县| 临夏县| 牙克石市| 新乡市| 平阴县| 衢州市| 平潭县| 舒城县| 大姚县| 文山县| 安远县| 申扎县| 五寨县| 平乐县| 屏东市| 上饶县| 新津县| 门源| 阳谷县| 肃宁县| 江西省| 潮州市| 陇南市| 扎囊县| 云南省| 绥德县| 翁源县| 高要市| 乐清市| 闻喜县| 扎鲁特旗| 呼和浩特市| 黄大仙区| 美姑县| 东丰县|