前言
眾所周知膏潮,iOS的網(wǎng)頁(yè)組件很封閉万俗,基本就是基于WKWebview修修改改〉莼Γ看起來(lái)能做的不多勇蝙,但是一個(gè)好的webview容器沫勿,其實(shí)能做的事情還有很多。今天想聊一下味混,一個(gè)好的webview的容器产雹,除了自己本身的功能,還需要哪些設(shè)計(jì)翁锡。
1.jsbridge的設(shè)計(jì)
wk很容易就可以使用jsbridge蔓挖,只要在configuration.userContentController
注入調(diào)用名
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
在js中附上剛面的name就可以調(diào)用了,非常方便
window.webkit.messageHandlers.name.postMessage()
同時(shí)也可以在想要的時(shí)間點(diǎn)(一般在初始過(guò)程)注入JS馆衔。
[userContentController addUserScript:[[WKUserScript alloc] initWithSource:script
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
forMainFrameOnly:YES]];
健全的容器瘟判,需要健全的bridge方法怨绣,比如容器的版本,基礎(chǔ)的設(shè)備信息等等拷获。業(yè)務(wù)功能比如照片選擇器篮撑、圖片瀏覽器、原生掃碼頁(yè)匆瓜、藍(lán)牙等等赢笨,都可以按需加入。當(dāng)然光提供bridge驮吱,幾個(gè)還好茧妒,一旦多起來(lái),他們就需要體系左冬,接收方法需要統(tǒng)一入口嘶伟,交由容器解析,有一套健全的派發(fā)邏輯又碌,因?yàn)閚ative的方法代碼可能散落在工程各處。返回結(jié)果需要統(tǒng)一出口绊袋,由容器統(tǒng)一格式返回毕匀。
而在js端調(diào)用的過(guò)程中需要規(guī)范調(diào)用的格式,入?yún)⒌囊?guī)則癌别,成功和失敗的回調(diào)規(guī)則皂岔。當(dāng)native執(zhí)行完畢之后,需要告知js側(cè)結(jié)果展姐。
2.同層渲染
讓網(wǎng)頁(yè)擁有原生組件的能力躁垛,這是近兩年比較火的同層渲染技術(shù)。
市面上的實(shí)現(xiàn)原理也已經(jīng)比較成熟圾笨,具體實(shí)現(xiàn)可以看微信這篇小程序同層渲染原理剖析寫的非常詳細(xì)教馆。
github上也有相關(guān)的源碼級(jí)別實(shí)現(xiàn)。iOS的做法來(lái)說(shuō)相對(duì)來(lái)說(shuō)“trick”一些擂达,而android在實(shí)現(xiàn)上會(huì)更加復(fù)雜一點(diǎn)土铺。
3.離線加載
故名思議通過(guò)加載本地的資源進(jìn)行網(wǎng)頁(yè)的渲染,達(dá)到網(wǎng)頁(yè)秒開的效果板鬓。
在這其中悲敷,資源的動(dòng)態(tài)的下發(fā)是比較重要的一環(huán),下發(fā)的時(shí)間點(diǎn)俭令,如何正確的命中用戶都是需要做的課題后德。后續(xù)數(shù)據(jù)的追溯,命中情況等都需要監(jiān)控抄腔。
當(dāng)然瓢湃,資源的管理是一方面理张,如果正確識(shí)別需要加載的URL繞過(guò)網(wǎng)絡(luò)去加載本地的資源的這個(gè)過(guò)程同樣需要精細(xì)化設(shè)計(jì)。WKWebView的請(qǐng)求攔截箱季,網(wǎng)上基本說(shuō)爛了涯穷,這篇文章基本是結(jié)貼WKWebView 請(qǐng)求攔截探索與實(shí)踐。市面上思路都差不多藏雏,"WKWebView不支持http拷况、https攔截"、"Body丟失"掘殴、"Cookie同步"這些問(wèn)題只要花時(shí)間都是有解的赚瘦。
補(bǔ)充:關(guān)于body丟失的問(wèn)題,不管是用NSURLProtocol
或者WKURLSchemeHandler
奏寨,基本都是需要js端配合hook XMLHTTPRequest
起意,只需在容器啟動(dòng)從native注入hook的js,對(duì)前端同學(xué)同樣也是透明的病瞳,沒(méi)有負(fù)擔(dān)揽咕。
4.性能穩(wěn)定監(jiān)控
基本的性能監(jiān)控不能少,統(tǒng)計(jì)網(wǎng)頁(yè)從打開到顯示的時(shí)間套菜,網(wǎng)頁(yè)加載完畢時(shí)候統(tǒng)計(jì)是否是白屏等等亲善。
也可以通過(guò)一些網(wǎng)頁(yè)的屬性傳給網(wǎng)頁(yè)進(jìn)行統(tǒng)計(jì)比如window.performance
補(bǔ)充:白屏的幾種判別方法:1.截圖像素點(diǎn)的判斷。2.遍歷dom節(jié)點(diǎn)查看是否有正常子節(jié)點(diǎn)逗柴。
5.預(yù)熱
今日頭條的詳情頁(yè)部分是通過(guò)WKWebView進(jìn)行渲染的蛹头,好的用戶體驗(yàn)的一個(gè)很重要的點(diǎn)就是wk的預(yù)熱和復(fù)用,詳見參考中的鏈接戏溺。
6.其他
大的塊暫時(shí)能想到的就這么多渣蜗,剩下的定制化功能其實(shí)還有很多,開發(fā)者可以不斷地往上壘旷祸,治理好bridge是關(guān)鍵耕拷,比如容器可以支持查看js日志,并且在線調(diào)試托享,增加一些對(duì)navibar斑胜,navibaritem,橫屏嫌吠,手勢(shì)等進(jìn)行設(shè)置的功能止潘,又比如將網(wǎng)頁(yè)一些耗時(shí)任務(wù)交給native處理,在體驗(yàn)上也會(huì)有不錯(cuò)的效果辫诅。
總結(jié)
相比于flutter凭戴,我其實(shí)更崇尚基于native + h5的這種hybrid開發(fā),隨著h5的體驗(yàn)越來(lái)越好炕矮,其實(shí)這種開發(fā)方式已經(jīng)是目前主流的開發(fā)模式了么夫,不管是從效率者冤、易用、容錯(cuò)等方面都是一個(gè)相當(dāng)不錯(cuò)的選擇档痪。
參考
今日頭條品質(zhì)優(yōu)化 - 圖文詳情頁(yè)秒開實(shí)踐