微信小程序自推出以來,逐漸發(fā)展,目前正受到越來越多的青睞。其中很重要的一點得益于小程序的輕量級特性,每個小程序最多不超過2MB,招之即來揮之即去,相比于幾十上百兆的APP,用戶進入小程序,或者說,小程序獲取新用戶,的成本大大降低。
但與之相應(yīng)的,是開發(fā)資源的限制。由于輕量級特性,小程序的代碼包體積、可用內(nèi)存空間、可用存儲空間等均受限制。如何在有效支持業(yè)務(wù)邏輯的同時,盡量減少資源占用,在小程序開發(fā)環(huán)境中顯得尤為重要。代碼包體積是其中的一個重要方面,本文將就此進行分析與探討。
背景
本文內(nèi)容基于小程序“轉(zhuǎn)轉(zhuǎn)官方”經(jīng)驗總結(jié),部分內(nèi)容與開發(fā)環(huán)境密切相關(guān),因而此處進行簡要介紹。
“轉(zhuǎn)轉(zhuǎn)官方”是一個重量型小程序,移植了轉(zhuǎn)轉(zhuǎn)APP的絕大部分功能,從商品發(fā)布、瀏覽、搜索、下單、跟進等交易邏輯,到留言、私信、紅包、推薦、運營活動、個人中心、圈子社區(qū)等擴展能力均已支持,目前代碼包體積約為1.5MB。
“轉(zhuǎn)轉(zhuǎn)官方”采用wepy框架進行開發(fā)。該框架類似vue,支持組件化開發(fā)、ES678語法、less語法等,源碼經(jīng)編譯、壓縮后才生成實際代碼。目前線上使用版本為1.5.8??蚣芙榻B: 像VUE一樣寫微信小程序-深入研究wepy框架
http://mp.weixin.qq.com/s/R2IlOzlA9Mb_XevDXAITdw
意義
控制代碼包大小主要意義:
避開大小限制
小程序代碼包體積存在大小限制,一開始為1MB,后來改為2MB,代碼包體積超過此上限時將無法進行預(yù)覽/上傳/發(fā)布。
降低用戶獲取成本
減小代碼包體積,可以降低小程序下載時長&首次加載時長,降低新用戶流失率;同時減少下載流量和本地空間占用,提升用戶體驗。
開發(fā)維護
保持代碼包干凈整潔,一定程度上有利于代碼的長期維護。
策略
控制代碼包大小主要策略:
-
搬
能搬的盡量搬。圖片、音頻、數(shù)據(jù)、甚至頁面,很多都可以搬至服務(wù)端,需要時再通過網(wǎng)絡(luò)載入。將非核心非必要的內(nèi)容移出代碼包可以大幅度釋放代碼包空間。 -
刪
搬不了的盡量刪。已下線、已廢棄、無關(guān)、冗余等不需要/不再需要的內(nèi)容應(yīng)及時清理,避免持續(xù)占用代碼包空間。 -
壓縮
刪不了的盡量壓縮。圖片、js、wxss、wxml等均存在壓縮空間。很多時候,適當程度的壓縮,能在幾乎不影響功能體驗的同時,有效減少空間占用。 -
合并
壓縮不了的盡量合并。功能類似的資源可以歸一化,在需求/設(shè)計/實現(xiàn)層面減少資源的重復(fù)消耗。 -
其它
其它壓縮策略。
方案
資源外置
非核心不緊急的資源文件,特別是圖片、音頻、視頻等體積較大的媒體文件,可以移至cdn服務(wù)器,需要時再通過網(wǎng)絡(luò)載入。
這常常是小程序前期膨脹的主要原因和最有效壓縮方式,比如我們的“手機30秒快賣”小程序,將圖片資源移出代碼包后,體積從約2MB直接降到了195KB。
數(shù)據(jù)外置
非核心不緊急的數(shù)據(jù)內(nèi)容,包括城市地區(qū)等大段數(shù)據(jù),標簽映射等大段配置,使用條約、服務(wù)說明等大段文案,可以移至數(shù)據(jù)服務(wù)器或本地storage,需要時再予以載入。
有些內(nèi)容體積會比想象中大,比如我們的“轉(zhuǎn)轉(zhuǎn)使用條約”,移出代碼包后,釋放了約40KB空間。
功能外置
非核心自定義屬性不強烈、不緊急可以異步處理的功能,可以移至外部實現(xiàn)。如選擇地址、查看大圖等功能可以交由小程序原生接口實現(xiàn),編碼解碼等功能可以交由服務(wù)端實現(xiàn)。
頁面外置
非核心不緊急的頁面,可以考慮移至服務(wù)端。從基礎(chǔ)庫1.6.4起,小程序開始支持內(nèi)嵌網(wǎng)頁,非核心頁面可以考慮適當往web服務(wù)器遷移。
[wepy] 清理殘留文件
目前wepy編譯時不會自動清理上次編譯殘留的文件,導(dǎo)致歷史資源持續(xù)積累。
e.g. 7個頁面,npm run build, 172KB -> 刪掉6個頁面, npm run build, 依然 172KB。
因而應(yīng)當修改build腳本,在編譯前增加清空dist步驟,或在編譯前手動刪除dist目錄。
清理無關(guān)文件
應(yīng)避免代碼包中混入運行無關(guān)的文件,如readme、doc、demo、測試用例等。
可以通過設(shè)計合理的文件結(jié)構(gòu)避免無關(guān)文件混入代碼目錄,wepy框架下也可以配置.wepyignore自動按類型/目錄過濾文件(項目目錄-新建.wepyignore文件-編輯-語法參考.gitignore)。
清理已下線/已棄用文件
已下線/已棄用的文件資源應(yīng)及時清理,包括npm包、組件、頁面、媒體資源等。若后續(xù)需要重新上線/重新使用,可以通過git等版本控制工具找回。這部分資源不需要持續(xù)占用代碼包空間。
IDE的查看引用、范圍搜索等功能可以為清理過程提供一定的便利。
資源都移至cdn之后,這部分空間可能就是最可觀的了?!稗D(zhuǎn)轉(zhuǎn)官方”小程序代碼包體積從2MB出頭降到了約1.5MB,主要就是由清理殘留文件、清理已下線/已棄用文件釋放的。
[wepy]清理多余wxml文件
目前wepy編譯時會將組件的dom部分拼合到頁面中,而不生成單獨的wxml文件。
但若組件所在文件路徑不含'/components/',則編譯環(huán)節(jié)wepy不會識別其為組件,會按'Other'類型處理,從而生成多余的wxml文件和json文件。
確保組件都放在components目錄下可以避免這部分多余空間消耗。
清理大文件
大文件常常存在較大的壓縮空間,值得重點排查和處理。
查找大文件tip:資源管理器 - 代碼目錄 - 搜索'*' - 右鍵 - 排序方式:大小,即可將代碼包內(nèi)所有文件按大小排序展示
資源壓縮
大部分資源都可以進行適當壓縮,常??梢栽诒WC功能體驗的同時,有效地減少空間占用。參考工具:
-
js壓縮: 配置wepy-plugin-uglifyjs插件
-
json、wxml壓縮: 配置wepy-plugin-filemin插件
-
less壓縮: 配置wepy-compiler-less插件
-
圖片壓縮: 配置wepy-plugin-imagemin插件、TinyPNG
其中TinyPNG工具壓縮效果非常可觀,400KB的圖片壓到40KB不足為奇,并且畫質(zhì)感知上幾乎無損。
資源合并
功能類似的資源可以歸一化,減少重復(fù)空間占用。
-
需求層面,比如不同運營活動可以采用統(tǒng)一模板,而不每次增加單獨頁面等;
-
樣式層面,比如可以統(tǒng)一彈窗規(guī)范,而不引入五花八門的零碎彈窗組件等;
-
設(shè)計開發(fā)層面,比如可以盡量解耦合抽取公共組件,減少重復(fù)造輪子等。
[wepy]清理組件DOM冗余拷貝?
觀察發(fā)現(xiàn),目前wepy的組件實現(xiàn)中,編譯后頁面對組件js、wxss的引用是通過require、@import的形式實現(xiàn)的,而對組件dom的引用則是直接拼合到頁面wxml文件中。
這導(dǎo)致,當一個組件被多處引用時,其dom內(nèi)容會有多份冗余拷貝。
e.g. 10個頁面引用了組件A => 編譯出的10個頁面wxml各含一份A的dom,A的template部分在代碼包中被原模原樣重復(fù)了10次
如果修改wepy編譯過程,將組件dom引用過程改為使用include或原生組件(基礎(chǔ)庫1.6.3開始支持)實現(xiàn),應(yīng)當可以節(jié)省這部分冗余開銷。
[wepy]壓縮自動生成的代碼量?
觀察發(fā)現(xiàn),代碼包中除了手動維護的業(yè)務(wù)代碼之外,也有不少框架/插件自動生成的代碼。如源碼編譯過程中生成的輔助代碼、兼容ES678語法引入的墊片代碼、兼容各運行環(huán)境引入的css前綴代碼等。
通過對框架和插件進行修改/配置,應(yīng)當可以一定程度減少這部分空間開銷。比如對babel插件進行規(guī)則配置、對auto-prefix插件進行最低版本配置,應(yīng)當可以犧牲部分不必要的兼容性,從而減少墊片代碼的生成量等。諸如此類。
只是筆者未及嘗試,尚不確定這部分開銷是否有可觀的壓縮空間。
壓縮額外文件空間?
觀察發(fā)現(xiàn),代碼包大小總是比代碼內(nèi)容總大小大得多(上傳后詳情面板中“上次上傳”、“上次預(yù)覽”總是比“本地代碼”大得多)。
這部分額外大小應(yīng)當也是存在壓縮空間的。比如將細碎圖片、細碎js文件、細碎less文件拼合成雪碧圖、js庫、less庫等較大文件,應(yīng)當可以減少由于文件最小存儲單元引入的額外空間開銷等。諸如此類。
只是筆者未及嘗試,尚不確定這部分開銷是否有可觀的壓縮空間。
總結(jié)
由于輕量級特性,小程序開發(fā)環(huán)境中,對代碼包體積的控制是十分必要且十分有意義的。
本文介紹了代碼包體積壓縮的一些策略、方案和幾個未及實踐的思路??偟膩碚f,就是盡量精簡,盡量只將最核心最必要最緊急的內(nèi)容放在代碼包內(nèi)。其它資源過多占用代碼包空間時,則考慮通過搬移/刪除/壓縮/合并等方式予以釋放。
拙劣之處歡迎不吝賜教。
——— ———————————— ———
長按二維碼,關(guān)注大轉(zhuǎn)轉(zhuǎn)FE