搜尋
首頁web前端js教程angular如何進行效能優化?變更檢測方式淺析

angular如何進行效能最佳化?以下這篇文章給大家深入介紹angular 效能優化方案--變更偵測,希望對大家有幫助!

angular如何進行效能優化?變更檢測方式淺析

angular 效能最佳化-變更偵測

         前端效能指標描述,業界皆各有說詞,總結下來都和首屏表現和頁面流暢度相關, 本次將會從頁面流暢度的角度,對頁面互動效能優化進行分析。 【相關教學推薦:《angular教學》】

什麼是頁面流暢度?

        頁面流暢度是透過幀率FPS(Frames Per Second - 每秒傳輸幀數)判定的,一般主流的瀏覽器螢幕更新率都在60Hz(每秒刷新60次),最優的幀率在60 FPS,幀率越高,頁面就越流暢,60Hz意味著每隔16.6ms會刷新一次顯示屏,也就是每一次渲染頁面需要在16.6ms內完成,否則就會導致頁面失幀,出現卡頓現象。 根因在於:瀏覽器中的 JavaScript 執行和頁面渲染會互相阻塞

         在Chrome 的devtools 中我們可以執行Cmd Shift P 輸入show fps 快速開啟fps 面板,如下圖所示:

angular如何進行效能優化?變更檢測方式淺析

#透過觀察FPS 面板,如下圖所示:

angular如何進行效能優化?變更檢測方式淺析

#透過觀察FPS 面板,如下圖所示:

#dFPS 面板面板, ,我們可以很方便的對目前頁面的流暢度進行監控

1 影響頁面效能的因素angular如何進行效能優化?變更檢測方式淺析

         頁面互動是否流暢,且在於頁面回應是否流暢,而頁面回應本質上是將頁面狀態的變更重新渲染到頁面上的過程。

         頁面回應過程大致如下:

一般情況Event Handler事件處理邏輯不會消耗太多時間,所以影響angular效能的因素主要在於非同步事件觸發

變更偵測

。 一般情況Event Handler事件處理邏輯不會消耗太多時間,所以影響angular效能的因素主要在於非同步事件觸發和變更偵測。

         對angular來說,頁面渲染的過程就是變更偵測的過程,可以理解為angular的變更偵測要在16.6ms內完成才不會導致頁面遺失畫面、卡頓。 可以從以下三個方面優化頁面回應的效能。 (1)對於觸發事件階段,可以

減少非同步事件的觸發

,來減少整體的變更偵測次數和重新渲染;

(2)對於Event Handler 執行邏輯階段,可以透過最佳化複雜程式碼邏輯來減少執行時間;(3)對於Change Detection 偵測資料綁定並更新DOM 階段,可以減少變更偵測模板資料的計算次數來減少渲染時間;

#對於(2)Event Handler要具體問題具體分析,不做討論,主要針對( 1)(3)進行最佳化

2

最佳化方案

angular如何進行效能優化?變更檢測方式淺析

2.1 減少非同步事件觸發

         Angular在預設變更偵測模式下,非同步事件會觸發全域的變更偵測,因此,減少非同步事件的觸發會大幅提升angular的效能。

         非同步事件包含Macro Task(巨集任務)事件與Micro Task微任務事件

         對非同步事件的最佳化事件為最佳化事件的最佳化事件。例如document上的click、mouseup、mousemove…等監聽事件。

###         監聽事件情境:######                Renderer2.listen( ####                document.addEventListener(…)## ####         dom監聽事件,且不需要觸發的時候一定要移除。 ###

範例:[pop]提示框指令

         使用情境:表格列篩選,點選圖示以外的地方,或是頁面捲動,列篩選彈框隱藏

         先前的做法是指

   在pop指令裡監聽document的click事件和scroll事件,這樣有個弊端就是提示框未顯示,但依然存在監聽事件,很不合理。

         合理的解決方案:當提示框顯示的時候才去監聽click和scroll事件,隱藏的時候就移除監聽事件。 angular如何進行效能優化?變更檢測方式淺析

對於頻繁觸發的dom監聽事件,可以使用rjx的運算元對事件進行最佳化。詳情請參考Rjx操作符

RxJS Marbles

2.2 變更偵測

