用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

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

湖人vs掘金:小程序包大小優化(uni-app)

湖人vs爵士季后赛 www.nbgeh.club Rolan 2019-11-28 00:24

在開發微信小程序的過程中,隨著業務邏輯日漸龐大之后,突顯了一些問題。首先我們發現在 dev mode 時,本地包大小已經達到了 4m+,這種情況下,已經無法在 dev mode 使用真機調試了。其次此時,小程序 build 后也有 ...

在開發微信湖人vs爵士季后赛的過程中,隨著業務邏輯日漸龐大之后,突顯了一些問題。

首先我們發現在 dev mode 時,本地包大小已經達到了 4m+,這種情況下,已經無法在 dev mode 使用真機調試了。

其次此時,小程序 build 后也有 1.8M 左右。而且后續還有相當多的業務需求需要開發,包大小肯定會更大。

這時候就想要優化小程序包大小。下面分享一下我的定位過程和解決思路。盡管我們使用 uni-app 開發,但思路是通用的,希望能給大家一些幫助吧。

如何減小包大小

代碼分析

首先分析包大在哪兒了。

打開本地代碼目錄查看文件大小??梢苑⑾?common/vendor.js 和 page,components 中 js 占了大部分。

在 build 編譯模式下,代碼壓縮已經啟用了,需要思考別的優化方式。這時候可以使用 webpack-bundle-analyzer 插件 。它可以幫助分析 vendor.js 中都有哪些 js ???,哪些??楸冉洗?,以便我們進一步優化代碼

通過這個插件,發現了下面兩個問題。

問題一: uni-app 自定義組件模式編譯 tree shaking 無效

如果不是使用 uni-app 開發可以跳過這一段

通過代碼分析發現有些??橛Ω帽?tree shaking 但卻被打包進來了?;救范ㄊ?tree shaking 沒有生效。

同樣是 webpack4 + babel7。在不使用 uni-app,直接使用 vue-cli create 項目的前提下,tree shaking 是沒有問題的。而使用 uni-app 去新建項目,tree shaking 卻無效。

排查 babel 配置時發現是由于 uni-app 在創建項目的時候,設置了 modules: 'commonjs'導致。修改后,demo 的 tree shaking ok。但是回到項目里一編譯,又出錯了。繼續定位發現是 uni-app 自定義組件模式編譯問題 。目前uni-app 已經修復 了我提的bug,雖然還未正式發布。

當然你不使用 uni-app 自定義組件模式編譯也可以解決,uni-app 還支持 template模板模式 ,但是會有一些開發差異和性能差距,有興趣可以看下 這篇文章

問題二:部分庫不支持 tree shaking

有些庫(比如 lodash)本身并沒有使用 import/export,所以 webpack 并不能對它們 tree shaking。這些庫我們可以分情況優化。

首先可以找下網上是否有庫對應的 esm 版本可以替代,如 lodash-es。

其次可以從代碼分析中看出,如果庫的每個??槎莢誆煌募?,入口文件只是一個統一入口,那么我們就可以通過修改寫法按需加載,如

import add from "lodash/add";
import Button from 'ant-design-vue/lib/button';
復制代碼

我們也可以使用 babel-plugin-import 插件針對那些庫統一實現按需加載,它的本質是在編譯時統一按配置修改加載路徑,不需要自己手動去修改代碼。

最后如果都不行,那要么接受,要么自己重寫為社區做貢獻~

規范??榭?/h2>

為了免除無法 tree shaking 的煩惱,我們在開發 npm ??櫚氖焙蛞殘枰裱歡ǖ墓娣?,從而減少??櫬虬蟮拇笮?。

同時支持 commonjs 和 es module

我們的??樾枰敝С?commonjs 和 es module。這樣才能既滿足 commonjs 開發的用戶,又支持 tree shaking。

如何實現呢?如果你的代碼是 typescript,以@sentry/browser 為例,可以在編譯時編譯 cjs 和 esm 兩種規范代碼,如下

// package.json
"build": "run-s build:dist build:esm build:bundle",
"build:bundle": "rollup --config",
"build:dist": "tsc -p tsconfig.build.json",
"build:esm": "tsc -p tsconfig.esm.json",
復制代碼

然后在 package.json 中指定兩個入口以及無副作用標識

"main": "dist/index.js",
  "module": "esm/index.js",
  "sideEffects": false,
復制代碼

這樣當 webpack 解析??? 解析規則 ),就會按需優先解析 esm 目錄。并且當識別到無副作用時進行 tree shaking。

如果你的代碼本身就是 es6,你也可以這樣

"module": "src/index.js",
復制代碼

第三方自定義組件

如果使用了第三方 微信自定義組件 ,由于引用是在 json 文件,所以 webpack 在編譯時并不能通過 entry 分析到相關文件,因此不會對其進行編譯、壓縮等。這時候就需要我們自己處理。而且由于 webpack 不處理,tree shaking 自然也無法支持,因此建議 盡量避免 這種方式引用組件。

分包

小程序分包 也是一種常規的優化方案。

通過分析后,可以將一些較大的頁面劃分為子包。如果有單頁依賴第三方自定義組件,而且第三方組件還挺大,也可以考慮將該頁面劃分為子包。也因此 盡量避免將第三方自定義組件放在 globalStyle ,不然沒法將它放到子包去。

大圖不要打包

小程序中的大圖,盡量避免打包進來,應該放到 CDN 通過 url 加載。我們的做法是在開發時加載本地圖片,在 CI/CD 環節自動化發布圖片,并改寫地址。

如何解決真機調試問題

首先還是查看編譯后的文件,發現 common/vendor.js 巨大,足有 1.5M。其次 pages 和 components 也有 1.4M,而這其中占了 js 的大小又占了絕大部分。

為什么 js 文件這么大呢?主要是因為在 dev mode 默認并沒有壓縮,當然也沒有 tree shaking。

我的選擇是 修改編譯配置,在 dev mode 壓縮 js 代碼 。本地代碼減少到了 2M。預覽大小則是減少到了 1.4M。參考配置如下:

// vue.config.js
    configureWebpack: () => {
        if (isDev && isMp) {
            return {
                optimization: {
                    minimize: true,
                },
            }
        }
    }
復制代碼

這看上去并不是個好方案,但確實簡單有效。也考慮過分包,但分包并不能解決 common/vendor.js 巨大的問題,預覽時包還是很大。如果有其它好的辦法也歡迎留言~

分享至 : QQ空間
收藏
原作者: 張塊塊 來自: 掘金
3d预测号怎样计算公式 湖北11选5玩法技巧 盈丰彩票游戏 在乡下开一家什么店比较赚钱 女士精品店赚钱吗 江西多乐彩开奖电脑版 捕鱼达人深海捕鱼下载 很有钱但没本事赚钱的男人 小红花测评靠什么赚钱 2015年加盟不花钱的暴利赚钱项目 在哪个软件投稿赚钱 双色球开奖结果 美人捕鱼漏洞刷分 北京pk10直播盛 36选7走势图 手机单机梭哈