提公升html5的效能體驗系列之一避免切頁白屏

2022-09-17 04:57:13 字數 3511 閱讀 1974

標準html5無法解決,我們就使用擴充套件的手段。

html5+是一套增強html5的規範,它可以用js呼叫幾十萬原生api。

想要解決切頁白屏這個問題,需要使用plus.webview類來做mpa多頁應用。

plus.webview類是對原生的webview物件的js化封裝,使用js可以操作webview。

解決白屏的原理是:把每個頁面當作乙個webview,但用js來控制它就像控制div一樣。

因為webview可以隱式建立,後台載入內容,並且在載入完畢時有js事件通知,我們可以在新頁面載入完成後再把它通過動畫移入螢幕,從而避免白屏。

同時webview之間相互獨立,不會出現spa下不同頁面js和css衝突的問題。

通過操作webview來避免切頁白屏,有幾種常見的做法:

一種是稱之為預載,即後台預載新頁面的html檔案及資源,使用時直接調出這個已經建立好的webview;

另一種稱之為現載,即點選前頁的鏈結開始走waiting轉圈,同時後台開始載入完整的新頁面,載入完再用js控制顯示到前台。

還有一種稱之為分開載入,隨後會細講。

- 1、預載入

varwebviewshow;document.addeventlistener('plusready',function());functionclicklist (id)

在mui框架裡,對這個過程進行了簡化封裝,使用preload引數來控制。參考:

- 2、現載

所謂現載,就是使用者點選時後台建立webview載入新頁面完整內容,渲染後再顯示到前台

有時我們無法使用預載,為了避免白屏,就要等待新webview完成後再通過動畫把它移進來。

當點選list頁面的item時,首先通過plus.nativeui.waiting()來彈出乙個等待框。

緊接著在後台create乙個webview,載入show頁面。

show頁面在後台聯網獲取資料。

show頁面在資料解析渲染後,有兩種方式通知list頁面。

一種是在list頁面註冊show頁面的webview的loaded**,在新webview載入完成後系統會自動觸發loaded事件。

還有一種是在show頁面合適的js位置通過evaljs方法通知list頁面關閉等待框,並執行窗體切換把show頁面顯示出來。

當然show頁面也可以不通知list頁面,而是自己直接關閉等待框,並呼叫窗體切換動畫把自己顯示出來。

示例**如下:

functionclicklist (id),false);}

需要注意的是,為了減少窗體切換的等待,一般不在點選後使用webview的create方法,因為建立過程也有時間消耗。

比較好的方法是提前建立乙個webview,需要載入頁面時使用webview的loadurl方法來載入。

如果中間還是出現白屏,可以通過延遲顯示新webview來解決。

目前官方演示demo裡,把新webview移入進來是在新webview的loaded**中做的,這個時機相當於新頁面的domcontentloaded時機,即dom tree完成但頁面未必渲染完畢。

此時可以settimeout延遲新webview的顯示動畫,也可以乾脆不在上級頁面操作顯示動畫,而是在下級頁面的onload或你認為頁面已經渲染完畢的時間來操作把下級頁面用動畫顯示出來。

- 3、head和body分開載入

-4、預截圖

預載入可以避免白屏的發生,但窗體動畫有時還不如預期流暢,有些新窗體移入過程中,還在不停聯網獲取資料,不停重繪介面,導致窗體進入過程感覺卡頓,此時還有乙個高階技巧是截圖動畫。

從hbuilder6.1起,5+ runtime提供了乙個plus.nativeobj.bitmap的物件,同時webview物件提供了乙個截圖方法,可以把webview顯示區域儲存到bitmap物件中。此外webview的動畫方法中支援傳bitmap,這樣給開發者提供了乙個效能調優的手段。

我們可以預載乙個webview,然後把這個webview預先截圖下來,然後在窗體移入時在動畫引數裡傳入儲存這個截圖的bitmap物件,這樣窗體移動時,移動的就不是webview,而是移動的,這樣能讓窗體動畫流暢許多。