什麼是變更偵測?          要瞭解變更偵測,我們可以從變更偵測的目標中找出答案。 angular變更偵測目標,是讓模型(TypeScript程式碼)與範本(HTML)保持同步。因此,變更偵測可以理解為:偵測模型變更的同時,更新範本( DOM

變更偵測流程是什麼? angular如何進行效能優化?變更檢測方式淺析

       透過在元件樹中依照

自頂向下

的順序執行變更偵測,也就是先對父元件執行變更偵測,再對子組件進行變更檢測。首先檢查父元件的資料變更,然後更新父元件模板,在更新模板的時候遇到子元件,會去更新子元件上綁定的值,然後進入子元件,看@Input輸入值的索引是否改變,如果改變就將該子元件標記為dirty,也就是後續需要變更偵測的,標記完子元件之後,繼續更新父元件中子元件後面的模板,父元件模板全部更新完之後再去對子元件做變更檢測。

2.2.1 angular變更偵測原理   

       在預設變更偵測default模式下,非同步事件觸發Angular的變更偵測的原理是angular透過使用Zone.js處理非同步事件時呼叫了ApplicationRef的tick()方法從根組件到子組件執行變更檢測。 Angular 應用初始化過程中,實例化了一個zone (NgZone),然後將所有邏輯都跑在該物件的 _inner 物件中。

    Zone.js實作了以下幾個類別:
  • Zone類,JavaScript 事件的執行環境,和執行緒一樣,它們可以帶一些數據,並且可能擁有父子 zone。
  • ZoneTask類,包裝後的非同步事件,這些 task 有三種子類:
    • MicroTask,由 Promise 創建。
    • MacroTask,由 setTimeout 等建立。
    EventTask,由 addEventListener 等創建,例如dom事件。
  • ZoneSpec對象,創建一個ngZone 時給它提供的參數,有三個可以觸發檢測的鉤子:
    • onInvoke,呼叫某個回調函數時觸發的鉤子。
    • onInvokeTask,ZoneTask 被觸發時觸發的鉤子,例如 setTimeout 到時。
    onHasTask,偵測到有或沒有 ZoneTask 時觸發的鉤子(即對第一個 schedule 的 zone 和最後一個 invoke 或 cancel 的 task 觸發)。
ZoneDelegate類,負責呼叫鉤子。

偵測過程原理大概如下:

       使用者操作觸發非同步事件(例如:dom事件,介面請求…)

=>  ZoneTask類別處理事件。 invokeTask()函數中呼叫zone的runTask()方法,在runTask方法中,zone透過_zoneDelegate實例屬性,呼叫ZoneSpec的鉤子

=>  ZoneSpec的三個鉤子(onInvokeTask、onInvoke、onHasTask)鉤子裡透過checkStable()函數觸發zone.onMicrotaskEmpty.emit(null)通知=>  根元件監聽onMicrotaskEmpty後呼叫tick(),tick方法中呼叫 

detectChanges()

#detect##從從根元件開始偵測=> ··· refreshView()呼叫executeTemplate()executeTemplate方法中呼叫

templateFn ()

更新範本、子元件綁定的值(

這時候會去偵測子元件的###@Input()###輸入引用是否改變,如果有改變,會將子元件標記為###Dirty###,也就是該子元件需要變更偵測###)######詳細變更偵測原理流程圖:###

angular如何進行效能優化?變更檢測方式淺析

簡化流程:

觸發非同步事件

=>  ZoneTask處理事件

=> 觸發非同步事件

=>  ZoneTask處理事件

=> ZoneDelegate 呼叫ZoneSpec的鉤子觸發onMicrotaskEmpty通知angular如何進行效能優化?變更檢測方式淺析

=> 根元件收到onMicrotaskEmpty通知,執行tick(),開始偵測並更新dom

由上述程式碼可知,

當微任務為空的時候才會觸發變更偵測

angular如何進行效能優化?變更檢測方式淺析

簡略變更偵測原理流程圖:

Angular 原始碼解析 Zone.js參考

blog

#。

2.2.2 變更偵測最佳化方案

1 )使用OnPush 模式

原理:減少1次變更偵測的耗時。

         OnPush模式與Default模式的差異在於:dom監聽事件、timer事件、promise都不會觸發變更偵測。 Default模式的元件狀態始終為CheckAlways,表示元件每次偵測週期都要偵測。

OnPush模式下:以下情況會觸發變更偵測

    S1、元件的@Input引用變更。

    S2、元件的DOM所綁定的事件,包含它子元件的DOM所綁定的事件,如 click、submit、mouse down。 @HostListener()

      注意:

        以renderer2.listen()監聽的dom事件不會觸發變更偵測

  Event List 會觸發變更偵測

    S3、Observable 訂閱事件,同時設定Async pipe。

    S4、使用以下方式手動觸發變更偵測:

      ChangeDetectorRef.detectChanges():觸發目前元件和非OnPush子元件的變更偵測。

      ChangeDetectorRef.markForCheck():將目前視圖及其所有的祖先標記為髒,下次偵測週期時會觸發偵測。

      ApplicationRef.tick():不會觸發變更偵測

2 )使用NgZone.runOutsideAngular()

原則:減少變更偵測次數

   #  全域dom事件監聽寫在NgZone.runOutsideAngular()方法的回呼裡面,dom事件將不會觸發angular的變更偵測。如果目前元件未更新,可以在回呼函數裡執行ChangeDetectorRef的detectChanges()鉤子來手動觸發目前元件的變更偵測。

angular如何進行效能優化?變更檢測方式淺析範例:app-icon-react動態圖示元件

2.2.3 除錯方法

1angular如何進行效能優化?變更檢測方式淺析         方式1:可在瀏覽器控制台,使用Angular DevTools外掛檢視某次dom事件,angular的偵測狀況:

         方式2:可在控制台直接輸入:ng.profiler.timeChangeDetection()檢視檢測時間,這種方式可查看全域的檢測時間。參考部落格

Profiling Angular Change Detection1angular如何進行效能優化?變更檢測方式淺析

2.3 範本(HTML)最佳化

2.3.1 減少DOM渲染:ngFor加trackBy

         使用*ngFor 的trackBy 屬性,Angular 只變更並重新渲染已變更的條目,而不必重新載入整個條目清單。

         例如:表格排序場景。 ngFor如果加了trackBy,表格渲染的時候只會移動行dom元素,如果不加trackBy,會先刪除現有的表格dom元素,再新增行dom元素。顯然只移動dom元素效能會好很多。

2.3.2 模板表達式中不要使用函數

         不要在Angular 模板表達式中使用函數調用,可以用管道pipe代替,也可以手動計算後用一個變數代替。模板中使用函數,不管值有沒有改變,每次變更偵測的時候都會執行函數,都會影響效能。 ######         範本中使用函數的情境:###

1angular如何進行效能優化?變更檢測方式淺析

2.3.3 減少ngFor的使用

使用ngFor,資料量大的時候會影響效能。

範例:

使用ngFor:

1angular如何進行效能優化?變更檢測方式淺析

1angular如何進行效能優化?變更檢測方式淺析

#不使用ngFor:效能提升10倍左右

1angular如何進行效能優化?變更檢測方式淺析

1angular如何進行效能優化?變更檢測方式淺析

更多程式相關知識,請造訪:程式設計影片! !

以上是angular如何進行效能優化?變更檢測方式淺析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金社区。如有侵權,請聯絡admin@php.cn刪除
Angular学习之聊聊独立组件(Standalone Component)Angular学习之聊聊独立组件(Standalone Component)Dec 19, 2022 pm 07:24 PM

本篇文章带大家继续angular的学习,简单了解一下Angular中的独立组件(Standalone Component),希望对大家有所帮助!

angular学习之详解状态管理器NgRxangular学习之详解状态管理器NgRxMay 25, 2022 am 11:01 AM

本篇文章带大家深入了解一下angular的状态管理器NgRx,介绍一下NgRx的使用方法,希望对大家有所帮助!

项目过大怎么办?如何合理拆分Angular项目?项目过大怎么办?如何合理拆分Angular项目?Jul 26, 2022 pm 07:18 PM

Angular项目过大,怎么合理拆分它?下面本篇文章给大家介绍一下合理拆分Angular项目的方法,希望对大家有所帮助!

聊聊自定义angular-datetime-picker格式的方法聊聊自定义angular-datetime-picker格式的方法Sep 08, 2022 pm 08:29 PM

怎么自定义angular-datetime-picker格式?下面本篇文章聊聊自定义格式的方法,希望对大家有所帮助!

浅析Angular中的独立组件,看看怎么使用浅析Angular中的独立组件,看看怎么使用Jun 23, 2022 pm 03:49 PM

本篇文章带大家了解一下Angular中的独立组件,看看怎么在Angular中创建一个独立组件,怎么在独立组件中导入已有的模块,希望对大家有所帮助!

手把手带你了解Angular中的依赖注入手把手带你了解Angular中的依赖注入Dec 02, 2022 pm 09:14 PM

本篇文章带大家了解一下依赖注入,介绍一下依赖注入解决的问题和它原生的写法是什么,并聊聊Angular的依赖注入框架,希望对大家有所帮助!

Angular的:host、:host-context、::ng-deep选择器Angular的:host、:host-context、::ng-deep选择器May 31, 2022 am 11:08 AM

本篇文章带大家深入了解一下angular中的几个特殊选择器:host、:host-context、::ng-deep,希望对大家有所帮助!

深入了解Angular中的NgModule(模块)深入了解Angular中的NgModule(模块)Sep 05, 2022 pm 07:07 PM

NgModule 模块是Angular种一个重要的点,因为Angular的基本构造块就是NgModule。本篇文章就来带大家了解一下Angular中的NgModule模块,希望对大家有所帮助!

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具