小程式 webview 應用實踐(演講內容整理)丨掘金開發者大會

轉轉_陳龍發表於2018-09-18

image

大家好,我是轉轉開放業務部前端負責人張所勇,今天主要來跟大家分享小程式 webview 方面的問題,但我並不會講小程式的 webview 原理,而我主要想講的是小程式內如何嵌入 H5。

那麼好多同學會想了,不就是用 web-view 元件就可以嵌入了嗎,是的,如果我們們的小程式和 H5 的業務比較簡單,那直接用 webview 接入就好了,但我們公司的 H5 除小程式之外,還執行在轉轉 app、58app、趕集 app 等多個端,如何能實現一套程式碼在多端執行,這是我今天主要想分享的,因此今天分享更適合 H5 頁面比較複雜,存在多端執行情況的開發者,期待能給大家提供一些多端相容的思路。

image

下面我先跟大家介紹下今天演講主要的提綱。

  1. 小程式技術演進
  2. webview VS 小程式
  3. h5 多端相容方案
  4. 小程式 sdk 設計
  5. webview 常見問題

1 轉轉小程式演進過程

image

相信在座的很多同學的產品跟轉轉小程式經歷了類似的發展過程,我們轉轉小程式是從去年五月份開始開發的,那時候也是小程式剛出來不久,我們就快速用原生語法搭建了個 demo,功能很簡單,就是首頁列表頁詳情頁。

然後我們從7月份開始進入了第二個階段,這時候各種中大型公司已經意識到了,藉助微信的龐大使用者群,小程式是一個很好的獲客渠道,因此我們也從 demo 階段正式的開始了小程式開發。

image

那時候我們整個團隊從北京跑到廣州的微信園區裡面去封閉開發,我們一方面在做小程式版本的轉轉,實現了交易核心流程,苦苦的做了兩三個月,DAU 始終也漲不上去,另一方面我們也在做很多營銷活動的嘗試,我們做了一款簡單的測試類的小遊戲,居然幾天就刷屏了,上百萬的 pv,一方面我們很欣喜,另一方面也很尷尬,因為大家都是來玩的,不是來交易的,所以我們就開始了第三階段。

這個階段我們進行了大量的開發工作,讓我們的小程式功能和體驗接近了轉轉 APP,那到了今年6月份,我們的小程式進入了微信錢包裡面,我們的 DAU 峰值也達到了千萬級別,這時候可以說已經成為了一個風口上的新平臺,這個時候問題來了,公司的各條線業務都開始想接入到小程式裡面。

image

於是乎就有了上面這段對話。 所以,為了能夠更好接入各業務線存量 h5 頁面和新的活動頁,我們開始著手進行多端適配的工作。

那我們會考慮三種開發方案(我這裡只說缺點)

image

在 webview 這個元件出來以前,我們是採用第一種方案,用純小程式開發所有業務頁面,那麼適合的框架有現在主流的三種,wepy,mpvue、taro,缺點是不夠靈活,開發成本巨大,真的很累,尤其是業務方來找我們想介入小程式,但他們的開發者又不會小程式,當時又不能嵌入 H5,所以業務方都希望我們來開發,所有業務都來找,你們可以想想成本又多高,這個方案肯定是不可行,第二種方案,就是一套程式碼編譯出多套頁面,在不同端執行,mpvue 和 taro 都可以,我們公司有業務團隊在使用 mpvue,編譯出來的結果不是特別理性,一是效能上面沒有達到理想的狀態,二是 api 在多端相容上面二次改造的成本很高,各個端 api 差異很大,如果是一個簡單的活動頁還好,但如果是一個跟端有很大功能互動的頁面,那這種方式其實很難實現。

那我們採用的是第三種方案,目前我們的小程式是作為一個端存在,像 app 一樣,我們只做首頁、列表、詳情、購買等等核心頁面都是用小程式開發,每個業務的頁面、活動運營頁面都是H5,並且用 webview 嵌入,這樣各個業務接入的成本非常低,但這也有缺點,一是小程式與 h5 互動和通訊比較麻煩,二是我們的 app 提供了很大功能支援,這些功能在小程式裡面都需要對應的實現

2 webview VS 小程式

image

這張圖是我個人的理解。(並不代表微信官方的看法) 把 webview 和小程式在多個方面做了比對。

3 h5多端相容方案

image

未來除了小程式之外,可能會多的端存在,比如智慧小程式等等,那我們期望的結果是什麼呢,就是一套 H5 能執行於各個環境內。

image

這可能是最差的一個 case,h5 判斷所在的環境,去呼叫不同 api 方法,這個 case 的問題是,業務邏輯特別複雜,功能耦合非常嚴重,也基本上沒有什麼複用性。

