下面我先跟大家介紹下今天演講主要的提綱。
相信在座的很多同學(xué)的產(chǎn)品跟轉(zhuǎn)轉(zhuǎn)小程序經(jīng)歷了類似的發(fā)展過程,我們轉(zhuǎn)轉(zhuǎn)小程序是從去年五月份開始開發(fā)的,那時(shí)候也是小程序剛出來不久,我們就快速用原生語法搭建了個(gè)demo,功能很簡單,就是首頁列表頁詳情頁。
然后我們從7月份開始進(jìn)入了第二個(gè)階段,這時(shí)候各種中大型公司已經(jīng)意識(shí)到了,借助微信的龐大用戶群,小程序是一個(gè)很好的獲客渠道,因此我們也從demo階段正式的開始了小程序開發(fā)。
那時(shí)候我們整個(gè)團(tuán)隊(duì)從北京跑到廣州的微信園區(qū)里面去封閉開發(fā),我們一方面在做小程序版本的轉(zhuǎn)轉(zhuǎn),實(shí)現(xiàn)了交易核心流程,苦苦的做了兩三個(gè)月,DAU始終也漲不上去,另一方面我們也在做很多營銷活動(dòng)的嘗試,我們做了一款簡單的測(cè)試類的小游戲,居然幾天就刷屏了,上百萬的pv,一方面我們很欣喜,另一方面也很尷尬,因?yàn)榇蠹叶际莵硗娴?,不是來交易的,所以我們就開始了第三階段。
這個(gè)階段我們進(jìn)行了大量的開發(fā)工作,讓我們的小程序功能和體驗(yàn)接近了轉(zhuǎn)轉(zhuǎn)APP,那到了今年6月份,我們的小程序進(jìn)入了微信錢包里面,我們的DAU峰值也達(dá)到了千萬級(jí)別,這時(shí)候可以說已經(jīng)成為了一個(gè)風(fēng)口上的新平臺(tái),這個(gè)時(shí)候問題來了,公司的各條線業(yè)務(wù)都開始想接入到小程序里面。
于是乎就有了上面這段對(duì)話。
所以,為了能夠更好接入各業(yè)務(wù)線存量h5頁面和新的活動(dòng)頁,我們開始著手進(jìn)行多端適配的工作。
那我們會(huì)考慮三種開發(fā)方案(我這里只說缺點(diǎn))
在webview這個(gè)組件出來以前,我們是采用第一種方案,用純小程序開發(fā)所有業(yè)務(wù)頁面,那么適合的框架有現(xiàn)在主流的三種,wepy,mpvue、taro,缺點(diǎn)是不夠靈活,開發(fā)成本巨大,真的很累,尤其是業(yè)務(wù)方來找我們想介入小程序,但他們的開發(fā)者又不會(huì)小程序,當(dāng)時(shí)又不能嵌入H5,所以業(yè)務(wù)方都希望我們來開發(fā),所有業(yè)務(wù)都來找,你們可以想想成本又多高,這個(gè)方案肯定是不可行,第二種方案,就是一套代碼編譯出多套頁面,在不同端運(yùn)行,mpvue和taro都可以,我們公司有業(yè)務(wù)團(tuán)隊(duì)在使用mpvue,編譯出來的結(jié)果不是特別理性,一是性能上面沒有達(dá)到理想的狀態(tài),二是api在多端兼容上面二次改造的成本很高,各個(gè)端api差異很大,如果是一個(gè)簡單的活動(dòng)頁還好,但如果是一個(gè)跟端有很大功能交互的頁面,那這種方式其實(shí)很難實(shí)現(xiàn)。
那我們采用的是第三種方案,目前我們的小程序是作為一個(gè)端存在,像app一樣,我們只做首頁、列表、詳情、購買等等核心頁面都是用小程序開發(fā),每個(gè)業(yè)務(wù)的頁面、活動(dòng)運(yùn)營頁面都是H5,并且用webview嵌入,這樣各個(gè)業(yè)務(wù)接入的成本非常低,但這也有缺點(diǎn),1是小程序與h5交互和通信比較麻煩,二是我們的app提供了很大功能支持,這些功能在小程序里面都需要對(duì)應(yīng)的實(shí)現(xiàn)
這張圖是我個(gè)人的理解。(并不代表微信官方的看法)
把webview和小程序在多個(gè)方面做了比對(duì)。
未來除了小程序之外,可能會(huì)多的端存在,比如智能小程序等等,那我們期望的結(jié)果是什么呢,就是一套H5能運(yùn)行于各個(gè)環(huán)境內(nèi)。
這可能是最差的一個(gè)case,h5判斷所在的環(huán)境,去調(diào)用不同api方法,這個(gè)case的問題是,業(yè)務(wù)邏輯特別復(fù)雜,功能耦合非常嚴(yán)重,也基本上沒有什么復(fù)用性。
那我們轉(zhuǎn)轉(zhuǎn)采取的是什么方案呢?
分三塊,小程序端,用WePY框架,H5這塊主要是vue和react,中間通過一個(gè)adapter來連接。我們轉(zhuǎn)轉(zhuǎn)的端特別多,除了小程序還包括純轉(zhuǎn)轉(zhuǎn)app端,58端,趕集端,純微信端,qq端,瀏覽器端,所以H5頁面需要的各種功能,在每個(gè)端都需要對(duì)應(yīng)的功能實(shí)現(xiàn),比如登錄、發(fā)布、支付、個(gè)人中心等等很多功能,這些功能都需要通過adapter這個(gè)中間件進(jìn)行調(diào)用,接下來詳細(xì)來講。
我這里就不貼代碼了,我只講下adapter的原理,首先adapter需要初始化,做兩件事情,一是產(chǎn)出一個(gè)供h5調(diào)用的native對(duì)象,二是需要檢測(cè)當(dāng)前所處的環(huán)境,然后根據(jù)環(huán)境去異步加載sdk文件,這里的關(guān)鍵點(diǎn)是我們要做個(gè)api調(diào)用的隊(duì)列,因?yàn)閟dk加載時(shí)異步的過程,如果期間頁面內(nèi)發(fā)生了api調(diào)用,那肯定得不到正確的響應(yīng),因此你要做個(gè)調(diào)用隊(duì)列,當(dāng)sdk初始化完畢之后再處理這些調(diào)用,其實(shí)adapter原理很簡單,如果你想實(shí)現(xiàn)多端適配,那么只需要根據(jù)所在的環(huán)境去加載不同的sdk就可以了。
做好adapter之后,你需要讓每個(gè)h5的項(xiàng)目都引入adapter文件,并且在調(diào)用api的時(shí)候,都統(tǒng)一在native對(duì)象下面調(diào)用。
我們總結(jié)小程序提供給H5的功能大體分為這四種,第一是基于小程序的五種跳轉(zhuǎn)能力,比如關(guān)閉當(dāng)前頁面。
那我們看到小程序提供了這五種跳轉(zhuǎn)方式。
第二是直接使用微信sdk提供的能力,比如掃碼,這個(gè)比較簡單。第三是h5打開小程序的某些頁面,這個(gè)是最常用的,比如進(jìn)入下單頁等。
對(duì)應(yīng)每個(gè)api,小程序這邊都需要實(shí)現(xiàn)對(duì)應(yīng)的頁面功能,大家看這幾個(gè)圖,skipToChat就是進(jìn)到我們的IM頁面,下面依次是進(jìn)入個(gè)人主頁,訂單詳情頁,下單頁面,其實(shí)我們的小程序開發(fā)的主要工作也是去做這些基礎(chǔ)功能頁面,然后提供給H5,各個(gè)業(yè)務(wù)基本都是H5實(shí)現(xiàn),接入到小程序里面來,我們只做一個(gè)平臺(tái)。
這是進(jìn)入個(gè)人主頁方法的實(shí)現(xiàn),其實(shí)就是進(jìn)入了小程序profile這個(gè)頁面。
第四就是h5與小程序直接的通信能力,這個(gè)比較集中體現(xiàn)在設(shè)置分享信息和登錄這塊。
上面(adapter)做好了以后,在h5這塊調(diào)用就一句話就可以了。
小程序和h5 之間的通信基本上常用兩種方式,一個(gè)是postMessage,這個(gè)方法大家都知道,只有在三種情況才可以觸發(fā),后退、銷毀和分享,但也有個(gè)問題,這個(gè)方法是基礎(chǔ)庫1.7.1才開始支持的,1.7.1以下就只能通過第二種方法來傳遞數(shù)據(jù),也就是設(shè)置和檢測(cè)webview組件的url變化,類似pc時(shí)代的iframe的通信方式。
sdk這塊怎么做呢,定義一個(gè)share方法,首先需要檢測(cè)下基礎(chǔ)庫版本,看是否支持postMessage,如果支持直接調(diào)用,如果不支持,把分享參數(shù)拼接到url當(dāng)中,然后進(jìn)行一次重載,所以說通過url傳遞數(shù)據(jù)有個(gè)缺點(diǎn),就是頁面可能需要刷新一次才能設(shè)置成功。
我們看下分享信息設(shè)置這塊,小程序這端,首先通過bindmessage事件接收h5傳回來的數(shù)據(jù),然后在用戶分享的時(shí)候onShareAppMessage判斷有沒有回傳的數(shù)據(jù),如果沒有就到webviewurl當(dāng)中取,否則就是用默認(rèn)分享數(shù)據(jù)。
h5調(diào)分享這塊,我們也做了一些優(yōu)化,傳統(tǒng)方式是要四步才能掉起分享面板,點(diǎn)頁面里的某個(gè)按鈕,然后給用戶個(gè)提示層,用戶再去點(diǎn)右上角的點(diǎn)點(diǎn)點(diǎn),再點(diǎn)轉(zhuǎn)發(fā),才能拉起分享面板。
我們后來改成了這樣,點(diǎn)分享按鈕,把分享信息帶到一個(gè)專門的小程序頁面,這個(gè)頁面里面放一個(gè)button,type=share,點(diǎn)一下就拉起來面板了,雖然是一個(gè)小小的改動(dòng),但能大幅提高分享成功率的,因?yàn)楹芏嘤脩魧?duì)右上角的點(diǎn)點(diǎn)點(diǎn)不太敏感。
接下來我們看看登錄功能
分兩種情況,接入的H5可能一開始就需要登錄態(tài),也可能開始不需要登錄態(tài)中途需要登錄,這兩種情況我們約定了h5通過自己的url上一個(gè)參數(shù)進(jìn)行控制。
一開始就需要登錄態(tài)的情況,那么在加載webview之前,首先進(jìn)行授權(quán)登錄,然后把登錄信息拼接到url里面,再去來加載webview,在h5里面通過adapter來把登錄信息提取出來并且存到cookie里,這樣h5一進(jìn)來就是有登陸態(tài)的。
一開始不需要登錄態(tài)的情況,一進(jìn)入小程序就直接通過webview加載h5,h5調(diào)用login方法的時(shí)候,把needLogin這個(gè)參數(shù)拼接到url中,然后利用api進(jìn)行重載,就走了第一種情況進(jìn)行授權(quán)登錄了。
第一是你如何區(qū)分h5所在的環(huán)境是小程序里面的webview還是純微信瀏覽器,為什么要區(qū)分呢,因?yàn)槟愕腍5在不同環(huán)境需要不同的api,比如我們的業(yè)務(wù),下單的時(shí)候,如果是小程序,那么我們需要進(jìn)入小程序的下單頁,如果是純微信,我們之間進(jìn)純微信的下單頁,這兩種情況的api實(shí)現(xiàn)是不一樣的,那么為什么難區(qū)分,大家可能知道,小程序的組件分為內(nèi)置組件和原生組件,內(nèi)置組件就是小程序定義的view、scroll-view這些基本的標(biāo)簽,原生組件就是像map啊這種,這其實(shí)是調(diào)用了微信的原生能力,webview也是一種類似原生的組件,為什么說是類似原生的組件,微信并沒有為小程序?qū)iT做一套webview機(jī)制,而是直接用微信本身的瀏覽器,所以小程序webview和微信瀏覽器的內(nèi)核都是一樣的,包括UA頭都是一模一樣,cookie、storage本地存儲(chǔ)數(shù)據(jù)都是互通的,都是一套,因此我們很難區(qū)分具體是在哪個(gè)環(huán)境。
還好微信提供了一個(gè)環(huán)境變量,但這個(gè)變量不是很準(zhǔn)確,加載h5以后第一個(gè)頁面可以及時(shí)拿到,但后續(xù)的頁面都需要在微信的sdk加載完成以后才能拿到,因此建議大家在wx.ready或者是weixinjsbridgeready事件里面去判斷,區(qū)別就在于前者需要加載jweixin.js才有,但這里有坑,坑在于h5的開發(fā)者可能并不知道你這個(gè)檢測(cè)過程需要時(shí)間,是一個(gè)異步的過程,他們可能頁面一加載就需要調(diào)用一些api,這時(shí)候就可能會(huì)出錯(cuò),因此你一定要提供一個(gè)api調(diào)用的隊(duì)列和等待機(jī)制。
第二個(gè)常見問題是支付,因?yàn)樾〕绦騱ebview里面不支持直接掉起微信支付,所以基本上需要支付的時(shí)候,都需要來到小程序里面,支付完再回去。
上面做好了以后,在h5這塊調(diào)用就一句話就可以了。
我們轉(zhuǎn)轉(zhuǎn)的業(yè)務(wù)分兩種支付情況,一是有的業(yè)務(wù)h5有自己完善的交易體系,下單動(dòng)作在h5里面就可以完成,他們只需要小程序付款,因此我們有一個(gè)精簡的支付頁,進(jìn)來直接就拉起微信支付,還有一種情況是業(yè)務(wù)需要小程序提供完整的下單支付流程,那么久可以之間進(jìn)入我們小程序的收銀臺(tái)來,圖上就是sdk里面的基本邏輯,我們通過payOnly這個(gè)參數(shù)來決定進(jìn)到哪個(gè)頁面。
我們?cè)倏聪滦〕绦蚶锩婢喼Ц对趺磳?shí)現(xiàn)的,就是onload之后之間調(diào)用api拉起微信支付,支付成功以后根據(jù)h5傳回來的參數(shù),如果是個(gè)小程序頁面,那之間跳轉(zhuǎn)過去,否則就刷新上一個(gè)webview頁面,然后返回回去。
第三個(gè)問題是formId,webview里面沒有辦法收集formId,這有什么影響呢,沒有formId就沒法發(fā)服務(wù)通知,沒有服務(wù)通知,業(yè)務(wù)就沒辦法對(duì)新用戶進(jìn)行召回,這對(duì)業(yè)務(wù)來講是一個(gè)很大的損失,目前其實(shí)我們也沒有很好的方案收集。
我們目前主要通過兩種方式收集,訪問量比較大的這種webview落地頁,我們會(huì)做一版小程序的頁面或者做一個(gè)小程序的中轉(zhuǎn)頁,只要用戶有任何觸摸頁面的操作,都可以收集到formid,另外一種就是h5進(jìn)入小程序頁面時(shí)候收集,比如支付,IM這些頁面,但并不是每個(gè)用戶都會(huì)進(jìn)到這些頁面的,用戶可能一進(jìn)來看不感興趣,就直接退出了,因此這種方式存在很大的流失。
那怎么解決這種流失呢,我們加了一個(gè)左上角返回的功能,。
首先進(jìn)入的是一個(gè)空白的中轉(zhuǎn)頁,然后進(jìn)入h5頁面,這樣左上角就會(huì)出現(xiàn)返回按鈕了,當(dāng)用戶按左上角的返回按鈕時(shí)候,頁面會(huì)被重載到小程序首頁去,這個(gè)看似簡單又微小的動(dòng)作,對(duì)業(yè)務(wù)其實(shí)有很大的影響,我們看兩個(gè)數(shù)字,經(jīng)過我們的數(shù)據(jù)統(tǒng)計(jì)發(fā)現(xiàn),左上角返回按鈕點(diǎn)擊率高達(dá)70%以上,因?yàn)檫@種落地頁一般是被用戶分享出來的,以前純h5的時(shí)候只能通過左上角返回,所以在小程序里用戶也習(xí)慣如此,第二個(gè)數(shù)字,重載到首頁以后,后續(xù)頁面訪問率有10%以上,這兩個(gè)數(shù)字對(duì)業(yè)務(wù)提升其實(shí)蠻大的。
其實(shí)現(xiàn)原理很簡單,都是通過第二次觸發(fā)onShow時(shí)進(jìn)行處理。
以上就是我今天全部演講的內(nèi)容,謝謝大家!