一、原因
1、問題背景原因
任何手機設備上,當手機內存不足時,os都會回收資源。一般是先回收后台打開的資源。如果當前應用占用的資源過高,當前應用也有可能崩潰。尤其是在調用攝像頭點擊拍照時,手機內存占用會達到一個峰值,此時較容易出問題。
iOS上當內存不足時,根據uiwebview和wkwebview的不同,它自身有不同的回收策略。
- 如果是uiwebview的app(常見於5+app),內存不足時整個app會崩潰,即閃退。
- 如果是wkwebview的app(uni-app和wap2app在iOS上默認就是wkwebview),內存不足時,單個wkwebview會崩潰。也就是所謂的應用還在,而頁面白屏。
這個問題在所有使用wkwebview的應用都會出現,比如微信的公眾號網頁里也存在。在微信小程序里,它做了一個自動恢復手段,可以讓jscore存儲數據狀態,崩潰的wkwebview自動恢復。所以在遇到問題時,會白一下然后恢復渲染。
2、在前端減少內存使用的注意
最重要的注意,就是圖片渲染,尤其是大圖片。
在頁面上不要渲染多張大圖,比如從攝像頭或相冊選擇多張圖,並縮放尺寸渲染在頁面上,雖然肉眼看起來手機屏幕上是幾張小圖,但實際上是多張大圖只是被縮小,這種情況非常耗費內存。一張圖片3m,9張這樣的大圖同時渲染到屏幕上,什么手機都受不了。
一個縮略圖控制在幾k或十幾k,才是合理的。
詳情頁面展現多張大圖並不受影響。如果圖片滾動在屏幕外,os內存不足時也會自動收回這些屏幕外圖片占用的渲染資源,最吃資源的就是同屏渲染多張大圖。
二、解決方案
- uni-app因為引入了獨立的jscore處理數據狀態,jscore不會崩潰,所以官方采用了和微信小程序一致的策略,補充自動的白屏恢復能力。
- uni-app中也可以使用nvue來避免這個問題,nvue頁面不會出現內存不足引發的白屏崩潰。
- 5+app、wap2app,一方面注意前端代碼寫法,減低內存使用。另外HBuilder2.3.4+開始支持配置WKWebview內核奔潰是重新啟動應用還是重新加載頁面的配置,但整體而言,5+app和wap2app在WKWebview下問題很多,還有各種跨域限制,還是建議開發者盡快升級為uni-app。
1、iOS平台5+APP/WAP2APP使用WKWebview內核時由於內核崩潰引起白屏后自動恢復的方法
HBuilderX 2.3.4+版本已將iOS上所有webview的默認內核由UIWebview調整為WKWebview請參考https://ask.dcloud.net.cn/article/36348,當內存占用過大或者應用切換到后台內存被回收會導致WKWebview內核Crash引起應用白屏,為了提高體驗App支持Crash后的恢復,開發者可以通過簡單的配置支持該功能。
注意:
(1)目前該功能針對在前台的應用,如果應用在后台時會直接重新啟動不適用該規則
(2)uniapp有自己的恢復邏輯不適用該規則
2、支持的恢復行為
- "restart":重啟應用,關閉所有頁面重新打開應用首頁,可通過(plus.runtime.isRecovery)來判斷應用是否恢復重啟
- "reload":重新加載當前WKWebview(崩潰的WKWebview)頁面,頁面中JS上下文中所有數據丟失,在當前Webview中可通過plus.webview.isRecovery判斷是否恢復重新加載,在其它Webview中可監聽recovery事件來判斷
- "none":不做任何操作
3、全局配置
在manifest.json中配置默認值
"plus": { //uni-app項目對應節點名稱為"app-plus"
"kernel": { "ios": "WKWebview", "recovery": "restart|reload|none" }, // ...
}
4、webview配置
webview style新增kernelRecovery屬性,通過該項可以自定義單個webview的恢復行為,覆蓋全局配置。引用文檔
var webview = plus.webview.create("[url]","[id]", {kernelRecovery:"restart|reload|none"});
5、API
(1)plus.webview.isRecovery:用於判斷當前Webview窗口是否由於內核崩潰自動恢復,當配置reload時生效。引用文檔
(2)plus.runtime.isRecovery:用於判斷當前應用是否是Webview崩潰自動恢復導致的啟動,當配置restart時生效。引用文檔
6、事件
recovery:當恢復行為配置為reload時,webview重新創建完成后會觸發該事件,可以監聽該事件做具體處理。引用文檔