當然這個方案也不是萬能,它有利有弊,因而也有其適用場景。

截圖以後圖即固定,窗體動畫過程中,圖不會改變,如果webview自身在變或外部通過evaljs在控制其變化,那動畫過程中無法反應該變化,

mui框架為了簡化窗體管理的工作,把一些常用的窗體模型做了簡化封裝。

但對於複雜的窗體切換,仍需開發者搞明白上面提到的窗體切換原理。

mui的init方法,通過引數封裝了preload和subpage,這樣就可以方便的預載webview,對於head和body分離的雙webivew介面,也可以方便的通過subpage引數來控制webviewbody。

mui的openwindow方法,封裝了顯示waiting,載入新頁面,處理動畫,關閉waiting等工作。

mui的back樣式控制,自動封裝了窗體的隱藏和關閉。

這些方法具體參考mui的js api。

首頁是沒有預載入的概念的。

啟動封面的關閉觸發條件,預設是在首頁的webview的loaded事件發生後關閉。

如果首頁內容較大或聯網後、框架載入後重繪螢幕,即在首頁html的domcontentloaded後無法立即渲染介面,會出現啟動封面消失後,頁面還沒渲染好的情況。

此時需要手動控制封面消失。

首先在工程下manifest.json裡找到plus、splashscreen、autoclose節點,設定為false,即手動控制封面的消失。

然後在首頁合適的位置,一般在聯網並構造完新的dom時,呼叫js關閉封面,plus.n**igator.closesplashscreen();

這樣就能防止第乙個頁面的白屏。

為了節約系統資源,在webview不可見時,我們的引擎缺省會**掉它的渲染資源。

如果頁面複雜、渲染的慢,在返回時可能會因為來不及渲染而造成先模糊後清晰的問題。

此時或者優化頁面寫法,加快渲染。或者使用我們提供的api,使得webview在不可見時一樣不移除渲染資源。

具體api位址見plus.webview的webviewstyle物件裡的render引數,render設為always即可不移除渲染,解決模糊的問題。

另外從hbuilder5.8開始,android上新引入了pop-in動畫,這個動畫效果經過特殊處理,在返回時不會虛一下。

5+runtime預設是開啟android硬體加速的,但android的一些非google官方rom的硬體加速有bug。尤其是android5.0初期的一些rom。

關於這方面的處理方案,單獨起了一篇文章,參考

plus.webview提供了很多切換動畫,上下左右平移、淡入淡出、縮放、擠壓......但比較常用的動畫是右移slide-in-right和擠壓pop-in。

一般在ios上,強烈推薦使用pop-in,更接近原生體驗。

在android上,其實也是pop-in效果更好,但為了達到更好的效果,也需要開發者編碼時注意一些寫法,如果寫不好,效果還不如slide-in-right

這裡是pop-in動畫使用注意:

提公升html5的效能體驗系列之三流暢下拉重新整理

為實現下拉重新整理功能,大多h5框架都是通過div模擬下拉回彈動畫,在低端android手機 android4.4以下 上,div動畫經常出現卡頓現象 特別是 列表的情況 解決方案還是webview。目前這個方案僅在android上實現,ios不存在效能問題,仍然可通過div拉動實現。為了方便開發者...

HTML5學習之 HTML 5 拖放

拖放 drag 和 drop 是 html5 標準的組成部分。拖放是一種常見的特性,即抓取物件以後拖到另乙個位置。在 html5 中,拖放是標準的一部分,任何元素都能夠拖放。internet explorer 9 firefox opera 12 chrome 以及 safari 5 支援拖放。注釋...

HTML5 高階系列 web Storage

html5 的 web storage 儲存方式有兩種 localstorage 和 sessionstorage。這兩種方式都是通過鍵值對儲存資料,訪問方便,不影響 效能。他們的用法相同,儲存時間不同。localstorage 的資料儲存在本地硬體上,可以永久儲存,可以手動呼叫api清除資料。se...