微信小程序開發(fā)之壓縮實踐

微信小程序依靠微信巨大的用戶流量優(yōu)勢,吸引來了眾多第三方開發(fā)者拓瞪。幾乎每個公司都會想通過小程序拉到新的用戶群體缴罗。3月份接到公司任務(wù),需要將公司各業(yè)務(wù)線小程序整合到一個小程序中祭埂。但擺在面前的問題是空間完全不夠面氓。當(dāng)時微信小程序的使用空間是 1024KB(現(xiàn)在已升為 2M),各個業(yè)務(wù)線獨立的小程序都不小蛆橡,『機票火車票汽車票』小程序更是超過 900KB舌界。如何整合和壓縮才能使 size 達標(biāo),成了最大的挑戰(zhàn)航罗。

我們經(jīng)過考慮禀横,準(zhǔn)備從兩個方面進行整合和壓縮,一是通過工程化的方式實現(xiàn)代碼復(fù)用——提取公共業(yè)務(wù)邏輯粥血,公共組件柏锄;二是通過工具進行自定義化代碼打包壓縮處理酿箭。

工程規(guī)范制定

為了節(jié)省開發(fā)時間,我們盡量整合現(xiàn)有業(yè)務(wù)線小程序代碼趾娃,減少業(yè)務(wù)改動缭嫡。

目錄結(jié)構(gòu)

同時為了后期計算各業(yè)務(wù)占用空間情況方便,我們直接將各業(yè)務(wù)線小程序工程代碼拷貝到各自業(yè)務(wù)線目錄下抬闷,最終的目錄結(jié)構(gòu)如下:

.├── common# 通用模塊/公共業(yè)務(wù)├── home# 首頁├── flight# 機票├── train# 火車票├── bus# 汽車票├── hotel# 酒店└── ticket# 門票

common 模塊即工程的復(fù)用部分妇蛀,具體業(yè)務(wù)代碼都在各自目錄下◇猿桑總體架構(gòu)如下:

公共組件评架、API

微信小程序其實并沒有提供組件化開發(fā)的方式。只是提供了template的方式炕泳,所以我們只提供了為數(shù)不多的頁面及組件纵诞,例如:城市定位、日歷組件等培遵。但是收益卻是非常明顯的浙芙,像這些頁面大小都在 20KB~30KB,如果每個業(yè)務(wù)自己整一套可能將徒增上百 KB 代碼籽腕。

公共 API 我們提供了統(tǒng)一的Watcher監(jiān)控嗡呼、Requester請求、Loading加載轉(zhuǎn)態(tài)皇耗、Navigation導(dǎo)航等南窗。這些公共邏輯的抽取豌汇,為整個項目整合節(jié)省了巨大的空間浑厚,使 size 達標(biāo)看起來不那么難了。

工程復(fù)用上節(jié)省了很大一部分空間巧婶。但是空間是有限的箭启,業(yè)務(wù)需求是無限的壕翩。而且,size 的大小會影響用戶加載的速度傅寡,包括下載最新版本代碼的速度和小程序初始化的速度放妈,所以還需要進一步進行代碼壓縮。

打包壓縮工具

微信開發(fā)者工具

我們知道微信小程序開發(fā)者工具本身提供了『代碼壓縮上傳』功能荐操。

但是個人覺得它是個『假的壓縮選項』芜抒。因為在閱讀開發(fā)者工具的源碼邏輯之后,發(fā)現(xiàn)它的壓縮托启,只是將 JavaScript 用uglify進行混淆壓縮宅倒。而對 WXML、WXSS 沒有進行任何壓縮處理屯耸。同時拐迁,對資源路徑中的無用文件也沒有做處理蹭劈。

小程序的構(gòu)建

在小程序開發(fā)者工具的 Sources 面板,查看 JavaScript 腳本线召,會發(fā)現(xiàn):項目中所有的 JavaScript 都會被同步加載铺韧,不管是否被require。

每個腳本都會被套上如下代碼:

