相信最近幾天,大家都被微信小程序(MINA)內(nèi)測(cè)開(kāi)始的新聞引爆了朋友圈,甚至因此引發(fā)了js的學(xué)習(xí)狂潮(笑)。有幸作為早期參與進(jìn)來(lái)的自選股攻關(guān)小分隊(duì)的我們,內(nèi)心也是激動(dòng)不已 ...
相信最近幾天,大家都被微信小程序(MINA)內(nèi)測(cè)開(kāi)始的新聞引爆了朋友圈,甚至因此引發(fā)了js的學(xué)習(xí)狂潮(笑)。有幸作為早期參與進(jìn)來(lái)的自選股攻關(guān)小分隊(duì)的我們,內(nèi)心也是激動(dòng)不已,希望可以盡早給大家分享一些開(kāi)發(fā)經(jīng)驗(yàn)和踩過(guò)的坑。不過(guò)呢,由于MINA的開(kāi)發(fā)權(quán)限還沒(méi)有完全放開(kāi),有一些具體的內(nèi)容還在保密階段,我們?cè)谡髑罅宋⑿砰_(kāi)平同事的同意后,將開(kāi)發(fā)過(guò)程中的一些經(jīng)驗(yàn)和改進(jìn)方案整理出來(lái),希望可以對(duì)其他開(kāi)發(fā)者提供一些參考。
引用一段官方介紹:
MINA是微信提供的一套應(yīng)用框架,通過(guò)封裝微信客戶端提供的文件系統(tǒng)、網(wǎng)絡(luò)通信、任務(wù)管理、數(shù)據(jù)安全等基礎(chǔ)功能,對(duì)上層提供了一套完整的Javascript Api,使得開(kāi)發(fā)者能夠非常方便的使用到微信客戶端提供的各種基礎(chǔ)功能,快速構(gòu)建一個(gè)應(yīng)用。
在頁(yè)面視圖層,我們使用wxml搭建頁(yè)面的基本視圖框架,使用css控制頁(yè)面的視圖樣式。wxml是MINA提供的一套類似html的標(biāo)簽語(yǔ)言,同時(shí)也提供了一系列的基礎(chǔ)組件,幫助我們快速構(gòu)建視圖。在頁(yè)面中不能使用腳本代碼,頁(yè)面渲染所需要的數(shù)據(jù),以及頁(yè)面的交互處理邏輯都是在AppService中。我們提供了很方法將AppService中的數(shù)據(jù)與頁(yè)面進(jìn)行單向綁定,當(dāng)AppService中的數(shù)據(jù)變更時(shí),會(huì)主動(dòng)觸發(fā)對(duì)應(yīng)的頁(yè)面組件的重新渲染,這里使用virtual-dom的技術(shù),加快頁(yè)面的渲染效率。同時(shí)我們?yōu)轫?yè)面組件提供了bindtap、bindtouchstart等事件監(jiān)聽(tīng)相關(guān)的屬性,可以與AppService中的提供的事件處理函數(shù)綁定在一起。實(shí)現(xiàn)頁(yè)面向AppService層同步用戶的交互數(shù)據(jù)。
AppService是每個(gè)MINA的服務(wù)中心,由微信客戶端在頁(yè)面視圖層外啟用異步線程單獨(dú)加載運(yùn)行,MINA中所有使用javascript編寫的交互邏輯、網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)處理都必須在AppService中實(shí)現(xiàn),且AppService中不能使用DOM操作相關(guān)的腳本代碼。應(yīng)用中的各個(gè)頁(yè)面可以通過(guò)AppService實(shí)現(xiàn)數(shù)據(jù)管理、網(wǎng)絡(luò)通訊、應(yīng)用生命周期管理和頁(yè)面路由管理。
所以有了這么棒的底層框架,我們才更有信心把自選股這么重的應(yīng)用搬到小程序里。
微信小程序除了在底層架構(gòu)的運(yùn)行機(jī)制做了大量的優(yōu)化,還對(duì)重功能(page切換、tab切換、多媒體、網(wǎng)絡(luò)連接等)實(shí)際上是更傾向于使用native組件承載。而對(duì)于自選股來(lái)說(shuō),除了大量的數(shù)據(jù),行情圖的展示也是不可缺少的一環(huán)。而如果沒(méi)有原生繪圖組件的支持,那么這樣的重功能一定會(huì)影響到速度,從而降低用戶體驗(yàn)。
由于自選股的行情圖是自研的前端模塊,里面涉及到坐標(biāo)系、幾何圖形、技術(shù)指標(biāo)等大量模塊,我們希望能夠在盡可能少的修改代碼就可以平滑的在小程序環(huán)境下完美運(yùn)行。因此我們主動(dòng)與微信開(kāi)平團(tuán)隊(duì)交流,推動(dòng)了Canvas Native的組件化流程,并共同構(gòu)思了Canvas Native的語(yǔ)法、圖形API的支持。
做過(guò)H5的前端開(kāi)發(fā)一定對(duì)截圖的Canvas語(yǔ)法不陌生。
(canvas原生寫法)
(協(xié)商討論后的支持寫法)
可以看到,繪圖語(yǔ)法基本沒(méi)有變化,其中wx.createContent()是創(chuàng)建并返回繪圖上下文context對(duì)象。 其中,context只是一個(gè)記錄方法調(diào)用的容器,用于生成記錄繪制行為的actions數(shù)組。context跟canvas不存在對(duì)應(yīng)關(guān)系,一個(gè)context生成畫布的繪制動(dòng)作數(shù)組可以應(yīng)用于多個(gè)canvas。而context.getActions()是獲取當(dāng)前context上存儲(chǔ)的繪圖動(dòng)作。輸出結(jié)果如下:
最后一步,使用wx.drawCanvas()進(jìn)行繪圖。
MINA的定位是輕量的、用完即走的,我們也配合著微信貫徹這一理念。隨著MINA版本的更迭,自選股小程序也及時(shí)調(diào)整著自身的方向,越來(lái)越凸顯出其不同于App的特性。
一方面,盡量減少需要多屏互動(dòng)的場(chǎng)景出現(xiàn),這也就是說(shuō),很多情況下我們需要在一屏上呈現(xiàn)更多的數(shù)據(jù),針對(duì)大量數(shù)據(jù)我們做出了如下優(yōu)化:
數(shù)據(jù)層優(yōu)化: 自選股產(chǎn)品本來(lái)就是數(shù)據(jù)驅(qū)動(dòng)的產(chǎn)品,而且要求數(shù)據(jù)實(shí)時(shí)性很高,在開(kāi)盤的時(shí)候頁(yè)面股票數(shù)據(jù)實(shí)時(shí)更新
優(yōu)化 1:setData 函數(shù)用于將數(shù)據(jù)從邏輯層發(fā)送到視圖層,同時(shí)改變對(duì)應(yīng)的 this.data 的值
改變String
this.setData({ text: '自選股'})
改變Array
var changeData = {};var index = 0;changeData['array[' + index + '].text'] = '自選股';this.setData(changeData);
改變Object
this.setData({ 'object.text': '自選股'})
這里需要注意的是:
1、直接修改 this.data 無(wú)效,無(wú)法改變頁(yè)面的狀態(tài),還會(huì)造成數(shù)據(jù)不一致
2、單次設(shè)置的數(shù)據(jù)不能超過(guò)1024kB,請(qǐng)盡量避免一次設(shè)置過(guò)多的數(shù)據(jù)
對(duì)于以上情況,我們的處理與優(yōu)化方法是:
1、減少setData的數(shù)據(jù)量
2、對(duì)setData數(shù)據(jù)分段處理
優(yōu)化 2:本地緩存,即每個(gè)微信小程序可以有自己的本地緩存
對(duì)于緩存的獲取、設(shè)置、清除,小程序分別提供了同步與異步的方法。
為了增強(qiáng)體驗(yàn),我們?cè)赑age的生命周期 onLoad(頁(yè)面加載) onHide(頁(yè)面隱藏) onUnload(頁(yè)面卸載)函數(shù)里面添加緩存載入、設(shè)置,提高應(yīng)用首次展示速度,加快頁(yè)面與頁(yè)面之間數(shù)據(jù)的通用性,提升用戶在弱網(wǎng)絡(luò)環(huán)境下體驗(yàn)。
后端優(yōu)化: 另一方面,鑒于MINA本身微信場(chǎng)景的限制,很多native app可以使用的特性在MINA這里并不支持,針對(duì)這樣的實(shí)際情況,我們暫時(shí)做了如下的兼容方式。
優(yōu)化1:小程序?qū)W(wǎng)絡(luò)請(qǐng)求接口域名有明確要求。針對(duì)4種服務(wù)器域名(request、socket、uploadfile、downloadfile)每種只能指定一個(gè)合法域名。自選股后臺(tái)業(yè)務(wù)十分復(fù)雜,使用了不同域名對(duì)業(yè)務(wù)進(jìn)行劃分。應(yīng)對(duì)這個(gè)限制,自選股通過(guò)統(tǒng)一代理方式將域名收斂為一個(gè)域名,由代理層將請(qǐng)求轉(zhuǎn)發(fā)。
優(yōu)化2:微信小程序文檔中要求wx.request網(wǎng)絡(luò)請(qǐng)求發(fā)起的是https請(qǐng)求,自選股在統(tǒng)一代理層部署證書(shū)支持https請(qǐng)求,后端RS機(jī)器無(wú)需改動(dòng)。
優(yōu)化3:小程序并發(fā)請(qǐng)求數(shù)不超過(guò)5,自選股使用動(dòng)態(tài)接口將頁(yè)面需要的數(shù)據(jù)進(jìn)行合并,通過(guò)一個(gè)接口獲取頁(yè)面所需數(shù)據(jù)。
優(yōu)化4:小程序關(guān)于登錄態(tài)與移動(dòng)應(yīng)用和網(wǎng)頁(yè)應(yīng)用的不同之處是拋棄了access_token的驗(yàn)證方式,而是采用session_key加簽名的方式,為小程序與服務(wù)器交換敏感數(shù)據(jù)提供了對(duì)稱加密方法。簽名方法對(duì)小程序透明,后端服務(wù)實(shí)現(xiàn)相應(yīng)的解密程序以及登錄態(tài)驗(yàn)證和控制能力。
綜上所述,微信小程序MINA有著接近原生app的運(yùn)行速度,做了大量的框架層面的優(yōu)化設(shè)計(jì),對(duì)android端和iOS端做出了高度一致的呈現(xiàn),并且準(zhǔn)備了完備的開(kāi)發(fā)和調(diào)試工具。感謝微信開(kāi)平的同事,他們的不懈努力為眾多開(kāi)發(fā)者們打開(kāi)了一扇新世界的大門。也很佩服開(kāi)平的同學(xué)們,我們?cè)陂_(kāi)發(fā)溝通過(guò)程中提出來(lái)的多數(shù)建議都能夠快速的響應(yīng)并支持,給了我們非常大的成就感!
而對(duì)于更多的開(kāi)發(fā)者來(lái)說(shuō),JS語(yǔ)言的低入門門檻、迅速的調(diào)試發(fā)布流程、完備的API文檔和微信強(qiáng)大的平臺(tái)能力更是讓人欲罷不能。我們從MINA誕生至今跟隨其一同演化發(fā)展,互相促進(jìn)支撐,過(guò)程中MINA框架結(jié)構(gòu)幾經(jīng)山崩地裂的調(diào)整,所有頁(yè)面在前一秒還是好好的,更新開(kāi)發(fā)工具后面目全非。但,很幸運(yùn)的是,現(xiàn)在工具已經(jīng)趨于完善穩(wěn)定,大家可以盡情地“玩耍”啦~~~最后還是要說(shuō),我們的開(kāi)發(fā)過(guò)程盡管荊棘滿布,我們?nèi)跃o追不舍,在短短的兩個(gè)月時(shí)間內(nèi),不斷推翻、不斷重構(gòu)、不斷打磨體驗(yàn)細(xì)節(jié),終于完成了自選股小程序的基本核心需求,初步形成了一個(gè)閉環(huán)。