image

那我們轉轉採取的是什麼方案呢?

分三塊,小程式端,用WePY框架,H5這塊主要是vue和react,中間通過一個adapter來連線。我們轉轉的端特別多,除了小程式還包括純轉轉app端,58端,趕集端,純微信端,qq端,瀏覽器端,所以H5頁面需要的各種功能,在每個端都需要對應的功能實現,比如登入、釋出、支付、個人中心等等很多功能,這些功能都需要通過adapter這個中介軟體進行呼叫,接下來詳細來講。

image

我這裡就不貼程式碼了,我只講下adapter的原理,首先adapter需要初始化,做兩件事情,一是產出一個供h5呼叫的native物件,二是需要檢測當前所處的環境,然後根據環境去非同步載入sdk檔案,這裡的關鍵點是我們要做個api呼叫的佇列,因為sdk載入時非同步的過程,如果期間頁面內發生了api呼叫,那肯定得不到正確的響應,因此你要做個呼叫佇列,當sdk初始化完畢之後再處理這些呼叫,其實adapter原理很簡單,如果你想實現多端適配,那麼只需要根據所在的環境去載入不同的sdk就可以了。

image

做好adapter之後,你需要讓每個h5的專案都引入adapter檔案,並且在呼叫api的時候,都統一在native物件下面呼叫。

4 小程式sdk設計

image

我們總結小程式提供給H5的功能大體分為這四種,第一是基於小程式的五種跳轉能力,比如關閉當前頁面。

image

那我們看到小程式提供了這五種跳轉方式。

image

第二是直接使用微信sdk提供的能力,比如掃碼,這個比較簡單。第三是h5開啟小程式的某些頁面,這個是最常用的,比如進入下單頁等。

image

對應每個api,小程式這邊都需要實現對應的頁面功能,大家看這幾個圖,skipToChat就是進到我們的IM頁面,下面依次是進入個人主頁,訂單詳情頁,下單頁面,其實我們的小程式開發的主要工作也是去做這些基礎功能頁面,然後提供給H5,各個業務基本都是H5實現,接入到小程式裡面來,我們只做一個平臺。

image

這是進入個人主頁方法的實現,其實就是進入了小程式profile這個頁面。

image

第四就是h5與小程式直接的通訊能力,這個比較集中體現在設定分享資訊和登入這塊。

4.1 設定分享

image

上面(adapter)做好了以後,在h5這塊呼叫就一句話就可以了。

image

小程式和h5 之間的通訊基本上常用兩種方式,一個是postMessage,這個方法大家都知道,只有在三種情況才可以觸發,後退、銷燬和分享,但也有個問題,這個方法是基礎庫1.7.1才開始支援的,1.7.1以下就只能通過第二種方法來傳遞資料,也就是設定和檢測webview元件的url變化,類似pc時代的iframe的通訊方式。

image

sdk這塊怎麼做呢,定義一個share方法,首先需要檢測下基礎庫版本,看是否支援postMessage,如果支援直接呼叫,如果不支援,把分享引數拼接到url當中,然後進行一次過載,所以說通過url傳遞資料有個缺點,就是頁面可能需要重新整理一次才能設定成功。

image

我們看下分享資訊設定這塊,小程式這端,首先通過bindmessage事件接收h5傳回來的資料,然後在使用者分享的時候onShareAppMessage判斷有沒有回傳的資料,如果沒有就到webviewurl當中取,否則就是用預設分享資料。

image

h5調分享這塊,我們也做了一些優化,傳統方式是要四步才能調起分享皮膚,點頁面裡的某個按鈕,然後給使用者個提示層,使用者再去點右上角的點點點,再點轉發,才能拉起分享皮膚。

image

我們後來改成了這樣,點分享按鈕,把分享資訊帶到一個專門的小程式頁面,這個頁面裡面放一個button,type=share,點一下就拉起來皮膚了,雖然是一個小小的改動,但能大幅提高分享成功率的,因為很多使用者對右上角的點點點不太敏感。

4.2 登入

接下來我們看看登入功能

image

分兩種情況,接入的H5可能一開始就需要登入態,也可能開始不需要登入態中途需要登入,這兩種情況我們約定了h5通過自己的url上一個引數進行控制。

  1. 一開始就需要登入態的情況,那麼在載入webview之前,首先進行授權登入,然後把登入資訊拼接到url裡面,再去來載入webview,在h5裡面通過adapter來把登入資訊提取出來並且存到cookie裡,這樣h5一進來就是有登陸態的。

  2. 一開始不需要登入態的情況,一進入小程式就直接通過webview載入h5,h5呼叫login方法的時候,把needLogin這個引數拼接到url中,然後利用api進行過載,就走了第一種情況進行授權登入了。