define("some.js",function(require,module){// 原本的代碼});

這種加載方式類似 AMD缓淹,但是跟標(biāo)準(zhǔn)的 AMD 又有些不同哈打,缺少了依賴部分的聲明。

而對于 WXSS 和 WXML 文件讯壶,則被開發(fā)者工具自動轉(zhuǎn)換為 JavaScript 后加載料仗,其中:

WXSS:主要處理的是 import 邏輯,然后生成的 CSS伏蚊,通過腳本的形式插入頁面使用罢维。

WXML:類似于 React Naitive 的 JSX,被編譯成createElement類似的形式丙挽。

一些技巧

在 MacOS 系統(tǒng)中,右鍵開發(fā)者工具『Show Contents』(顯示包內(nèi)容)匀借,就能在Resources/app.nw/下找到相應(yīng)的源碼颜阐,完成路徑如下:/Applications/wechatwebdevtools.app/Contents/Resources/app.nw/。

源碼都是壓縮過后的 JavaScript 腳本吓肋,可以使用js-beautity進行格式化凳怨,以便于閱讀。

// 在源碼目錄的 app 目錄下執(zhí)行find . -type f -name'*.js'-exec js-beautify -r-s2 -p-f'{}'\;

在資源目錄下: app/dist/app.js 的第 37 行window.addEventListener("resize", function() {})之前是鬼,加入nw.Window.get().showDevTools();肤舞。之后每次打開微信開發(fā)者工具時,會自動啟動針對『開發(fā)者工具』的開發(fā)者工具均蜜,并可以通過它調(diào)試微信的開發(fā)者工具李剖。

在打印日志時,不要用console.log囤耳,請使用global.contentWindow.console.log篙顺。這樣,才能輸出到上面所說的開發(fā)者工具的開發(fā)者工具的控制臺里充择。(NW.js 的 Node JS Context 和 Webkit JS Context 是分開的德玫, JavaScript 腳本運行在 Node 的 JS Context 中,因此椎麦,打印其實打印在 Node 的輸出中宰僧,并不在 Webkit 的開發(fā)者工具的控制臺中。global.contentWindow獲取的是 Webkit 的 JS Context 里的 Window)

使用這兩點技巧观挎,讀者們可以優(yōu)雅地去閱讀微信開發(fā)者工具的源碼了琴儿。

在閱讀源碼段化,知道微信小程序的內(nèi)部加載構(gòu)建方式之后,我們可以針對性的對 JavaScript凤类、WXML穗泵、WXSS 等代碼文件進行打包壓縮。

壓縮 JavaScript

由于微信只是將js進行了混淆壓縮谜疤,并沒有打包合并成一個文件佃延。所以我們提供了打包壓縮工具將js文件合并壓縮成一個bundle.js文件。合并成一個文件有以下好處:

require的長路徑?jīng)]了夷磕,腳本壓縮效率變高

代碼合并在一起履肃,混淆性越大

文件合并,減少了 IO 次數(shù)坐桩,提升了加載效率

上文說了 JavaScript 都會被同步加載尺棋,所以不用擔(dān)心打包成一個文件后會延長小程序加載時間。

那么打包壓縮工具具體做了什么工作呢绵跷?

小程序有一個統(tǒng)一的入口是app.js膘螟,而每個頁面都有自己的入口page.js

利用 AST,將page.js里頁面注冊Page(pageOpt)代碼改成global.YPage(pageName, pageIndex)(pageOpt)

pageName頁面路由

pageIndex是打包工具根據(jù)頁面路由內(nèi)部自動維護的

// global.YPage 函數(shù)global.YPage = (pageName, index)=> {return(pageOpt) => {// 其他處理邏輯global['p'+ index] = ()=> {? ? ? ? ? ? Page(pageOpt);? ? ? ? }? ? }}

這樣page.js里實際是這樣的代碼

global['p'+ index] = ()=> {? ? ? Page(pageOpt);}

這樣并不會執(zhí)行Page(pageOpt)碾局,頁面也沒注冊啊荆残。這就是要達到的目的,繼續(xù)往后看净当。

將所有這些入口require到一個統(tǒng)一的入口文件中内斯,然后用 webpack 打包壓縮輸出到bundle.js。

require('app.js')require('page1.js')require('page2.js')...

現(xiàn)在page.js里的代碼都打包到單一文件bundle.js里了像啼。將page.js內(nèi)容替換成global['p' + index]()俘闯,這樣第三步中的Page(pageOpt)不就可以執(zhí)行注冊頁面了。

最后一步忽冻,替換app.js內(nèi)容為require('./bundle.js')即大功告成真朗。

壓縮 WXML、WXSS僧诚、JSON

WXML

//gm去除注釋

/\"\n\s*/g去除換行

WXSS

直接用uglifycss

JSON

直接JSON.stringify(JSON.parse(...))

這里蜜猾,有些讀者會可能提出兩個疑問:

空白字符、換行能有多少振诬,減不了多少吧蹭睡?

開發(fā)者工具為什么不做對這些文件的壓縮?

