騰訊課堂小程序開發(fā)實踐與思考
2022-11-28 加入收藏

本文由 InfoQ 整理自騰訊 CSIG 在線教育部前端高級開發(fā)工程師陳天忱在 GMTC 全球大前端技術(shù)大會(深圳站)2021 的分享《騰訊課堂小程序開發(fā)實踐》。
你好,我是陳天忱,來自騰訊 CSIG 在線教育部。我所在的團隊主要負責(zé)騰訊課堂平臺的開發(fā)和維護,我從加入團隊以來就圍繞著小程序做了很多探索和優(yōu)化,目前也是騰訊課堂小程序的負責(zé)人。
我本次分享的內(nèi)容分為五個部分,首先我們從整體的角度來看一下騰訊課堂小程序的技術(shù)演進過程,接著會分別從開發(fā)體驗、性能優(yōu)化以及監(jiān)控體系三個角度分享一些實踐和經(jīng)驗,最后進行一下總結(jié)。
在我剛進入團隊的時候,騰訊課堂小程序的工具鏈還處在比較原始的階段。除了在編碼層面利用了 web 比較成熟的 scss、postcss、lint、typescript 結(jié)合 gulp 做一些語法層面的編譯以外,在測試、構(gòu)建 npm、上傳、設(shè)置體驗版、發(fā)布等階段都是依賴的小程序開發(fā)者工具和管理后臺,人工手動操作來完成的。
石器時代
在這個階段,大部分都是簡單地利用一些現(xiàn)有的工具,我們稱之為騰訊課堂小程序的石器時代。
這個階段存在幾個明顯的問題:
構(gòu)建和上傳依賴人工操作,有可能會因為流程操作失誤而導(dǎo)致現(xiàn)網(wǎng)事故;
由于發(fā)布流程的不規(guī)范,需求并行時經(jīng)常會出現(xiàn)發(fā)布撞車的情況,導(dǎo)致體驗版相互覆蓋造成預(yù)發(fā)布驗證成本。
為了解決人工操作帶來的隱患,我們從零開始基于小程序提供的命令行工具打造了小程序 CI。讓源碼編譯、構(gòu)建 npm、上傳、生成開發(fā)版 / 體驗版二維碼、自動化測試等流程在 CI 流水中自動流轉(zhuǎn)。
同時我們也將小程序 CI 與企業(yè)微信打通,將小程序的構(gòu)建進度和小程序二維碼實時同步過去,而且也支持通過企業(yè)微信主動觸發(fā)小程序構(gòu)建,解決了在測試過程中因為開發(fā)版二維碼過期而中斷測試的問題。
為了解決發(fā)布流程不規(guī)范的問題,我們將小程序的發(fā)布也接入到了業(yè)務(wù)發(fā)布平臺。在發(fā)布平臺上進行 CheckList、CodeReview、發(fā)布評審、發(fā)布環(huán)境管理、發(fā)布靜態(tài)資源等流程的流轉(zhuǎn),確保需求發(fā)布的質(zhì)量、合規(guī)和有序。

解決了開發(fā)流程中的問題之后,我們將更多的精力放到了小程序的研發(fā)效能與性能上。開發(fā)和構(gòu)建階段我們打造跨端的公共模塊,通過 kbone 進行同構(gòu)開發(fā),利用云開發(fā)來輔助首屏性能優(yōu)化,以及代替部分后臺的開發(fā),在構(gòu)建方面將構(gòu)建工具從 gulp 遷移到 webpack,能對構(gòu)建常務(wù)進行更細致的優(yōu)化。
在發(fā)布之后,通過完善監(jiān)控告警,將發(fā)布質(zhì)量做到可視化的體現(xiàn),并能夠?qū)Τ霈F(xiàn)的問題得到及時的接收和感知,減少用戶的反饋。

到這里我們可以看到整個技術(shù)演進的過程,它涵蓋了小程序開發(fā)、構(gòu)建、測試、部署發(fā)布以及監(jiān)控,形成了小程序的 DevOps 開發(fā)模式,這其中具體是怎么做的呢?

首先是開發(fā)階段,我們想要形成一個可以稱之為“爽”的開發(fā)體驗,并不僅僅是指 coding 階段,還需要覆蓋到測試以及發(fā)布階段:
編碼階段——業(yè)務(wù)邏輯跨端可復(fù)用
測試階段——改動持續(xù)集成、測試與開發(fā)解藕
發(fā)布階段——規(guī)范化、流程化、可追溯
為此我們分別通過打造跨端可復(fù)用的公共模塊、小程序 CI、統(tǒng)一業(yè)務(wù)發(fā)布平臺來提升開發(fā)體驗。

這里從一個實際場景出發(fā),我們之前有這樣一個需求:產(chǎn)品希望在各端的課程詳情頁有一個提示當(dāng)前此機構(gòu)正在直播的課程,可以引導(dǎo)用戶跳轉(zhuǎn)到直播間聽老師講解課程的細節(jié)。

梳理一下這個需求的流程,發(fā)現(xiàn)其實還是挺簡單的:
詳情頁渲染完成后 -> 調(diào)用接口拉取直播間數(shù)據(jù) -> 渲染引導(dǎo)模塊 -> 用戶點擊跳轉(zhuǎn)直播
可以看到,業(yè)務(wù)的主邏輯在各端都是一樣的,但如果去看這些邏輯的細節(jié)就會發(fā)現(xiàn)其實各端需要的是不一樣的實現(xiàn),比如發(fā)起請求的 api 在瀏覽器和在小程序中是不一樣的;提示的疲勞度控制需要用到本地的緩存能力,瀏覽器和小程序的 api 也是不一樣的;然后在業(yè)務(wù)上,直播間在三端的頁面地址也是不一樣的。

通過 ifelse 或者 switch 的方式,在運行時判斷當(dāng)前的執(zhí)行環(huán)境,然后調(diào)用不同的分支邏輯當(dāng)然是能夠?qū)崿F(xiàn)需求的,但是這種方式會讓一個端同時存在三端的邏輯,這樣的邏輯多了之后,會造成比較明顯的代碼冗余,而在小程序端由于有 2M 的包大小限制,對于代碼冗余是比較敏感的。
要解決代碼冗余的問題,大家會很自然地想到構(gòu)建時注入一個環(huán)境變量,通過 tree-shaking 的能力在不同端構(gòu)建出對應(yīng)端所需要用到的邏輯。但這個方案對于構(gòu)建工具有著一定的要求,而在實際的工作場景中,新老項目往往由于歷史的原因,不僅僅是源碼,在構(gòu)建上的技術(shù)棧也是有很多歷史包袱的,比如 gulp、fis、webpack 等,如果要全部統(tǒng)一起來成本和風(fēng)險都會比較大。
所以我們需要一個能夠跨端復(fù)用,按需打包,而且不依賴項目構(gòu)建體系的公共模塊。
我們基于 git submodule 的方式從組件、業(yè)務(wù)、工具三個維出發(fā),每個維度根據(jù)具體的邏輯按照執(zhí)行環(huán)境將其拆分成同構(gòu)目錄 (isomorph)、瀏覽器目錄 (lib)、小程序目錄 (wx),各個項目將 lib 目錄或者 wx 目錄作為引用的入口,而入口文件會繼承或者透傳導(dǎo)出 isomorph 目錄下的邏輯,對環(huán)境有依賴的特殊邏輯則在 lib 目錄和 wx 目錄下分別實現(xiàn)。
在開發(fā)階段通過路徑別名來統(tǒng)一引用路徑,例如小程序的項目中設(shè)置tsconfig.json的paths為"ke-modules/*": "submodules/ke-modules/*/wx",這樣就可以統(tǒng)一業(yè)務(wù)層面的代碼邏輯。在構(gòu)建階段submodule會通過ts單獨編譯成js,如果是h5和PC的項目就只會將isomorph和lib目錄構(gòu)建到產(chǎn)物中,小程序的項目就只將isomorph和wx目錄構(gòu)建到產(chǎn)物中。

