小程序uni-app(vue3)主包体积优化方案(SDK过大问题)

小程序 0

方案一:业务代码和SDK都在分包

  • 基于@rollup/plugin-commonjs
  • 不同的业务代码可以分包

案例(lottie):

  1. 将lottie的业务代码和lottie库、lottie动画文件放到根目录的lottie文件夹下(node_modules的源文件建议删除)
  2. 开启分包模式(manifest.json),在page.json文件中注册lottie分包,和预加载该分包
  3. 安装依赖 pnpm install @rollup/plugin-commonjs -d
  4. 创建vite.config.js文件
import { defineConfig } from 'vite';import uni from '@dcloudio/vite-plugin-uni';import commonjs from "@rollup/plugin-commonjs";export default defineConfig({	plugins: [uni(),commonjs()]// 使rollup可以打包cjs规范的npm代码});
  1. 在lottie的业务代码中引用自己的lottie库和lottie动画文件即可

方案二:业务代码在主包,SDK在分包

  • 基于分包异步化、@rollup/plugin-commonjs
  • 业务代码不能从主包拆分

案例(lottie):

  1. 将lottie库、lottie动画文件放到根目录的lottieSDK文件夹下(node_modules的源文件建议删除)
  2. lottieSDK分包目录下创建入口页面(用户欺骗uni-app以为你是用了lottie相关依赖)
  3. 开启分包模式(manifest.json),在page.json文件中注册lottieSDK分包和入口页面,和预加载该分包
  4. 安装依赖 pnpm install @rollup/plugin-commonjs -d
  5. 创建vite.config.js文件
import { defineConfig } from 'vite';import uni from '@dcloudio/vite-plugin-uni';import commonjs from "@rollup/plugin-commonjs";export default defineConfig({	plugins: [uni(),commonjs()]// 使rollup可以打包cjs规范的npm代码});
  1. lottieSDK分包入口文件index.vue引用所有用到的依赖
<script>// 这个地方需要引用一下这个包里所有需要打包的sdk 欺骗uni-app以为你使用了分包里的sdkimport lottie from './lottie/index.js';import animationData from './static/lottie.js';let ani = null; // 必须放在外面,uni里不要挂在this上,否则会触发循环引用的报错export default {	data() {},	methods: {		init() {			this.createSelectorQuery()				.select('#lottie_demo')				.node(res => {					console.log(res); // 节点对应的 Canvas 实例。					const canvas = res.node;					const context = canvas.getContext('2d');					canvas.width = 300;					canvas.height = 300;					lottie.setup(canvas);					ani = lottie.loadAnimation({						loop: true,						autoplay: true,						animationData: animationData,						rendererSettings: {							context						}					});				})				.exec();		}	}};</script>
  1. 在lottie的业务代码中引用lottieSDK中的依赖
<template>	<view class="container">		  <view style="text-align: center;">			  <canvas id="lottie_demo" type="2d" style="display: inline-block; width: 300px; height: 300px;" />			  <button @tap="init" style="width: 300px;">初始化</button>			  <button @tap="play" style="width: 300px;">播放</button>			  <button @tap="pause" style="width: 300px;">暂停</button>		  </view>	</view></template><script>import { onShow } from '@dcloudio/uni-app'let ani = null; // 必须放在外面,uni里不要挂在this上,否则会触发循环引用的报错export default {	data() {		return {			lottie : null,			animationData : null,			inited: false		};	},	async onShow() {		await require			.async('../../lottieSDK/lottie/index.js')			.then(({				lottie			}) => {				this.lottie = lottie;				console.log('lottie',this.lottie);			})			.catch((res) => {				console.log(res);			});		await require			.async('../../lottieSDK/static/lottie.js')			.then((animationData) => {				this.animationData = animationData;				console.log('animationData',this.animationData);			})			.catch((res) => {				console.log(res);			});	},	methods: {		init() {			if (this.inited) {				return;			}			this.createSelectorQuery()				.select('#lottie_demo')				.node(res => {					console.log(res); // 节点对应的 Canvas 实例。					const canvas = res.node;					const context = canvas.getContext('2d');					canvas.width = 300;					canvas.height = 300;					this.lottie.setup(canvas);					ani = this.lottie.loadAnimation({						loop: true,						autoplay: true,						animationData: this.animationData,						rendererSettings: {							context						}					});					this.inited = true;				})				.exec();		},		play() {			ani.play();		},		pause() {			ani.pause();		}	}};</script>
  • demo地址miniprogram-packageOptimization
  1. master 分支是无优化方案
  2. businessPackage 分支是方案一:业务代码和SDK都在分包
    主包196KB、lottie分包492KB 压缩后:主包83KB、lottie分包403KB
  3. asyncPackage 分支是方案二:业务代码在主包,SDK在分包请添加图片描述

腾讯IM案例

业务代码与 IM SDK 打包到“IM”分包

  1. TUIKit文件夹移动到im分包目录下,App.vuelogin.vue中的代码移动到im分包的page目录下
  2. node_modules目录下的im相关依赖移动(chat,chat-uikit-engine,tim-profanity-filter-plugin,tim-upload-plugin,tui-core)到im分包的@package目录下

使所有的im代码和功能都放在im分包下
在这里插入图片描述

  1. 开启分包模式(manifest.json),im分包路由(pages.json)

  2. 安装依赖npm install @rollup/plugin-commonjs path -d

  3. 创建vite.config.js文件

import {	defineConfig} from 'vite';import uni from '@dcloudio/vite-plugin-uni';import commonjs from "@rollup/plugin-commonjs";import path from "path";export default defineConfig({	plugins: [uni(),		commonjs() // 使rollup可以打包cjs规范的npm代码	],	resolve: {		alias: { // im的依赖之间有互相的引用, 通过别名将彼此关联起来(因为别名和原名一致,node_modules的依赖需要删掉)			"@tencentcloud": path.resolve(__dirname, "im/@onmcPackage/"),			"tim-upload-plugin": path.resolve(__dirname, "im/@onmcPackage/tim-upload-plugin"),			"tim-profanity-filter-plugin": path.resolve(__dirname,"im/@onmcPackage/tim-profanity-filter-plugin")		}	}});

IM 业务代码在主包, IM SDK 在“ IM SDK”分包中

敬请期待

也许您对下面的内容还感兴趣: