天天看點

「快應用篇02」快應用開發時,優化總結篇

童鞋們好,國慶節已經結束。大家是否已經把學習與工作模式完全切回來了呢?

歡迎關注公衆号:大前端早讀

之前一篇文章我們了解了一下什麼是快應用,現在我們帶大家來看看快應用開發時,需要做到的一些優化方式。如果對快應用開發并不熟悉的童鞋,可以先去學一學快應用的一般開發方式。

快應用是一種新的應用形态,以往的手機端應用主要有兩種方式:網頁、原生應用;網頁無需安裝,卻體驗不是很好;原生應用體驗流暢,卻需要從應用商店下載下傳安裝,難以一步直達使用者;快應用的出現,就是希望能夠讓使用者無需下載下傳安裝,并且還能流暢的體驗應用内容。

以下主要針對布局元件和js子產品的技巧優化進行說明.由于編寫快應用時所用到的标簽最終由裝置從底層渲染為對應的Native元件,是以合理使用布局元件和設計業務代碼一定程度上影響着性能和使用者體驗。

「快應用篇02」快應用開發時,優化總結篇

頁面布局元件的使用

text: 展示文本使用text元件,且子元件隻能為a和span,文本溢出等屬性均适用内聯屬性lines等設定.

block: 在周遊數組類型的資料時,最外層容器盡可能的使用block元件,因為它在最終渲染時不會産生對應的Native元件減少備援的頁面結構同時配合for、if、show等指令能更為靈活的進行清單條件渲染.

「快應用篇02」快應用開發時,優化總結篇

list: 在開發一些常清單或者螢幕滾動效果時,一般會使用div進行循環便利,然而DOM結構複雜時,滾動頁面會出現卡頓現象,因為Native無法複用div元件實作的清單元素,針對需要良好清單滾動體驗的情形推薦使用list元件代替div實作場清單布局,Native會複用type屬性的list-item(作為複用的自定義字元串辨別),設定相同type屬性的list-item是優化清單滾動性能的關鍵.

「快應用篇02」快應用開發時,優化總結篇

同時需要注意以下幾點:

  1. list-item内不能嵌套list
  2. list-item的type屬性為必填屬性
  3. list-item内部需謹慎使用if/for指令,因為相同list-item的DOM結構必須完全相同,使用if或for指令會造成DOM結構的差異

當遇到類似xxx cannot be cast to xxx at …list的錯誤時,需要檢查list-item是否存在如下情形:

  1. 是否設定了type屬性. 解決方案: 設定type屬性
  2. 内部使用了if指令時. 解決方案:使用show指令替代或設定不同的type屬性
  3. 設定為相同的type屬性時,但DOM結構不同. 解決方案:使用不同的type屬性

了解list元件特點後,當DOM結構複雜時為了得到流暢的清單滾動體驗,可以從以下幾點進行性能優化:

精簡DOM層級: 即減少DOM樹的層級和分支上的DOM節點數.層級越少、數量越少,布局和渲染就會越快.是以在開發中盡量避免容易的容器元件包裹和層級嵌套.

複用list-item: 即清單中相同的DOM結構設定為同一type屬性的list-item,這是優化清單滾動體驗的關鍵.

細粒度劃分list-item: 即清單中相同DOM結構劃分為盡可能小的清單元素,而非将複雜的結構放在同一個當中.

「快應用篇02」快應用開發時,優化總結篇

關閉scrollpage: 此屬性預設關閉,标志是否将頂部頁面中非list的元素随list一起滾動.開啟會降低list的渲染性能,是以在開啟的情況下推薦先嘗試将頂部頁面中非list的元素,作為一種或多種type屬性的list-item,移入list中,進而達到關閉scrollpage提高渲染性能的目的.

「快應用篇02」快應用開發時,優化總結篇

list-item懶加載: 此懶加載方案跟傳統web中類似,即在可視區域内加載部分資料,并提前fetch請求足夠的清單資料儲存在記憶體變量中,當list滾動到底部時再從清單變量中提取另一部分資料來渲染清單,且當清單變量中資料不足時檢查清單變量中是否具有足夠資料,有則直接在清單變量中取否則提前fetch請求資料填充清單變量.

這樣達到每次請求與頁面渲染的資料量不一緻,減少首屏渲染占用的JS執行時間,減少渲染後續list-item的等待時間.

注意: 避免在viewModel的資料屬性中定義清單變量,避免資料屬性對變量的變化監聽而導緻觸發set/get資料驅動的定義造成不必要的性能消耗.

「快應用篇02」快應用開發時,優化總結篇

tabs: 直接使用tabs元件預設會加載所有标簽頁面的内容,會大緻JS線程連續忙于渲染而無法響應使用者點選事件等,造成體驗困擾.可以讓頁簽内容在使用者點選時延遲渲染而不是整個頁面初始化時渲染,這項功能可以通過if指令有條件的渲染來達到減少加載時間提升頁面性能.

「快應用篇02」快應用開發時,優化總結篇

合理使用背景選擇器: 過多的使用背景選擇器,也會在節點配置上帶來性能損耗,尤其是當一個節點滿足多個選擇時.

優化建議:

  1. 避免使用元件名稱(tag 标簽名稱)作為後代選擇的最後一項比對規則,如: .doc-page #shop text { ... };否則每個 text 元件渲染時都會周遊比對一次
  2. 減少後代選擇的層級數量,層級越深,單次比對耗時越長,如:.class1 .class2 .class3 .class4 .class5 .class6 { … }
  3. 後代選擇中最後一條比對規則的定義名稱盡量唯一,如:.doc-page #shop .shop-item .shop-name-full { ... }
「快應用篇02」快應用開發時,優化總結篇

JS子產品

函數共享: 快應用與傳統H5頁面顯著的不同點是快應用多頁面共享同一個V8 Context,而H5通常是一個頁面一個.頁面無法通訊.

跨應用架構中可以在頁面ViewModel中通過擷取app.ux中導出的資料及方法.

const appDef = this.$app.$def

整合常用JS庫到app.ux中并暴露給每個頁面使用,可以避免每個頁面在打包時對JS的重複定義,減少備援代碼.

簡化ViewModel的資料: 對于屬性public、protected、private主要承擔資料的定義與改造功能,會對指派的資料中每個屬性進行遞歸式的定義.

是以屬性個數的定義越少越好,尤其是數組類型資料,建議過濾不需要用到的對象屬性使資料結構盡可能的扁平化.

「快應用篇02」快應用開發時,優化總結篇

錯誤處理: 當對一個值為null或undefined的變量取值就會報錯.

解決方案:

1. 使用&&短路邏輯運算的執行順序來規避錯誤.

a && a.x && a.x.o

2. 在ViewModel上增加函數方法(推薦).

「快應用篇02」快應用開發時,優化總結篇

JSON.parse()解析出錯: 在遇到伺服器端權限校驗失敗等問題時,會傳回類似503的HTML頁面,此時JSON解析肯定就會失敗.

1. 在每個JSON.parse()代碼執行處進行try-catch包圍,處理出錯情況

2. 在app.ux中提前使用try-catch包圍(推薦)

「快應用篇02」快應用開發時,優化總結篇

回調函數中引用ViewModel資料報錯:

例如: 使用者打開 PageA,然後點選連結打開 PageB,PageB 中執行接口方法(如 fetch 請求),然後立即傳回到 PageA;此時接口的回調函數傳回,但 PageB 已經出棧銷毀,此時,執行開發者傳遞的回調函數報錯 這是由于,回調函數中通路了一些ViewModel的資料等,而這些ViewModel的資料屬性已經伴随着頁面銷毀而删除了,是以引起報錯.

報錯資訊為:undefined:217: TypeError: Cannot read property 'xx' of null

1. 在回調函數執行之前,通過ViewModel對象的$valid判斷頁面狀态

2. 在Function.prototype上定義方法,關聯到每個回調函數綁定ViewModel執行個體(推薦)

堆棧溢出問題:

通過$element(id)擷取到内容并指派給成員變量,可能會引發堆棧溢出(RangeError: Maximum call stack size exceeded)進而導緻程式崩潰,同時成員變量發生變化時,即會引發堆棧溢出報錯問題.

這是因為指派為VM屬性,會觸發資料驅動變化,導緻内部出現異常循環,進而引發堆棧溢出報錯.

解決方案: 避免$element(id)擷取到的内容直接指派給成員變量,而是指派給局部變量或全局變量的形式.

「快應用篇02」快應用開發時,優化總結篇

總結

  1. 針對頁面布局元件的使用來看,盡量減少無用備援DOM結構和層級嵌套.對于清單和多頁面切換展示盡可能的懶加載.
  2. 業務子產品主要通過良好的結構優化盡可能的代碼複用減少頁面數量以較少rpk包的體積,同時提升項目可維護性,保證頁面渲染性能,減少不必要的代碼耦合.

本公衆号“大前端早讀”内容範圍圍繞大前端,更多原創文章請關注我們,并點選内容系列--原創篇,學習更多:

「快應用篇02」快應用開發時,優化總結篇

部落格園作者:herry菌,原文連結:

https://www.cnblogs.com/wuhairui/p/11642398.html

朋友,看到這裡,關注作者的公衆号吧,不漏掉更新哦

「快應用篇02」快應用開發時,優化總結篇