preloader
心得

Solution of Ionic4 Performance Problem | ionic v3 升級到 v4 後的效能問題

Solution of Ionic4 Performance Problem | ionic v3 升級到 v4 後的效能問題

本週工作上線製作許久的專案: ionic v3 升級到 ionic v4,陸續收到客戶的回饋意見,其中一個就是當清單畫面有大量資料時,呈現資料和搜尋時,使用者都會有一段時間做其他動作沒有反應,以及速度太慢,例如滑鼠捲動畫面時,畫面並沒有捲動。我試了四種解決方法,直到第四種才完整有效。

第一種方式是參考 ionic v4 官網教的,將原本放在 ionViewWillEnter() 裡的程式碼內容,改放在 ionViewDidEnter(),這只解決到達此畫面的情境,後續在此畫面的操作,仍然有網頁畫面沒反應的問題。

第二種方式是使用 ion-infinite-scroll 元件呈現大型清單資料,一樣沒效果; 改用 material-ui 套件的 virtualscroll 元件,也是沒有效果。

第三種方式是使用 angular 框架必備的 ngZone 套件,將畫面無關的操作放到 runOutsideAngular(),這也只解決一部份問題,例如捲動畫面當在畫面資料上半部時仍能正常捲動,但當捲到畫面下半部時,因為畫面只顯示一部份資料,捲動畫面時會有卡頓的現象。

終於,第四種方式是關掉 zone.js v0.8.27 後的 custom_element patch。步驟如下:

  1. src/ 目錄底下新增一個檔案 zone-flags.ts,裡面內容是:
/**
 * Prevents Angular change detection from
 * running with certain Web Component callbacks
 */
// eslint-disable-next-line no-underscore-dangle
(window as any).__Zone_disable_customElements = true;
  1. src/polyfills.ts 檔案裡新增以下內容,裡面內容是:
import './zone-flags'; // <- 新增剛才建立的檔案,並且在底下的 `zone.js` 之前 import zone-flags

/***************************************************************************************************
 * Zone JS is required by default for Angular itself.
 */
import 'zone.js';  // Included with Angular CLI.
  1. 在專案家目錄底下的 tsconfig.app.json 檔案裡,確認以下內容:

{
    ...(略),
    "files": [
        "./src/main.ts",
        "./src/zone-flags.ts", // <-本次新增的內容
        "./src/polyfills.ts"
    ]

}

因為套件 zone.js v0.8.27 以後的版本,會對 custom element 產生額外的 change detection,而 ionic v4 的 各種 component 方式是使用 WebComponent (例如shadow DOM),所以必須關掉 zone.jscustom element 的處理。

資料來源:

  1. If you see performance problems from using ionViewWillEnter when loading data, you can do your data calls in ionViewDidEnter instead
  2. 討論串 ionic 4 slow performance on user interaction, 原因說明 on ionic 4 slow performance on user interaction
  3. 討論串2 on github issue#18020 , 其他人的說明
  4. 範例 @ionic/angular starter PR#750
  5. MDN: WebComponent 的重要特色之一是建立客製化元素 custom element