5 webview常見問題

5.1 區分環境

第一是你如何區分h5所在的環境是小程式裡面的webview還是純微信瀏覽器,為什麼要區分呢,因為你的H5在不同環境需要不同的api,比如我們的業務,下單的時候,如果是小程式,那麼我們需要進入小程式的下單頁,如果是純微信,我們直接進純微信的下單頁,這兩種情況的api實現是不一樣的,那麼為什麼難區分,大家可能知道,小程式的元件分為內建元件和原生元件,內建元件就是小程式定義的view、scroll-view這些基本的標籤,原生元件就是像map啊這種,這其實是呼叫了微信的原生能力,webview也是一種類似原生的元件,為什麼說是類似原生的元件,微信並沒有為小程式專門做一套webview機制,而是直接用微信本身的瀏覽器,所以小程式webview和微信瀏覽器的核心都是一樣的,包括UA頭都是一模一樣,cookie、storage本地儲存資料都是互通的,都是一套,因此我們很難區分具體是在哪個環境。

image

還好微信提供了一個環境變數,但這個變數不是很準確,載入h5以後第一個頁面可以及時拿到,但後續的頁面都需要在微信的sdk載入完成以後才能拿到,因此建議大家在wx.ready或者是weixinjsbridgeready事件裡面去判斷,區別就在於前者需要載入jweixin.js才有,但這裡有坑,坑在於h5的開發者可能並不知道你這個檢測過程需要時間,是一個非同步的過程,他們可能頁面一載入就需要呼叫一些api,這時候就可能會出錯,因此你一定要提供一個api呼叫的佇列和等待機制。

5.2 支付

第二個常見問題是支付,因為小程式webview裡面不支援直接調起微信支付,所以基本上需要支付的時候,都需要來到小程式裡面,支付完再回去。

image

上面做好了以後,在h5這塊呼叫就一句話就可以了。

image

我們轉轉的業務分兩種支付情況,一是有的業務h5有自己完善的交易體系,下單動作在h5裡面就可以完成,他們只需要小程式付款,因此我們有一個精簡的支付頁,進來直接就拉起微信支付,還有一種情況是業務需要小程式提供完整的下單支付流程,那麼久可以直接進入我們小程式的收銀臺來,圖上就是sdk裡面的基本邏輯,我們通過payOnly這個引數來決定進到哪個頁面。

image

我們再看下小程式裡面精簡支付怎麼實現的,就是onload之後直接呼叫api拉起微信支付,支付成功以後根據h5傳回來的引數,如果是個小程式頁面,那直接跳轉過去,否則就重新整理上一個webview頁面,然後返回回去。

5.3 formId收集

第三個問題是formId,webview裡面沒有辦法收集formId,這有什麼影響呢,沒有formId就沒法發服務通知,沒有服務通知,業務就沒辦法對新使用者進行召回,這對業務來講是一個很大的損失,目前其實我們也沒有很好的方案收集。

image

我們目前主要通過兩種方式收集,訪問量比較大的這種webview落地頁,我們會做一版小程式的頁面或者做一個小程式的中轉頁,只要使用者有任何觸控頁面的操作,都可以收集到formId,另外一種就是h5進入小程式頁面時候收集,比如支付,IM這些頁面,但並不是每個使用者都會進到這些頁面的,使用者可能一進來看不感興趣,就直接退出了,因此這種方式存在很大的流失。

5.4 左上角返回

那怎麼解決這種流失呢,我們加了一個左上角返回的功能。

image

首先進入的是一個空白的中轉頁,然後進入h5頁面,這樣左上角就會出現返回按鈕了,當使用者按左上角的返回按鈕時候,頁面會被過載到小程式首頁去,這個看似簡單又微小的動作,對業務其實有很大的影響,我們看兩個數字,經過我們的資料統計發現,左上角返回按鈕點選率高達70%以上,因為這種落地頁一般是被使用者分享出來的,以前純h5的時候只能通過左上角返回,所以在小程式裡使用者也習慣如此,第二個數字,過載到首頁以後,後續頁面訪問率有10%以上,這兩個數字對業務提升其實蠻大的。

image

其實現原理很簡單,都是通過第二次觸發onShow時進行處理。

以上就是我今天全部演講的內容,謝謝大家!

image

這是我們“大轉轉FE”的公眾號。裡面發表了很多FE和小程式方向的原創文章。感興趣的同學可以關注一下,如果有問題可以在文章底部留言,我們共同探討。

同時也感謝掘金舉辦了這次大會,讓我有機會同各位同仁進行交流。在未來的前端道路上,與大家共勉!

相關文章