內(nèi)容來(lái)源:2017年3月11日,周偉鵬在“H5夢(mèng)工廠(chǎng)”進(jìn)行《京東小程序的三生三世》演講分享。IT大咖說(shuō)作為獨(dú)家視頻合作方,經(jīng)主辦方和講者審閱授權(quán)發(fā)布。閱讀字?jǐn)?shù):2211 | 3分鐘閱讀摘要作為中國(guó)最大的自營(yíng)式電商企業(yè), ...
內(nèi)容來(lái)源: 2017年3月11日,周偉鵬在“H5夢(mèng)工廠(chǎng)”進(jìn)行《京東小程序的三生三世》演講分享。IT大咖說(shuō)作為獨(dú)家視頻合作方,經(jīng)主辦方和講者審閱授權(quán)發(fā)布。
閱讀字?jǐn)?shù):2211 | 3分鐘閱讀
作為中國(guó)最大的自營(yíng)式電商企業(yè),京東小程序的開(kāi)發(fā)也是一波三折。
“不是每個(gè)人都能看透這三生三世的愛(ài)恨交織。”
嘉賓演講視頻地址: t.cn/R9Vtevu
之前京東購(gòu)物入口的首頁(yè)還是比較復(fù)雜的,現(xiàn)在首頁(yè)簡(jiǎn)化到只有搜索和領(lǐng)券的功能。
用完即走,觸手可及。
輕量、突出重點(diǎn),快速直達(dá)用戶(hù)的核心需求。
優(yōu)秀的操作體驗(yàn)。
作為開(kāi)發(fā)者來(lái)說(shuō),小程序需要WXML、WXSS和JS三部分。WXML和WXSS組成了view層,負(fù)責(zé)view層的渲染。JS組成了manager層,JS負(fù)責(zé)整個(gè)小程序的邏輯部分。
WXML和WXSS負(fù)責(zé)配置部分,小程序的view層其實(shí)還是Web view的形式。Manger是在app service的部分。
頁(yè)面可以通過(guò)JSbridge和app service進(jìn)行交互,也可以調(diào)用一些native組件。
Manager也是通過(guò)JSbridge,額外有一個(gè)單獨(dú)封裝的API,就可以直接通過(guò)API調(diào)用native組件。
小程序的實(shí)現(xiàn)方式是通過(guò)小程序JSbridge的API,獲取原來(lái)Web組件的信息,在Webview上蓋了一層native的組件。
小程序里具有native能力的組件大概有canvas、video、input、textarea、map和picker。這幾個(gè)組件在小程序里是以native的形式展現(xiàn)出來(lái)。
優(yōu)點(diǎn) :
小程序具有native的能力,有掃碼、離線(xiàn)、地圖之類(lèi)的功能。
它接近原生應(yīng)用的用戶(hù)體驗(yàn)。
它是類(lèi)似Web的開(kāi)發(fā)語(yǔ)言,入門(mén)門(mén)檻低。
提供大量常用組件,開(kāi)發(fā)成本低。
自帶ES6支持。
限制 :
無(wú)法訪(fǎng)問(wèn)到真實(shí)的DOM節(jié)點(diǎn)。
無(wú)法綁定原生事件。
更新需要發(fā)版本,微信審核。
技術(shù)預(yù)研 :前期我們做了大量的技術(shù)預(yù)研。閱讀一些官方文檔、事例代碼,動(dòng)手編寫(xiě)demo,也讓一些同事組織了內(nèi)部技術(shù)分享。
組件開(kāi)發(fā)團(tuán)隊(duì) :我們的開(kāi)發(fā)團(tuán)隊(duì)前端是四個(gè)人,“后臺(tái)”開(kāi)發(fā)有六個(gè)人。
確定結(jié)構(gòu)及分工 :
我們把小程序分為page和models、API兩部分。
前端主要負(fù)責(zé)page部分,包括頁(yè)面重構(gòu)、數(shù)據(jù)渲染、用戶(hù)交互邏輯等等。
Models和API這層是“后臺(tái)”開(kāi)發(fā)負(fù)責(zé)的,它們主要負(fù)責(zé)數(shù)據(jù)的獲取、加工,提供公共的API。
制定開(kāi)發(fā)規(guī)范:我們制定了命名規(guī)范、接口規(guī)范、樣式規(guī)范、文檔規(guī)范、文件目錄規(guī)范和git分支規(guī)范。
我們?cè)陂_(kāi)發(fā)小程序的時(shí)候遇到的第一個(gè)問(wèn)題就是運(yùn)行環(huán)境里沒(méi)有cookie,導(dǎo)致后臺(tái)接口無(wú)法驗(yàn)證登錄態(tài)。
利用本地存儲(chǔ)的能力,在獲得網(wǎng)絡(luò)請(qǐng)求的時(shí)候拿到cookie,存到local storage里。下次發(fā)網(wǎng)絡(luò)請(qǐng)求的時(shí)候,再?gòu)膕torage里拿出cookie,手動(dòng)添加到header里,實(shí)現(xiàn)了手動(dòng)cookie的過(guò)程。
第二個(gè)問(wèn)題是wx.request的合法域名最多為10個(gè),導(dǎo)致其他域名下的業(yè)務(wù)請(qǐng)求失敗。
因?yàn)榫〇|業(yè)務(wù)分散,域名很多,一個(gè)頁(yè)面需要調(diào)用大量API接口,這些API都散落在不同的域名下面。
我們配置了一臺(tái)nginx,培植了一個(gè)新域名專(zhuān)門(mén)供小程序進(jìn)行域名的轉(zhuǎn)發(fā),把需要用到的域名全都映射到新域名的路徑里,這樣就可以把大量域名合并到一個(gè)或幾個(gè)很小的域名里,成功繞過(guò)了限制。
wx.request的并發(fā)數(shù)不能超過(guò)5個(gè),導(dǎo)致并發(fā)能力受限,超出限制時(shí)請(qǐng)求失敗。
傳統(tǒng)方式是通過(guò)page直接和Server進(jìn)行交互。有了小程序限制之后,我們?cè)谥虚g加入了WS Server,就可以把請(qǐng)求包裝到Websocket里,Websocket再通過(guò)轉(zhuǎn)發(fā)到Server,Server返回?cái)?shù)據(jù)后再通過(guò)Websocket的形式回到前面的小程序。
因?yàn)槲⑿旁С諻ebsocket,并發(fā)數(shù)也比較高,基本滿(mǎn)足了并發(fā)的需求。
微信小程序頁(yè)面層級(jí)最多為5個(gè),這就會(huì)導(dǎo)致像京東購(gòu)物這樣比較復(fù)雜的頁(yè)面層級(jí)達(dá)到上限時(shí)頁(yè)面跳轉(zhuǎn)無(wú)響應(yīng)。
提前做好頁(yè)面層級(jí)關(guān)系的梳理,保證頁(yè)面邏輯在5層之內(nèi)。
小程序只能通過(guò)page對(duì)象來(lái)進(jìn)行頁(yè)面內(nèi)容的修改,加大了UI組件的開(kāi)發(fā)難度。
京東的小程序開(kāi)發(fā)是把組件完全獨(dú)立出來(lái),每個(gè)組件都擁有自己的JS、WXML和WXSS。利用組件自己的JS,setData到WXML,WXML通過(guò)事件回調(diào)的方式回調(diào)到自己的JS。
組件開(kāi)發(fā)完之后WXML通過(guò)import+template的方式引用到頁(yè)面的WXML里。JS通過(guò)require的方式引入頁(yè)面。
小程序的程序包大小不能超過(guò)1MB,使很多功能受限。對(duì)于電商應(yīng)用,1MB確實(shí)不太夠。
我們當(dāng)時(shí)有想過(guò)將JS腳本內(nèi)容通過(guò)接口請(qǐng)求,然后用eval執(zhí)行,或是把模版文件內(nèi)容通過(guò)接口獲取后,動(dòng)態(tài)插入到頁(yè)面中。但是微信在這方面有許多限制,eval等能動(dòng)態(tài)執(zhí)行JS語(yǔ)句的函數(shù)被禁用,模版文件內(nèi)容無(wú)法動(dòng)態(tài)添加。
“Getthe hardest part done first.”這里的the hardest part我們當(dāng)時(shí)首先想到的是圖片。
京東有一套比較好的圖片系統(tǒng),它是基于京東分布式文件系統(tǒng)JFS和CDN系統(tǒng)的一個(gè)包括存儲(chǔ)、圖片的在線(xiàn)處理、緩存分發(fā)的圖片系統(tǒng)。
利用CDN域名來(lái)分散請(qǐng)求,從而擴(kuò)大并行下載數(shù);
按需加載不同尺寸的圖片;
使用Webp圖片格式;
根據(jù)當(dāng)前網(wǎng)絡(luò)狀況請(qǐng)求不同壓縮質(zhì)量的圖片。
小程序本地存儲(chǔ)的文件是像HTML、CSS、IMG和JS這類(lèi)靜態(tài)資源。
利用小程序的能力,通過(guò)上一個(gè)頁(yè)面直接把首屏需要展現(xiàn)的頁(yè)面?zhèn)鞯较乱粋€(gè)頁(yè)面。在打開(kāi)新頁(yè)面的時(shí)候,靜態(tài)資源和接口數(shù)據(jù)都已經(jīng)有了,就可以直接展現(xiàn)出來(lái)。
搜索列表頁(yè)通過(guò)回收屏幕外的節(jié)點(diǎn)來(lái)保持滑動(dòng)的流暢性。
我們用事件的方式做了一個(gè)page間的通信,支付成功后會(huì)觸發(fā)一個(gè)事件,通知到前面需要訂閱它的頁(yè)面去更新自己的狀態(tài)。
Page是通過(guò)Websocket的方式和Server進(jìn)行交互的,但因?yàn)橛脩?hù)的網(wǎng)絡(luò)情況是不確定的,導(dǎo)致有時(shí)候小程序會(huì)連不到Websocket。這時(shí)我們會(huì)在小程序里自動(dòng)切到備份的HTTPS的服務(wù)器,通過(guò)HTTPS服務(wù)器和Server正常地進(jìn)行交互,保證了小程序的穩(wěn)定性。
在一些不確定的情況下,小程序有可能出現(xiàn)報(bào)錯(cuò)之類(lèi)的情況。微信給我們提供了onError的API,通過(guò)這個(gè)API可以捕獲到小程序的一些錯(cuò)誤,然后我們就能把這些錯(cuò)誤信息提交到monitor上,根據(jù)監(jiān)控平臺(tái)反饋的數(shù)據(jù)對(duì)這些錯(cuò)誤進(jìn)行不斷優(yōu)化和迭代。
把基礎(chǔ)類(lèi)服務(wù)打包,給其它小程序做引用。
我的分享到此結(jié)束,謝謝大家!