相信最近幾天,大家都被微信小程序(MINA)內(nèi)測開始的新聞引爆了朋友圈,甚至因此引發(fā)了js的學習狂潮(笑)。有幸作為早期參與進來的自選股攻關(guān)小分隊的我們,內(nèi)心也是激動不已 ...
相信最近幾天,大家都被微信小程序(MINA)內(nèi)測開始的新聞引爆了朋友圈,甚至因此引發(fā)了js的學習狂潮(笑)。有幸作為早期參與進來的自選股攻關(guān)小分隊的我們,內(nèi)心也是激動不已,希望可以盡早給大家分享一些開發(fā)經(jīng)驗和踩過的坑。不過呢,由于MINA的開發(fā)權(quán)限還沒有完全放開,有一些具體的內(nèi)容還在保密階段,我們在征求了微信開平同事的同意后,將開發(fā)過程中的一些經(jīng)驗和改進方案整理出來,希望可以對其他開發(fā)者提供一些參考。

引用一段官方介紹:
MINA是微信提供的一套應用框架,通過封裝微信客戶端提供的文件系統(tǒng)、網(wǎng)絡通信、任務管理、數(shù)據(jù)安全等基礎功能,對上層提供了一套完整的Javascript Api,使得開發(fā)者能夠非常方便的使用到微信客戶端提供的各種基礎功能,快速構(gòu)建一個應用。
在頁面視圖層,我們使用wxml搭建頁面的基本視圖框架,使用css控制頁面的視圖樣式。wxml是MINA提供的一套類似html的標簽語言,同時也提供了一系列的基礎組件,幫助我們快速構(gòu)建視圖。在頁面中不能使用腳本代碼,頁面渲染所需要的數(shù)據(jù),以及頁面的交互處理邏輯都是在AppService中。我們提供了很方法將AppService中的數(shù)據(jù)與頁面進行單向綁定,當AppService中的數(shù)據(jù)變更時,會主動觸發(fā)對應的頁面組件的重新渲染,這里使用virtual-dom的技術(shù),加快頁面的渲染效率。同時我們?yōu)轫撁娼M件提供了bindtap、bindtouchstart等事件監(jiān)聽相關(guān)的屬性,可以與AppService中的提供的事件處理函數(shù)綁定在一起。實現(xiàn)頁面向AppService層同步用戶的交互數(shù)據(jù)。
AppService是每個MINA的服務中心,由微信客戶端在頁面視圖層外啟用異步線程單獨加載運行,MINA中所有使用javascript編寫的交互邏輯、網(wǎng)絡請求、數(shù)據(jù)處理都必須在AppService中實現(xiàn),且AppService中不能使用DOM操作相關(guān)的腳本代碼。應用中的各個頁面可以通過AppService實現(xiàn)數(shù)據(jù)管理、網(wǎng)絡通訊、應用生命周期管理和頁面路由管理。
所以有了這么棒的底層框架,我們才更有信心把自選股這么重的應用搬到小程序里。
微信小程序除了在底層架構(gòu)的運行機制做了大量的優(yōu)化,還對重功能(page切換、tab切換、多媒體、網(wǎng)絡連接等)實際上是更傾向于使用native組件承載。而對于自選股來說,除了大量的數(shù)據(jù),行情圖的展示也是不可缺少的一環(huán)。而如果沒有原生繪圖組件的支持,那么這樣的重功能一定會影響到速度,從而降低用戶體驗。
由于自選股的行情圖是自研的前端模塊,里面涉及到坐標系、幾何圖形、技術(shù)指標等大量模塊,我們希望能夠在盡可能少的修改代碼就可以平滑的在小程序環(huán)境下完美運行。因此我們主動與微信開平團隊交流,推動了Canvas Native的組件化流程,并共同構(gòu)思了Canvas Native的語法、圖形API的支持。
做過H5的前端開發(fā)一定對截圖的Canvas語法不陌生。

(canvas原生寫法)

(協(xié)商討論后的支持寫法)
可以看到,繪圖語法基本沒有變化,其中wx.createContent()是創(chuàng)建并返回繪圖上下文context對象。 其中,context只是一個記錄方法調(diào)用的容器,用于生成記錄繪制行為的actions數(shù)組。context跟canvas不存在對應關(guān)系,一個context生成畫布的繪制動作數(shù)組可以應用于多個canvas。而context.getActions()是獲取當前context上存儲的繪圖動作。輸出結(jié)果如下:

最后一步,使用wx.drawCanvas()進行繪圖。

MINA的定位是輕量的、用完即走的,我們也配合著微信貫徹這一理念。隨著MINA版本的更迭,自選股小程序也及時調(diào)整著自身的方向,越來越凸顯出其不同于App的特性。
一方面,盡量減少需要多屏互動的場景出現(xiàn),這也就是說,很多情況下我們需要在一屏上呈現(xiàn)更多的數(shù)據(jù),針對大量數(shù)據(jù)我們做出了如下優(yōu)化:
數(shù)據(jù)層優(yōu)化: 自選股產(chǎn)品本來就是數(shù)據(jù)驅(qū)動的產(chǎn)品,而且要求數(shù)據(jù)實時性很高,在開盤的時候頁面股票數(shù)據(jù)實時更新
優(yōu)化 1:setData 函數(shù)用于將數(shù)據(jù)從邏輯層發(fā)送到視圖層,同時改變對應的 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 無效,無法改變頁面的狀態(tài),還會造成數(shù)據(jù)不一致
2、單次設置的數(shù)據(jù)不能超過1024kB,請盡量避免一次設置過多的數(shù)據(jù)
對于以上情況,我們的處理與優(yōu)化方法是:
1、減少setData的數(shù)據(jù)量
2、對setData數(shù)據(jù)分段處理
優(yōu)化 2:本地緩存,即每個微信小程序可以有自己的本地緩存
對于緩存的獲取、設置、清除,小程序分別提供了同步與異步的方法。

為了增強體驗,我們在Page的生命周期 onLoad(頁面加載) onHide(頁面隱藏) onUnload(頁面卸載)函數(shù)里面添加緩存載入、設置,提高應用首次展示速度,加快頁面與頁面之間數(shù)據(jù)的通用性,提升用戶在弱網(wǎng)絡環(huán)境下體驗。
后端優(yōu)化: 另一方面,鑒于MINA本身微信場景的限制,很多native app可以使用的特性在MINA這里并不支持,針對這樣的實際情況,我們暫時做了如下的兼容方式。
優(yōu)化1:小程序?qū)W(wǎng)絡請求接口域名有明確要求。針對4種服務器域名(request、socket、uploadfile、downloadfile)每種只能指定一個合法域名。自選股后臺業(yè)務十分復雜,使用了不同域名對業(yè)務進行劃分。應對這個限制,自選股通過統(tǒng)一代理方式將域名收斂為一個域名,由代理層將請求轉(zhuǎn)發(fā)。
優(yōu)化2:微信小程序文檔中要求wx.request網(wǎng)絡請求發(fā)起的是https請求,自選股在統(tǒng)一代理層部署證書支持https請求,后端RS機器無需改動。
優(yōu)化3:小程序并發(fā)請求數(shù)不超過5,自選股使用動態(tài)接口將頁面需要的數(shù)據(jù)進行合并,通過一個接口獲取頁面所需數(shù)據(jù)。
優(yōu)化4:小程序關(guān)于登錄態(tài)與移動應用和網(wǎng)頁應用的不同之處是拋棄了access_token的驗證方式,而是采用session_key加簽名的方式,為小程序與服務器交換敏感數(shù)據(jù)提供了對稱加密方法。簽名方法對小程序透明,后端服務實現(xiàn)相應的解密程序以及登錄態(tài)驗證和控制能力。
綜上所述,微信小程序MINA有著接近原生app的運行速度,做了大量的框架層面的優(yōu)化設計,對android端和iOS端做出了高度一致的呈現(xiàn),并且準備了完備的開發(fā)和調(diào)試工具。感謝微信開平的同事,他們的不懈努力為眾多開發(fā)者們打開了一扇新世界的大門。也很佩服開平的同學們,我們在開發(fā)溝通過程中提出來的多數(shù)建議都能夠快速的響應并支持,給了我們非常大的成就感!
而對于更多的開發(fā)者來說,JS語言的低入門門檻、迅速的調(diào)試發(fā)布流程、完備的API文檔和微信強大的平臺能力更是讓人欲罷不能。我們從MINA誕生至今跟隨其一同演化發(fā)展,互相促進支撐,過程中MINA框架結(jié)構(gòu)幾經(jīng)山崩地裂的調(diào)整,所有頁面在前一秒還是好好的,更新開發(fā)工具后面目全非。但,很幸運的是,現(xiàn)在工具已經(jīng)趨于完善穩(wěn)定,大家可以盡情地“玩耍”啦~~~最后還是要說,我們的開發(fā)過程盡管荊棘滿布,我們?nèi)跃o追不舍,在短短的兩個月時間內(nèi),不斷推翻、不斷重構(gòu)、不斷打磨體驗細節(jié),終于完成了自選股小程序的基本核心需求,初步形成了一個閉環(huán)。