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