用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

小程序社區 首頁 教程 查看內容

騰訊在線教育小程序開發實踐之路

Rolan 2019-7-2 00:08

作者于2019年6月21日赴北京GMTC大前端技術會議小程序專場,分享話題《騰訊在線教育小程序開發實踐之路》演講稿一、騰訊在線教育小程序矩陣首先介紹下騰訊在線教育下的3個主要業務:面向成人職業化,興趣化學習的騰訊 ...

作者于2019年6月21日赴北京GMTC大前端技術會議小程序專場,分享話題《騰訊在線教育小程序開發實踐之路》演講稿

一、騰訊在線教育小程序矩陣

首先介紹下騰訊在線教育下的3個主要業務:

  • 面向成人職業化,興趣化學習的騰訊課堂
  • 面向小學,初高中k12領域的企鵝輔導
  • 面向少兒英語學習的ABCmouse

每個業務下都有PC Web,客戶端,H5,APP這幾端,來滿足學生的多端上課需求。但由于教育的前身是基于QQ群視頻孵化出來的,后續也是圍繞QQ生態去搭建產品形態,所以在流量上面,QQ相關的流量占比較多。

我們希望能夠通過小程序生態,來為教育業務帶來微信端流量的增長,并且優化學生的微信端上課體驗,所以我們打造了在線教育的小程序矩陣。

我們通過工具,內容型的小程序,來獲取流量。比如騰訊課堂打開小程序,騰訊微課堂,企鵝速算,口語拼讀等工具型小程序,并最終轉化到平臺小程序上。

二、小程序基礎架構設計及工程化探索

上面提到的那么多小程序,我們是如何進行框架選型 以及團隊在多人協作的開發中,是如何制定統一的開發規范,小程序工程化的探索呢?下面將一一介紹。

框架選型時,我們對小程序幾大主流開發框架,taro, wepy, mpvue跟原生開發框架進行了對比。可以看出原生框架在CSS預處理,多端復用,管理,自動構建這幾塊能力對比其他框架是欠缺到。但考慮到以下幾點,我們比較傾向于使用原生框架進行開發:

  • 小程序的特性更新迭代速度較快,我們希望能最快使用上最新特性,其他第三方框架可能會有迭代滯后到問題
  • 我們的多端復用需求較弱
  • 對性能調優,問題排查要求較高,希望直接操控原生API

那么以上這些開發上的缺陷,使用原生框架是否可以解決,如何解決呢?

1,CSS預處理

首先來看CSS預處理,我們是期望能夠在小程序中使用到CSS預處理,包括嵌套語法,mixin,變量等以及styleLint等工具。 經過調研后,我們可以直接使用postcss來寫樣式文件并編譯處理成wxss。

并且通過引入插件,可以解決小程序樣式開發中的痛點。比如postcss-url解決background-image不支持本地圖片問題,將其變成base64格式;通過postcss-font-base64插件將字體變成base64格式。

2,數據管理

數據管理方面可以使用westore來接入。

3,構建

小程序的構建需要完成什么事情呢?小程序開發者工具已經提供了部分能力: ES7/ES6轉ES5,NPM包管理,代碼分包,組件化,打包合并。

我們借助gulp來實現圖片壓縮以及前面提到的Post CSS編譯

為什么使用gulp而不用更流行的webpack呢?

這里補齊的能力主要涉及文件處理比較多,使用gulp開發效率較高,小程序一些官方腳手架也是使用gulp。

最后,我們選擇了小程序原生框架作為我們的開發框架。并且補齊了跟其他開發框架對比欠缺的基礎能力。當然,這里并非說其他框架不好,具體選擇還是需要看具體的業務場景。

確定好開發框架后,統一的目錄規范也是團隊協同開發必須約束的。

在引入npm包管理后,我們在小程序的基礎目錄中,通過新起了一個miniprogram目錄來作為小程序代碼的根目錄。這是由于小程序會對node_modules里面的包打包編譯到miniprogram_npm目錄,為了避免小程序的node_modules跟其他工程化相關的node_modules混在一起,才新起了一個文件夾來存放小程序工程代碼。可以通過修改project.config.js可以配置小程序代碼的根目錄路徑。

約束好目錄,那么在團隊協同開發,如何維護規范化,風格統一的代碼,我們希望可以團隊成員開發時可以統一代碼規范, 提交規范, 風格保持一致。因此,跟我們其他web項目一樣,我們可以使用 eslint,stylelint,commitment,prettier等插件來對我們的代碼進行約束,規范。通過git hook來在做提交時的校驗檢測,不通過則不允許提交。

通過Commitizen以及standard-version來自動化生成統一的版本號以及ChangeLog。會自動將你在本次版本迭代中,提交的規范化log(遵循Angular團隊的commit規范: https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits )自動生成ChangeLog, 注明是特性發布,bugfix還是breakingChange,以及對應的log信息。后續我們在需要回滾或者回溯某一版本的改動時,就可以一目了然。

我們基于上面的能力以及約束規范,做成統一的腳手架,方便團隊在統一的環境下快速開發,并且開源了出去( https://github.com/imweb/generator-imweb-wxapp )。

三、小程序開發實踐

介紹完我們的框架選型,工程化探索,接下去分享下在線教育小程序的開發實踐經歷。

1,小程序音視頻

第一部分是小程序音視頻能力相關的實踐。騰訊課堂是一個在線學習的平臺,那么最核心的就是音視頻直播,錄播能力。那么在小程序上面,我們如何搭建課堂音視頻能力呢?

1),直播場景

我們先來看未接入小程序前,騰訊課堂的直播架構。我們通過老師上行到云上,再實時下行到端上, App學生以及通過WebRTC下行到PC web學生。對于延遲要求不高的場景,我們可以將直播流旁路轉碼到CDN,再供用戶拉流觀看,以節省成本。

這是各端使用的直播協議以及延遲對比,小程序應該采用那種協議,如何接入呢?

揭秘之前,我們先來了解下小程序音視頻能力的發展歷史。最初,小程序音視頻只有原生的video標簽。意味著只能支持 HLS高延時直播場景。

2017年4月份,騰訊云與小程序達成合作,在小程序上嵌入騰訊云音視頻SDK,并封裝成了live-pusher,live-player標簽,使小程序能夠支持更低延遲的直播協議,如:rtmp, http-flv等。

因此,我們可以使用live-player來播放rtmp,http-flv協議的流媒體來播放,降低小程序直播場景上的延遲。

不過目前live-player還存在一些不足:

  • 比如全屏按鈕不支持,需要自己定義。
  • 由于live-player是原生組件,因此需要通過cover-view以及一些hack方式來實現自定義控制條的全屏按鈕跟視頻窗口顯示層級的bug
  • IOS全屏時,bindevent無效 不過小程序后面采用同層渲染的方案,解決了原生組件需要使用cover-view來解決顯示層級問題,使用最新版本的基礎庫即可。

使用live-player大概1-2s的延遲,那么小程序上還有沒更低延遲的直播方案呢?

加入你是在騰訊云上面開通了WebRTC后,可以使用wbertc-room去實現小程序上更低延遲的直播。其原理是基于live-player的RTMP,但走的高速專線,不經過CDN,降低了延遲。

(小程序接入課堂音視頻的整體架構圖)

2),錄播場景

介紹完直播接入方案,接著講下錄播。由于版權保護,騰訊課堂錄播播放采用了加密HLS。

由于錄播對延遲沒要求,小程序上面可以直接使用video標簽來播放加密hls流。

在Web上,播放加密HLS的流程如下:

1,獲取到加密HLS的m3u8地址,傳給video;

2,瀏覽器video底層解析m3u8,發現其帶有加密協議標識-EXT-X-KEY,其值是一個獲取解密key的接口地址;

3,瀏覽器會自動發起該請求,發起請求,去獲取解密key;

4,瀏覽器自動發起請求時,會把用戶登陸態通過cookie方式帶上,業務后臺對cookie鑒權后返回解密key,之后瀏覽器拿到解密key后就可以解密播放了。

但在小程序中,由于小程序是沒有cookie的,那么怎么去針對小程序發起的獲取解密key請求鑒權呢?

我們通過在獲取m3u8文件時,在meu8地址加入加密后的鑒權參數,并加上前綴"voddrm.token.",這樣server返回m3u8文件時,會在EXT-X-KEY的請求地址上,將鑒權參數拼接進去。后面發起請求時,業務后臺獲取到鑒權參數,按照協商好到方式解密,即可獲取到用戶登陸票據進行判斷是否合法用戶。之后就按照之前的流程,鑒權通過即返回解密key。

2,小程序自動化發布

補齊了音視頻能力后,我們項目也正常上線。由于平臺功能不斷增加,小程序也在按照以下流程進行迭代發布。

但是上面流程是存在一些隱藏問題的,特別對于新人,容易因疏忽導致出錯,我們也因此導致了一個現網bug。不知道大家能發現不?

揭曉下答案,主要有2個問題:

  • 1,多人開發過程,npm包可能存在不同版本,比如登錄能力的npm包,有可能會忘記更新最新包。
  • 2,構建npm按鈕在開發者工具上面入口比較隱蔽,容易導致更新了npm包但是忘記點擊構建npm,覆蓋了線上的特性 上面操作對于熟悉小程序開發的人來說不容易出錯,但對于新人,由于不熟悉,容易疏忽。即使犯錯但概率很小,但是也必須解決。 
    那么我們能否通過自動化工具來幫我們校驗檢測這些隱患呢?

我們希望在上傳發布前,可以進行以下流程的自動檢測:

1,代碼合并主干檢測

2,node_modules版本檢測,必須是大于或者等于當前package.json的版本

3,自動執行構建npm操作

4,自動執行上傳操作,包括填寫版號以及備注信息

其中1跟2可以通過githook以及npm命令來判斷,3跟4涉及到小程序相關到能力調用,是否有暴露相關到接口可以調用呢?

這里小程序開發者工具提供了命令行以及http調用方式( https://developers.weixin.qq.com/miniprogram/dev/devtools/cli.html),可以讓你操作項目打開/關閉,代碼上傳,預覽,構建npm , 自動化測試等功能。因此,我們利用這個能力,采用cli調用等方式,實現了構建npm以及自動發布等能力。

具體流程如下:

1,進行是否更新最新主干代碼檢測;

2,判斷是否安裝了小程序開發者工具且正常設置到環境變量;

3,進行本地node_modules版本檢測;

4,調用構建npm命令;

5,自動獲取package.json的版本號作為上傳版本,獲取git 提交log作為備注; 6,調用上傳命令進行上傳

自動化發布流程示例

3,小程序第三方平臺

有了以上工具后,我們就可以愉快地進行開發迭代發布了。但隨著我們課堂平臺小程序的推廣,課堂平臺的各家機構都想擁有其自己的機構小程序,并且其頁面是課堂平臺小程序的一個子集。

通過分析后,我們決定通過構建的方式,從平臺小程序中拆離出機構小程序代碼。通過2份模版配置信息, 通過構建,可以動態生成平臺小程序以及機構小程序的app.json。這樣進行上傳的時候,就只會上傳對應的頁面。

代碼復用的問題解決了,但隨著而來還有另外一個問題。需要生成的機構有80多家,有些機構不一定有開發人員,如果幫助機構快速上傳發布他們自己的機構小程序呢?

這里引入微信第三方平臺的概念( https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489144594_DhNoV&token=&lang=zh_CN ),我們可以往微信開發平臺申請成為第三方平臺。機構申請完獨立的小程序賬號后,將其授權給我們騰訊課堂第三方平臺。這樣我們就可以獲取到該機構到代碼管理,版本發布到權限。通過上傳我們之前構建好到機構小程序模版,再調用發布接口,就可以快速實現幫助機構發布其獨立個體到機構小程序了。

4,性能優化實踐

我們的小程序上線后,通過在小程序管理后臺看到的啟動總耗時,發現幾個問題: 1,小程序管理后臺只展示了啟動總耗時,下載耗時,渲染耗時這3個數據緯度,但是啟動總耗時!= 下載耗時 + 渲染耗時;

2,啟動耗時居然達到了3.8s,這是一個合格都數據嗎?除了下載耗時跟渲染耗時,其他耗時消耗在哪個環節呢?

要想知道耗時消耗在哪里,首先要先了解小程序啟動過程中究竟發生了什么。

1, 小程序初始化

在這個步驟,微信會初始化小程序環境,比如邏輯層的js引擎,視圖層的WebView,并且注入公共基礎庫。

2,下載小程序代碼包

這里會進行業務小程序代碼包的下載。

3,加載業務代碼包

對下載完成對代碼包進行注入執行 - 小程序的代碼會被加載到適當的線程中執行。此時,所有app.js、頁面所在的JS文件和所有其他被require的JS文件會被自動執行一次,小程序基礎庫會完成所有頁面的注冊。

4,初始化小程序首頁

拉取數據,從邏輯層傳遞到視圖層,生成VD樹,進行渲染。

了解完小程序的啟動過程后,我們經過分析定位,個階段耗時如上圖所示。

其中灰色部分是小程序底層的執行耗時,這塊開發者是無法操控的。那在其他耗時中,下載代碼包這塊占比比較高。我們能怎么去減少這塊耗時呢?

原先對課堂小程序的所有頁面都是在一個包里面,那么這里我們采用分包方案。將主tab的3個頁面以及util, 常用組件這種公共模塊放在主包。其他每個頁面單獨分成300-500k左右大小對子包,子包可以引用主包對公共模塊。

經過分包處理后,下載代碼包對耗時減少了500ms左右,整體啟動耗時降到了3.2s。整體來說,已經比小程序大盤平均啟動耗時4.5s少了1.3s。

不過隨著而來的,也有其他問題的引入,比如從首頁打開課程詳情頁這一場景。

這個時候點擊詳情頁時,需要先下載完詳情頁分包,才能打開課程詳情頁,顯然這樣的體驗是極差的。

我們可以通過分包預加載的方案,來解決這個問題。打開首頁,加載完主包后,可以靜默加載其他分包,通過配置preloadRule即可實現分包預加載。

下面是一組本地測試數據,可以看到使用分包以及分包預加載的方案,可以減少啟動耗時以及提高用戶體驗。

除了普通分包方案,小程序還有獨立分包的方案。不依賴主包加載,即可打開分包頁面。常用于一些比較獨立的頁面,比如活動頁等。

但使用獨立分包也有一些限制:

  • 獨立分包無法引用主包或其他分包的資源
  • 全局App對象只能在主包定義,獨立分包不能使用App對象
  • 生命周期只能通過:wx.onAppShow, wx.onAppHide來監聽

解決了代碼包下載的耗時以及采用分包,以及分包與加載提高頁面打開性能以及效率。我們接下來看渲染耗時這塊。

這是一個典型但小程序雙線程通信的模型。每次調用setData方法,都會將數據從邏輯層傳遞到native層,再到渲染層,形成VD樹進行渲染。

以上是setData傳輸數據量以及傳輸時間的關系圖,可以看到當數據量大于64kb時,傳輸時間呈指數級增長。

因此,在使用setData時,應該盡量遵循以下建議:

  • 不要頻繁調用setData, 盡量合并到一次setData調用
  • 傳輸數據量跟通信性能有關,盡量少于64k,避免一些不需要在頁面展示的復雜數據結構或者長字符串
  • 與界面無關的數據最好不要設置在data中
  • 去掉不必要的事件綁定,減少通信的數據量以及次數
  • 不要在節點data前綴放置過大數據(需要傳輸target的currentTarget和dataset)

5,公共基礎組件庫

為了提高開發效率,代碼復用率,我們對常見的一些能力以及功能型組件進行了封裝(后續計劃開源)。

這里拿基礎能力的request組件來看,我們基于wx.request來封裝,利用storage來存儲登陸后的cookie信息,并在后續發起請求的時候,將登陸票據設置到請求頭中。

采用可插拔插件式封裝方法,來做各種插件到擴展。例如有loading插件,一個可以在發起請求的時候,自動顯示loading,請求完成后,自動隱藏的插件。

以上就是小程序開發實踐相關的分享。

四、QQ小程序

QQ小程序是一個基于手Q龐大流量,面向年輕化群體,跟隨小程序行業標準的小程序平臺。啟動于18年12月份,并于6月底全量發布,目前覆蓋微信小程序API達到了95%以上。

從用戶側來看,基本跟微信小程序類似。在聊天下拉即可發現小程序入口,里面有小程序商城,可發現各類小程序以及小游戲。它的開發者工具的UI也類似微信開發者工具。

它跟微信小程序之間有以下的一些區別:

API以及功能方面

  • 調用前綴:例如:qq.getSystemInfoSync (也兼容wx語法) ,覆蓋率95%
  • webview: QQ小程序暫不支持webview
  • 喚起方式:支持http鏈接喚起小程序
  • 組件:不支持live-player, live-pusher組件
  • 分享:QQ小程序支持分享到QQ空間

開發者工具方面

  • 底層框架:都是基于nw.js
  • 編譯能力:
    • 不支持增強型編譯
    • 不支持多核心編譯
  • 其他
    • 不支持體驗評分
    • 不支持自動化測試

總的來說,QQ小程序的API基本對齊微信小程序,它的迭代速度較快,能力逐漸補齊中。并且擁有QQ生態流量紅利,最重要的是從微信小程序遷移到QQ小程序工作量較小,代碼95%以上基本可以復用。

總結

小程序生態發展之迅速,支付寶,百度等各大廠商都在各自研發自己的小程序。從開發者的角度來說,希望能夠統一一套API規范,形成行業標準。前不久W3C中文興趣組也在對小程序的生態進行了規范的相關討論,相信后續必然會朝著標準化的方向發展。以上便是此次在線教育小程序開發實踐之路的分享,可以通過下方的二維碼關注IMWeb團隊的公眾號以及個人的公眾號。

鮮花
鮮花
雞蛋
雞蛋
分享至 : QQ空間
收藏
原作者: IMWeb社區 來自: IMWeb社區
致青春APP