Mobile Bridge:讓 WebView 擁有原生體驗(yàn)
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
前言 如何解決傳統(tǒng) WebView 所面臨的三大核心問(wèn)題 —— 性能、外觀和集成性,以及 Mobile Bridge 如何成為我們移動(dòng)開(kāi)發(fā)策略中的關(guān)鍵轉(zhuǎn)折點(diǎn),甚至幫助我們加速向 React Native 的遷移。今日前端早讀課文章由 @Mauricio de Meirelles 分享,@飄飄編譯。
Shopify 的移動(dòng)應(yīng)用大約有 600 個(gè)界面,雖然這些界面都對(duì)商家使用移動(dòng)端體驗(yàn)有所貢獻(xiàn),但并不是每個(gè)界面對(duì)日常操作都同樣重要。 對(duì)于那些關(guān)鍵界面,我們毫無(wú)疑問(wèn)地選擇使用原生或 React Native 來(lái)開(kāi)發(fā),以確保提供最好的使用體驗(yàn)。但如果將同樣的開(kāi)發(fā)方式應(yīng)用到其他不那么關(guān)鍵的界面上,代價(jià)就非常高昂,同時(shí)還會(huì)嚴(yán)重拖慢開(kāi)發(fā)進(jìn)度。 我們的挑戰(zhàn)很明確:我們需要一種高效的方式,把這些 “非關(guān)鍵” 界面集成到移動(dòng)應(yīng)用中,而不需要再為 Web 和移動(dòng)端分別開(kāi)發(fā)。 WebView 看起來(lái)是一個(gè)合理的選擇,但它往往難以提供良好的用戶體驗(yàn) —— 經(jīng)常顯得慢、不流暢,而且跟原生界面風(fēng)格不一致,容易讓人感覺(jué)脫節(jié)。 我們不滿足于這些限制,而是把它當(dāng)作一次機(jī)會(huì):我們是否能 “重塑” WebView,讓它更快、更美觀、看起來(lái)更像原生界面?這也正是我們創(chuàng)建 Mobile Bridge 框架的出發(fā)點(diǎn)。這個(gè)框架專門(mén)用來(lái)增強(qiáng) WebView,讓網(wǎng)頁(yè)內(nèi)容可以無(wú)縫融入我們的移動(dòng)應(yīng)用。 在這篇文章中,我們會(huì)分享我們是如何解決傳統(tǒng) WebView 在性能、外觀和集成方面的主要問(wèn)題,以及 Mobile Bridge 如何成為我們移動(dòng)開(kāi)發(fā)策略中的關(guān)鍵工具,甚至幫助我們加速向 React Native 的遷移。 WebView 的難題WebView 一直不被看好,主要是因?yàn)橛脩粢谎劬湍芸闯鏊皇?App 的原生部分。它們看起來(lái)脫節(jié)、運(yùn)行緩慢,給人不好的使用體驗(yàn)。
為了改善這些問(wèn)題,我們啟動(dòng)了一個(gè)項(xiàng)目,設(shè)定了三個(gè)關(guān)鍵目標(biāo):
1、讓 WebView 更快 ??我們首先著手找出 WebView 為什么加載緩慢。結(jié)果發(fā)現(xiàn),主要問(wèn)題出在認(rèn)證流程上。每次加載 Web 頁(yè)面時(shí),WebView 都要經(jīng)過(guò)好幾次跳轉(zhuǎn)來(lái)完成身份驗(yàn)證,這就導(dǎo)致了明顯的延遲。 為了解決這個(gè)問(wèn)題,我們提出了一個(gè)簡(jiǎn)單的方案:在應(yīng)用啟動(dòng)時(shí),就在后臺(tái)預(yù)加載并完成 WebView 的身份認(rèn)證。 為此,我們分別為 iOS 和 Android 構(gòu)建了原生模塊,可以實(shí)現(xiàn)以下功能:
通過(guò)這種方式,我們將 WebView 的加載時(shí)間提升了大約 6 倍 ——P75(75% 用戶體驗(yàn)到的加載時(shí)間)從 6 秒縮短到 1.4 秒,這其中包括了網(wǎng)絡(luò)延遲和頁(yè)面渲染時(shí)間。
左圖為優(yōu)化前,右圖為優(yōu)化后 2、讓 WebView 看起來(lái)更像原生界面在解決了性能問(wèn)題之后,我們開(kāi)始著手提升 WebView 的外觀和使用感受,重點(diǎn)是去除那些讓它看起來(lái)不像原生界面的元素。我們主要改進(jìn)了以下幾個(gè)方面:
經(jīng)過(guò)這些改進(jìn),我們的 WebView 在視覺(jué)風(fēng)格和交互方式上更加接近原生界面,遵循了統(tǒng)一的用戶體驗(yàn)設(shè)計(jì)標(biāo)準(zhǔn)。 優(yōu)化前(左)與優(yōu)化后(右)對(duì)比圖 3、讓 WebView 用起來(lái)更像原生界面想要讓 WebView 真正 “用起來(lái)像原生應(yīng)用”,關(guān)鍵是要實(shí)現(xiàn) Web 與移動(dòng)端之間的簡(jiǎn)單通信。它們需要能夠輕松地共享數(shù)據(jù)、追蹤用戶操作,并快速做出響應(yīng),比如知道用戶何時(shí)導(dǎo)航、完成了什么操作,或者頁(yè)面發(fā)生了哪些變化。 為此,我們開(kāi)發(fā)了 Mobile Bridge 框架,它基于 Shopify 的 @remote-ui/rpc 庫(kù),能夠在 Web 與移動(dòng)端之間建立順暢的雙向通信通道。 解決頁(yè)面標(biāo)題和操作問(wèn)題 我們首先處理的是標(biāo)題欄的問(wèn)題。在原生應(yīng)用中,頁(yè)面的標(biāo)題和操作按鈕(如 “保存”、“編輯”)通常顯示在導(dǎo)航欄,而不是頁(yè)面本身。為了讓 WebView 與這一原生模式一致,我們?cè)?Mobile Bridge 中設(shè)計(jì)了可以設(shè)置標(biāo)題欄和操作按鈕的 API。 接著,我們修改了 Polaris 的 Page 組件,讓它將自己的標(biāo)題和操作按鈕傳送給 Mobile Bridge,然后由 Mobile Bridge 將它們渲染到原生導(dǎo)航欄中。這樣一來(lái),WebView 瞬間看起來(lái)更像原生界面了。
解決 WebView 中的導(dǎo)航問(wèn)題 導(dǎo)航功能是另一個(gè)關(guān)鍵挑戰(zhàn)。在瀏覽器中,點(diǎn)擊鏈接通常會(huì)重新加載整個(gè)頁(yè)面,但原生應(yīng)用則是將新頁(yè)面 “壓入” 導(dǎo)航堆棧中。如果我們每次導(dǎo)航都創(chuàng)建一個(gè)新的 WebView,就會(huì)導(dǎo)致用戶的會(huì)話數(shù)據(jù)和動(dòng)態(tài)內(nèi)容丟失,體驗(yàn)既慢又令人沮喪。 為了解決這個(gè)問(wèn)題,我們開(kāi)發(fā)了一個(gè)名為 TransportableView 的新組件。它可以讓我們?cè)谄聊恢g “移動(dòng)” 現(xiàn)有的 WebView,而不丟失任何狀態(tài)或數(shù)據(jù)。TransportableView 可以把當(dāng)前 WebView 實(shí)例直接轉(zhuǎn)移到另一個(gè)屏幕上使用,這樣即使用戶返回上一個(gè)頁(yè)面,也不會(huì)丟失任何內(nèi)容或連接。 處理返回導(dǎo)航的問(wèn)題 TransportableView 成功解決了 “前進(jìn)導(dǎo)航” 的問(wèn)題,因?yàn)槲覀兛偸窃?WebView 進(jìn)入新頁(yè)面時(shí)展示一個(gè)全屏加載動(dòng)畫(huà),用戶不會(huì)看到前一頁(yè)的內(nèi)容短暫出現(xiàn)。 但如果是 “返回導(dǎo)航” 呢?如果不加處理,用戶在返回或預(yù)覽某些頁(yè)面時(shí)可能會(huì)看到空白或損壞的界面,這就破壞了我們想要實(shí)現(xiàn)的原生體驗(yàn)。 為了解決這個(gè)問(wèn)題,我們?cè)?WebView 移動(dòng)前會(huì)快速拍一張當(dāng)前界面的 “快照”。當(dāng)用戶返回時(shí),先顯示這張靜態(tài)圖片,確保界面內(nèi)容是完整的。等到實(shí)際的 WebView 完全加載好之后,我們?cè)賹⑦@張快照移除。 iOS 上快照的捕捉與還原示意圖:
以原生方式處理彈窗(Modal) Web 頁(yè)面中的彈窗通常是覆蓋在當(dāng)前內(nèi)容之上的,而在移動(dòng)應(yīng)用中,彈窗通常作為獨(dú)立的屏幕出現(xiàn),并伴隨原生的過(guò)渡動(dòng)畫(huà)。為了與這一行為保持一致,我們將彈窗處理為原生屏幕,并通過(guò)和前文頁(yè)面跳轉(zhuǎn)相同的方式來(lái)傳遞 WebView。 其中一個(gè)關(guān)鍵優(yōu)化是:我們對(duì) Polaris 的 Modal 組件進(jìn)行了自定義處理,讓它在原生動(dòng)畫(huà)完成之后再開(kāi)始渲染內(nèi)容。這樣能保持過(guò)渡過(guò)程流暢,避免內(nèi)容閃爍。
更進(jìn)一步的優(yōu)化 在做完上述優(yōu)化后,我們的 WebView 已經(jīng)有了巨大的提升,但我們并沒(méi)有就此止步。為了讓體驗(yàn)更加無(wú)縫,我們還把已有的原生功能直接集成到了 WebView 中。 一個(gè)很好的例子就是日期選擇器(Date Picker)。我們的很多分析類頁(yè)面都采用 WebView,而日期選擇器是查看報(bào)表的重要交互。雖然 Web 上的日期選擇器在瀏覽器中運(yùn)行良好,但在 App 里卻不夠 “原生”。既然我們已有原生版本的日期選擇器組件,我們就通過(guò) Mobile Bridge 把它集成進(jìn) WebView。 這種將原生與 Web 元素融合的方式,讓用戶體驗(yàn)變得更加自然、順暢。 優(yōu)化前(左)與優(yōu)化后(右)對(duì)比圖 我們還讓 WebView 可以無(wú)縫調(diào)用原生功能。現(xiàn)在,Web 內(nèi)容不僅能直接觸發(fā)原生界面,還能輕松地獲取返回結(jié)果。 在我們目前的應(yīng)用中,已有一些實(shí)際應(yīng)用場(chǎng)景,例如:
條碼掃描器(左)和添加到錢(qián)包功能(右) 這種混合式方案讓我們能夠快速推出基于 Web 的新功能,同時(shí)為用戶提供更豐富、更接近原生體驗(yàn)的使用感受。 Mobile Bridge 的未來(lái)發(fā)展目前,Mobile Bridge 可以讓 Web 觸發(fā)原生界面元素,但這些原生元素必須事先在 App 中實(shí)現(xiàn)。這在一定程度上限制了發(fā)布速度,也讓舊版本的 App 無(wú)法享受到新功能的升級(jí)。 為了解決這個(gè)問(wèn)題,我們正在嘗試使用 Shopify 的 remote-dom 技術(shù),讓 Polaris 組件可以通過(guò) Web 代碼在 App 中以原生方式渲染。 這種方式可以讓我們?cè)诒A魳I(yè)務(wù)邏輯在 Web 端的同時(shí),把界面組件交由原生端渲染。這樣不僅帶來(lái)更大的靈活性,還顯著提升了整個(gè)混合應(yīng)用的用戶體驗(yàn)。 下面是我們基于這一方案構(gòu)建的原型示例,你能猜出哪一部分是 WebView,哪一部分是原生的嗎?
Mobile Bridge:Shopify 的變革者Mobile Bridge 所帶來(lái)的改進(jìn)是如此顯著,以至于 WebView 現(xiàn)在已經(jīng)成為我們移動(dòng)端開(kāi)發(fā)戰(zhàn)略中不可或缺的一部分。我們大量使用 WebView 來(lái)實(shí)現(xiàn)重要但非關(guān)鍵的功能,從而避免在 Web 和移動(dòng)端重復(fù)開(kāi)發(fā)。 而對(duì)于應(yīng)用中所有關(guān)鍵功能,我們?nèi)匀粓?jiān)持使用原生或 React Native 來(lái)提供最優(yōu)質(zhì)的體驗(yàn)。 我們已經(jīng)將 Mobile Bridge 開(kāi)源為一個(gè)獨(dú)立的庫(kù),并開(kāi)始將其整合進(jìn) Shopify 的其他產(chǎn)品中,比如 Balance、POS 和 Shop。這意味著更多應(yīng)用也能采用這種強(qiáng)大的混合開(kāi)發(fā)模式,從而享受到更快的開(kāi)發(fā)周期和更好的用戶體驗(yàn)。 Mobile Bridge 徹底改變了我們對(duì) Web 與移動(dòng)集成方式的看法 —— 它讓我們可以擁有 Web 開(kāi)發(fā)的靈活性與速度,同時(shí)為用戶提供接近原生的流暢體驗(yàn)。它還釋放了大量工程資源,讓我們能將更多精力投入到提升關(guān)鍵原生界面的質(zhì)量上。 閱讀原文:原文鏈接 該文章在 2025/5/26 12:30:08 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |