首頁 > web前端 > uni-app > uni-app之小程式包大小優化

uni-app之小程式包大小優化

coldplay.xixi
發布: 2020-09-27 17:02:54
轉載
7356 人瀏覽過

uni-app之小程式包大小優化

背景

在開發微信小程式的過程中,隨著業務邏輯日漸龐大之後,突顯了一些問題。

首先我們發現在 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插件來針對那些庫統一實現按需加載,它的本質是在編譯時統一按配置修改加載路徑,不需要自己手動去修改程式碼。

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

規範模組開發

為了免除無法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。其次pagescomponents也有 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 巨大的问题,预览时包还是很大。如果有其它好的办法也欢迎留言~

更多相关免费学习推荐:微信小程序开发

以上是uni-app之小程式包大小優化的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.im
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板