這樣就確保了在保證兼容性的基礎(chǔ)上不會產(chǎn)生冗余的代碼,以此來滿足我們之前提出的幾個需求。
我們搭建小程序的 CI/CD 的起因,是由于開發(fā)者工具中很多人工操作帶來的一系列問題,比如:
在構(gòu)建過程中,很容易漏掉構(gòu)建 npm 依賴
在上傳時的版本信息和版本號也不規(guī)范
不同需求的體驗版需要管理后臺切換,需求并行非常不友好
開發(fā)版二維碼需要開發(fā)者實時提供,影響測試進度要解決以上這些問題就需要從自動化和流程控制來入手。
我們先是基于小程序官方提供的一個命令行工具進行了封裝和擴展,支持小程序的 npm 構(gòu)建、上傳、獲取二維碼、自動獲取版本號、版本信息等功能,并作為小程序 CI 流水線中的核心插件。
CI 流水線支持通過 git hook、OpenAPI、手動的方式觸發(fā)執(zhí)行。在流水線的流轉(zhuǎn)執(zhí)行中,完成代碼拉取、分支檢查、版本號迭代及版本信息更新、小程序代碼包上傳、開發(fā) / 體驗版二維碼獲取,同時歸檔小程序產(chǎn)物、sourcemap 等文件便于對性能和錯誤的分析。
同時通過 CI 的插件與企業(yè)微信機器人打通,將構(gòu)建進度以及構(gòu)建后的小程序二維碼同步到企業(yè)微信中,同時也支持通過 @企業(yè)微信機器人以 openAPI 的形式主動觸發(fā)流水線執(zhí)行,讓產(chǎn)品和測試都可以實時獲取最新的小程序二維碼進行測試和體驗。
在發(fā)布階段,與 web 項目一樣接入統(tǒng)一的業(yè)務(wù)發(fā)布平臺,在發(fā)布平臺上對發(fā)布流程進行規(guī)范,確保發(fā)布之前的 CheckList、CodeReview、發(fā)布評審等流程正確執(zhí)行。發(fā)布開始對發(fā)布環(huán)境進行管理,設(shè)置門禁,確保同一時間只會有一個需求處在發(fā)布流程中,避免多需求并行出現(xiàn)的發(fā)布混亂問題,發(fā)布完成并現(xiàn)網(wǎng)觀察沒有問題之后再將環(huán)境釋放給下一個需求。

建設(shè)了這樣一套 CI/CD 的流程之后,之前遇到的問題就都得到了解決。
通過在構(gòu)建過程中獲取依賴的 npm 信息來判斷是否需要更新及構(gòu)建 npm,并自動執(zhí)行;
上傳時根據(jù) Angular 的 git commit 規(guī)范,自動迭代 major、minor、patch 的版本號,更新 changelog;
CI 使用機器人賬號上傳小程序,通過業(yè)務(wù)發(fā)布平臺對小程序的發(fā)布環(huán)境進行管理,避免發(fā)布沖突;
提供企業(yè)微信觸發(fā)小程序構(gòu)建的能力,測試和產(chǎn)品可實時出發(fā)構(gòu)建并獲取最新二維碼。
這是我們在 CI/CD 上面的一些實踐經(jīng)驗,以及在開發(fā)體驗上面的一些處理方案。
小程序的啟動方式分為冷啟動和熱啟動,而小程序的性能瓶頸大部分也都集中在冷啟動這一階段。

冷啟動階段分為如上幾個步驟,其中環(huán)境初始化對于開發(fā)者來說是個黑盒,目前還無法介入,而下載代碼包和加載代碼包的耗時,主要與小程序代碼包的體積正相關(guān),數(shù)據(jù)拉取需要開發(fā)者對請求時機進行優(yōu)化,頁面渲染則需要優(yōu)化渲染策略。
業(yè)務(wù)代碼的體積優(yōu)化需要通過構(gòu)建來解決,以一個項目的常規(guī)結(jié)構(gòu)來看,我們一般會將一些有可能復(fù)用的模塊放置到公共模塊中。如下圖所示,引用關(guān)系如果只進行編譯的話,根據(jù)小程序的規(guī)則,公共模塊和組件的大小都會被計算到主包中,我們希望通過構(gòu)建來優(yōu)化產(chǎn)物結(jié)構(gòu),避免主包太大的問題。

再者,隨著需求的迭代,可能某一個組件的引用就丟失了,這種情況在小程序的規(guī)則下,依然會被計算在主包里面,可以看下面這張圖。我們希望能通過構(gòu)建將未使用的模塊或者組件進行過濾。

另外,如果某一個分包與主包引用了同一個模塊,這時候?qū)⑦@個模塊計算到主包中是 OK 的,但如果這個分包是一個獨立分包的情況下,再去引用主包的模塊,是有可能報錯的。上面這種情況需要通過構(gòu)建的方式將模塊復(fù)制一份放到獨立分包下面才能保證小程序的正確執(zhí)行。

我們面對的上面三個問題有一個核心思路是需要在構(gòu)建的過程中,針對小程序的規(guī)則進行依賴分析。下面是我們對比目前市面上比較成熟的構(gòu)建工具,從四個維度進行了分析:

根據(jù)對比的結(jié)果,webpack 對于需求的支持還是比較成熟的,我們最終決定選擇 webpack 作為小程序的構(gòu)建工具,但是 webpack 也不支持小程序的組件,這一點就需要我們自己進行支持了。
以 app.js 作為入口文件,根據(jù)小程序的配置規(guī)則找到對應(yīng)的 json 文件,逐層遞歸就可以將整個小程序所使用到的頁面和組件分析出來,并將所有的頁面和組件都作為 webpack 的 entry,就可以獲取到小程序中 js 模塊的引用信息了。
通過 plugin 對引用信息根據(jù)一定策略進行計算 chunk:

例如,某一個頁面引用了一個模塊,先判斷模塊是否在分包內(nèi),如果在分包內(nèi)則按照常規(guī)方案打包;不在分包內(nèi)則判斷引用它的分包是否為獨立分包。如果是獨立分包則復(fù)制一份 (新建一個 chunk);是普通分包則收集是否被多個分包引用。若不是,則將模塊移動到分包下 (新建一個 chunk,并將原來的刪除)。
計算完 chunk 之后就可以通過 webpack 的 load 去處理另外的資源文件,包括 css、image、font,提取靜態(tài)資源文件,替換引用路徑。

處理完成后的效果也相當(dāng)明顯,我們的主包從 1900 多 kb 優(yōu)化到了 900 多 kb,優(yōu)化幅度達到 50%,總包的一些體積也優(yōu)化了 27%。

優(yōu)化的體積主要來自以下三個方面:
模塊下沉到了分包
對未使用到的組件和模塊進行了過濾
靜態(tài)資源文件上到 CDN
我們的優(yōu)化在實際的啟動耗時上也有比較顯著的效果,主包下載耗時優(yōu)化了 43%,js 的注入耗時優(yōu)化了 18%。

另一方面,當(dāng)小程序需要通過 npm 的形式使用一個比較復(fù)雜的 SDK 時,由于小程序的 npm 包需要單獨構(gòu)建一次,無法做到編譯時按需打包,這也會遇到體積較大的問題。
在我們的實際業(yè)務(wù)場景中就有這樣的問題,騰訊課堂作為在線教育業(yè)務(wù),有個核心能力是直播互動,就是用戶在線上上課的過程中聊天、舉手、連麥、抽獎等形式的交互行為。
為了讓這個核心能力能夠達到跨端跨業(yè)務(wù)的復(fù)用效果,我們團隊開發(fā)了一個直播互動的 SDK,對外拋出簡單的 API,內(nèi)部設(shè)計了接口層、適配層、通道層、策略層,結(jié)構(gòu)非常清晰,使用起來也很方便,初始化后開發(fā)只需要監(jiān)聽或請求對應(yīng)的命令字即可,無需關(guān)心內(nèi)部的轉(zhuǎn)化,并且能夠利用 ts 的類型推斷能力直接拿到通道返回的數(shù)據(jù)類型。

但是當(dāng)我們在小程序端進行接入時,遇到了幾個問題:
為了支持跨端跨業(yè)務(wù),SDK 內(nèi)置了所有功能的邏輯,在小程序端使用會造成大量的包體積浪費
針對 web 設(shè)計,不兼容小程序;單獨維護一個小程序的版本成本比較大
不同項目和業(yè)務(wù)對 SDK 的迭代會導(dǎo)致版本管理混亂
要解決上面這些問題,我們必須對 SDK 進行升級改造。
我們改造的方案是進行插件化處理,將接入層(業(yè)務(wù)層)和適配層作為 SDK 的內(nèi)核抽離出來,并添加了 pluginAdaptor 對插件進行適配管理,將策略層和通道連接層的邏輯進行抽象處理,制訂好對應(yīng)的規(guī)范,根據(jù)抽象類和業(yè)務(wù)需求實現(xiàn)對應(yīng)的策略插件和通道插件。

在業(yè)務(wù)中的改造非常簡單,只需要初始化之前注冊當(dāng)前場景和功能所需要的插件,后續(xù)在使用上與之前完全一致,業(yè)務(wù)的改造成本非常低。

兼容性上通過 rollup 打包,在構(gòu)建時注入不同的環(huán)境變量,輸出對應(yīng)端所需要用到的 bundle。

插件化改造之后,好處就顯而易見了:
按需引入,運行時它的體積是最小的,改造前后 SDK 運行時體積從 384KB 減少到 42KB,優(yōu)化了近 90%
多包結(jié)構(gòu)迭代比較清晰,內(nèi)核和抽象通道也很穩(wěn)定,各個插件可以進行單獨的版本迭代
跨端復(fù)用能力得到了擴展,統(tǒng)一維護
請求的優(yōu)化也是小程序性能優(yōu)化中很重要的一環(huán),在冷啟動和頁面跳轉(zhuǎn)的過程中,我們分別對請求時機以及弱網(wǎng)阻塞兩種情況進行了優(yōu)化。
請求時機上,可以利用小程序的全局 app 實例將數(shù)據(jù)請求的時機提前到頁面加載之前,進一步利用小程序的數(shù)據(jù)預(yù)加載能力,將首屏數(shù)據(jù)的請求時機提前到啟動小程序時:

頁面加載前發(fā)起請求的流程如下,在 onLaunch 或者頁面跳轉(zhuǎn)時就直接發(fā)起下一個頁面的請求,并將請求的 Promise 掛載在 app 實例上,當(dāng)頁面加載完成出發(fā) onLoad 的時候則直接通過 app 上的 Promise 返回進行渲染,根據(jù)我們的統(tǒng)計平均可以優(yōu)化 100ms 的耗時,而且相對靜態(tài)的數(shù)據(jù)可以通過本地緩存的方式,在二次加載此頁面時通過緩存數(shù)據(jù)渲染,達到秒開的效果。

而數(shù)據(jù)預(yù)拉取則類似于 web 的服務(wù)端渲染,在啟動小程序時通過云函數(shù)根據(jù)啟動參數(shù)調(diào)用業(yè)務(wù)后臺的服務(wù)獲取數(shù)據(jù)并返回給小程序,小程序啟動后就可以直接使用預(yù)拉取的數(shù)據(jù)進行渲染,預(yù)拉取成功可以平均優(yōu)化 90% 的首屏數(shù)據(jù)請求耗時。

除了上面常規(guī)情況的請求優(yōu)化,我們還注意到小程序有一個網(wǎng)絡(luò)使用限制,最大的并發(fā)限制是 10 個,這就會造成隱患。因為在小程序加載和用戶交互的過程中會產(chǎn)生很多的上報請求,例如 PV 上報、錯誤日志等,在弱網(wǎng)的情況下,很容易出現(xiàn)上報請求響應(yīng)慢而阻塞了業(yè)務(wù)請求的發(fā)送導(dǎo)致超時,而我們也確實收到了類似情況的反饋。
為了優(yōu)化弱網(wǎng)情況下存在的隱患,我們對請求隊列進行了優(yōu)化,通過設(shè)置請求池與等待隊列,并劫持 wx.request,在發(fā)送請求時對請求的 url 進行優(yōu)先級排序,將業(yè)務(wù)請求設(shè)置為高優(yōu)先級的請求,上報請求的優(yōu)先級降低。當(dāng)請求通道相對緊張時會將高優(yōu)先級的請求優(yōu)先發(fā)送,低優(yōu)先級的請求在請求通道空閑時再進行補發(fā)。

在實際運行過程中的邏輯如下圖:

視圖渲染和更新可以優(yōu)化的方向在于,將非首屏和非核心模塊數(shù)據(jù)延后更新,因為 setData 更新視圖數(shù)據(jù)太大會增加通信和解析的時間。以我們最復(fù)雜的課程詳情頁為例,因為模塊比較多,導(dǎo)致頁面比較長,一般會有 5~7 屏的內(nèi)容。如果需要等到頁面的所有數(shù)據(jù)全部出完再開始更新試圖,那么白屏?xí)r間和視圖更新時間都會比較長,比較合理的渲染策略應(yīng)該是首屏優(yōu)先,分步渲染。

但由于小程序的雙線程模式,通過 setData 的方式更新視圖是同步更新邏輯層數(shù)據(jù),異步更新視圖層數(shù)據(jù),所以并不能簡單地在處理完一部分數(shù)據(jù)后調(diào)用 setData 再繼續(xù)處理其余的數(shù)據(jù),甚至通過 Promise 也做不到分步渲染,而使用 setData 的回調(diào)或者 setTimeout 的方式又會出現(xiàn)邏輯嵌套的問題,降低代碼的可讀性和可維護性。
針對這個問題,我們的解決方案是基于 setTimeout 根據(jù) Promise 的表示封裝了一個 PromiseMacro 的類,這樣我們就可以向使用 Promise 一樣通過 then 方法將小程序的渲染拆分成多個步驟達到漸進式渲染的效果。

通過分步渲染的方式,可以將我們首屏渲染的起始時間從 230ms 提前到 90ms,達到減少用戶等待焦慮,提升用戶體驗的效果。
一個產(chǎn)品的質(zhì)量不僅僅是靠好的產(chǎn)品設(shè)計和代碼質(zhì)量,還有很大一部分需要通過收集操作和性能日志,為技術(shù)優(yōu)化提供方案,而對現(xiàn)網(wǎng)報錯的比例及數(shù)量進行監(jiān)控,能讓我們及時響應(yīng)并修復(fù)。之前我們的小程序上報也依賴了好幾個上報系統(tǒng)來完成:
通過 BadJS 來收集前端報錯和操作日志
通過 Wang 進行測速上報
通過 Monitor 進行打點監(jiān)控告警
通過 Tdw 進行產(chǎn)品需求上報
通過不同的系統(tǒng)進行上報會存在一些問題:
依賴的 SDK 比較多,每一個 SDK 的 API 都不一致,學(xué)習(xí)和維護的成本會比較高,這一點對于新人來說尤其明顯;
每個 SDK 上報的數(shù)據(jù)結(jié)構(gòu)也不一樣,想要查找對應(yīng)的數(shù)據(jù),就必須去對應(yīng)的統(tǒng)計平臺進行搜索。
解決這些問題的首要任務(wù)就是需要對這些上報的 SDK 進行整合,根據(jù)產(chǎn)品和業(yè)務(wù)需求將日志、測速、監(jiān)控、上報收歸到一個 SDK 里面,并統(tǒng)一上報的數(shù)據(jù)結(jié)構(gòu),部分功能會在 SDK 中進行備份轉(zhuǎn)發(fā),保證原上報系統(tǒng)的功能也能得到利用。

再結(jié)合小程序提供的幾個 API 就可以在日志收集的同時對用戶進行多維度的統(tǒng)計:

在統(tǒng)一上報數(shù)據(jù)結(jié)構(gòu)的前提下,就可以自定義制定多維度的統(tǒng)一看板,降低質(zhì)量監(jiān)控的成本。

以上是這次分享的主要內(nèi)容,我們簡單做一個總結(jié)。
隨著我們課堂小程序的技術(shù)演進,圍繞小程序逐漸形成了 DevOps 的開發(fā)模式:開發(fā)階段,我們打造了兼容小程序端的公共模塊,提升了小程序 30%~40% 的研發(fā)效率,同時在 CI/CD 建設(shè)方面,減少了人工操作的風(fēng)險,充分利用工程化自動化來解放開發(fā)的生產(chǎn)力,而且小程序 CI 建設(shè)的很通用化,公司內(nèi)部有 140+ 的項目接入。

在性能優(yōu)化方面,我們通過在體積、請求、渲染方面的優(yōu)化,將冷啟動下的首屏性能優(yōu)化了 1.5s,達到了 42.7% 的優(yōu)化比例。

在監(jiān)控告警方面,通過小程序的 API 再結(jié)合收攏的上報 SDK,可以讓統(tǒng)計力度更細,而且可視化可定制。

接下來小程序還有一些非常好用的特性可以加以利用,我們比較關(guān)注的是分包異步化和自動化測試。
異步化打包策略
分包異步化可以極大地縮小首屏包的大小,目前分包異步化的特性已經(jīng)適配了 2.11.2 的基礎(chǔ)庫版本,兼容性的問題也已經(jīng)得到了解決;接入分包異步化的能力,可以嘗試在小程序構(gòu)建打包時將一個頁面拆分成首屏包 + 異步邏輯包 + 異步組件包的形式,結(jié)合分包預(yù)加載功能,將首屏的代碼包下載耗時和加載耗時降至最低。
基于錄制回放的自動化測試
小程序團隊很早就支持了小程序的自動化測試,但是在 UI 自動化測試方面,測試用例的維護成本是最大的痛點,我們嘗試在本地錄制操作流程,按照一定的約定轉(zhuǎn)換成測試用例,可以極大地降低測試用例的維護成本,提高代碼質(zhì)量。