關(guān)于第一個問題赶么,一個約 1000KB 的代碼肩豁,空白字符和換行大概有 10KB。在有上限的情況之下,10 KB 也是要珍惜的清钥。

關(guān)于第二個問題琼锋,個人認為微信開發(fā)者工具的開發(fā)者覺得沒有必要去做。因為祟昭,WXML 和 WXSS 都會被轉(zhuǎn)義成 JavaScript 腳本缕坎,在此過程中,不管 WXML 和 WXSS 是否被壓縮篡悟,它們的轉(zhuǎn)化結(jié)果是相同的谜叹。因此,壓縮與否搬葬,對于最終產(chǎn)物是沒有影響的(最終產(chǎn)物指在服務(wù)器二次打包后的結(jié)果荷腊,也是用戶真正使用的)。但是急凰,Size 是以本地打包上傳的內(nèi)容進行計算的女仰,不進行此步壓縮,會使微信服務(wù)端判定的 Size 增大抡锈。

刪除無用文件

工程龐大了疾忍,肯定會存在很多無用的空目錄,空文件床三,沒有被import的js锭碳、wxml、wxss文件勿璃。

刪除這些無用文件不僅可以減小 size,還可以提升小程序加載時間推汽。上文說了這些文件都會被轉(zhuǎn)成 JavaScript 進行加載的补疑,是會占用加載時間的。

刪除無用 JavaScript

由于通過 webpack 打包歹撒,除了page.js莲组、bundle .js文件,其他js文件都可以刪掉暖夭。

刪除無用 WXML

打包壓縮工具在打包時锹杈,已經(jīng)記錄了所有頁面的路由。遍歷分析所有路由下的wxml文件迈着,通過xmldom解析代碼記錄其他被import的wxml文件竭望。最后遍歷所有wxml文件,刪除不在import列表里的無用wxml文件裕菠。

刪除無用 WXSS

類似處理 WXML咬清。遍歷分析所有路由下的wxss文件,通過正則/@import\s*["']([^"']+)["']/g分析代碼記錄其他被import的wxss文件。最后遍歷所有wxss文件旧烧,刪除不在import列表里的無用wxss文件影钉。

代碼級優(yōu)化

除了利用工具進行壓縮,在編寫代碼時掘剪,也可以通過一些方法來減小體積平委,在這里簡單列幾點:

使用 ES6 時,盡量不使用依賴 Runtime/Polyfill 的語法夺谁,例如import和class廉赔。

圖標(biāo)使用 Iconfont。

等等…

最終效果

經(jīng)過打包工具的極限壓縮處理予权,還有代碼設(shè)計上的可復(fù)用性昂勉,目前我們七個業(yè)務(wù)線的微信小程序整合后代碼編譯包大小維持在 1300KB 左右。

還剩余 730KB 的可用空間扫腺。

結(jié)語

希望此次在微信小程序整合上做的岗照,工程化抽取公共邏輯、規(guī)范業(yè)務(wù)代碼笆环,通過工具進行針對性的代碼打包壓縮的實踐能給大家?guī)硪欢ǖ膸椭?/p>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末攒至,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子躁劣,更是在濱河造成了極大的恐慌迫吐,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件账忘,死亡現(xiàn)場離奇詭異志膀,居然都是意外死亡,警方通過查閱死者的電腦和手機鳖擒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門溉浙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蒋荚,你說我怎么就攤上這事戳稽。” “怎么了期升?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵惊奇,是天一觀的道長。 經(jīng)常有香客問我播赁,道長颂郎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任容为,我火速辦了婚禮祖秒,結(jié)果婚禮上诞吱,老公的妹妹穿的比我還像新娘。我一直安慰自己竭缝,他們只是感情好房维,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抬纸,像睡著了一般咙俩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上湿故,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天阿趁,我揣著相機與錄音,去河邊找鬼坛猪。 笑死脖阵,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的墅茉。 我是一名探鬼主播命黔,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼就斤!你這毒婦竟也來了悍募?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤洋机,失蹤者是張志新(化名)和其女友劉穎坠宴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绷旗,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡喜鼓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了衔肢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庄岖。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖膀懈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谨垃,我是刑警寧澤启搂,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站刘陶,受9級特大地震影響胳赌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜匙隔,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一疑苫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦捍掺、人聲如沸撼短。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽曲横。三九已至,卻和暖如春不瓶,著一層夾襖步出監(jiān)牢的瞬間禾嫉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工蚊丐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留熙参,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓麦备,卻偏偏與公主長得像孽椰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子泥兰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容