>  기사  >  웹 프론트엔드  >  유니앱의 작은 패키지 크기 최적화

유니앱의 작은 패키지 크기 최적화

coldplay.xixi
coldplay.xixi앞으로
2020-09-27 16:59:297237검색

유니앱의 작은 패키지 크기 최적화

Background

WeChat 애플릿을 개발하는 과정에서 비즈니스 로직이 점점 더 커지면서 몇 가지 문제점이 부각되었습니다.

우선, 개발 모드에서는 로컬 패키지 크기가 4m+에 도달한 것으로 나타났습니다. 이 경우 개발 모드에서는 더 이상 실제 머신 디버깅을 사용할 수 없습니다.

둘째, 이때 미니프로그램은 구축 후 약 180만개 정도 됩니다. 게다가 앞으로도 개발해야 할 비즈니스 요구 사항이 여전히 적지 않으며 패키지 크기도 확실히 더 커질 것입니다.

이번에는 작은 프로그램 패키지 크기를 최적화하고 싶습니다. 아래에서 포지셔닝 프로세스와 솔루션 아이디어를 공유하겠습니다. 우리는 개발을 위해 uni-app을 사용하지만 아이디어는 일반적입니다. 도움이 되길 바랍니다.

패키지 크기 줄이는 방법

코드 분석

패키지가 큰 곳을 먼저 분석하세요.

로컬 코드 디렉터리를 열어 파일 크기를 확인하세요. common/vendor.js와 페이지,컴포넌트의 대부분을 js가 차지하고 있음을 알 수 있습니다.

빌드 컴파일 모드에서는 코드 압축이 활성화되었으며 다른 최적화 방법을 고려해야 합니다. 이때 webpack-bundle-analyzer 플러그인을 사용할 수 있습니다. Vendor.js에 어떤 js 모듈이 있고 어떤 모듈이 더 큰지 분석하는 데 도움이 되므로 코드를 더욱 최적화할 수 있습니다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

이 플러그인을 통해 다음 두 가지 문제가 발견되었습니다.

문제 1: uni-app 사용자 정의 컴포넌트 모드 컴파일 트리 쉐이킹이 유효하지 않습니다

uni-app을 사용하여 개발하지 않는 경우 이 섹션을 건너뛸 수 있습니다

코드 분석을 통해 일부 모듈은 트리 쉐이킹이 되어야 하지만 패키징되어 있음을 발견했습니다. 기본적으로 나무 흔들림이 효과가 없다는 것은 확실합니다.

webpack4 + babel7도 마찬가지입니다. uni-app을 사용하지 않고 vue-cli create 프로젝트를 직접 사용한다는 전제하에 트리 쉐이킹에는 문제가 없습니다. uni-app을 사용하여 새 프로젝트를 생성할 때 트리 쉐이킹이 효과가 없습니다.

바벨 구성을 확인해 보니 프로젝트 생성 시 uni-app 설정 모듈인 'commonjs'에 의해 발생한 것으로 나타났습니다. 수정 후 데모의 트리 흔들림은 괜찮습니다. 그런데 컴파일을 위해 프로젝트로 돌아갔을 때 또 문제가 발생했습니다. 계속해서 찾아보니

uni-app 사용자 정의 구성 요소 모드 컴파일 문제

였습니다. 현재 uni-app에서는 제가 언급한 버그를 수정했지만 아직 공식적으로 출시되지는 않았습니다.

물론 uni-app 사용자 정의 컴포넌트 모드 컴파일을 사용하지 않고도 문제를 해결할 수 있습니다. uni-app은 템플릿 템플릿 모드도 지원하지만, 그렇게 한다면 약간의 개발 차이와 성능 차이가 있을 것입니다. 관심이 있으시면 이 기사를 살펴보세요

문제 2: 일부 라이브러리는 트리 쉐이킹을 지원하지 않습니다

일부 라이브러리(예: lodash)는 트리 쉐이킹을 지원하지 않습니다. 자체적으로 가져오기/내보내기를 하므로 웹팩은 트리를 흔들 수 없습니다. 상황에 따라 이러한 라이브러리를 최적화할 수 있습니다.

우선 lodash-es와 같이 교체 가능한 라이브러리의 해당 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",复制代码

또한 babel-plugin-import 플러그인을 사용하여 해당 라이브러리에 대한 온디맨드 로딩을 ​​균일하게 구현할 수 있습니다. 그 핵심은 컴파일 중 구성에 따라 로딩 경로를 균일하게 수정하는 것입니다. 코드를 수동으로 수정해야 합니다. 결국 안되면 받아들이거나, 직접 다시 작성해서 커뮤니티에 기여하세요~

모듈 개발을 표준화하세요

트리 쉐이킹을 할 수 없는 문제를 피하기 위해 저희도 npm 모듈을 개발할 때 특정 사양을 따라야 하므로 모듈의 패키지 크기를 줄입니다.

🎜commonjs와 es 모듈 모두 지원🎜🎜우리 모듈은 commonjs와 es 모듈을 모두 지원해야 합니다. 이런 방식으로 우리는 commonjs 개발 사용자를 만족시킬 수 있을 뿐만 아니라 트리 쉐이킹도 지원합니다. 🎜🎜어떻게 달성하나요? 코드가 @sentry/browser를 예로 들어 Typescript인 경우 다음과 같이 컴파일 타임에 cjs 및 esm 표준 코드를 컴파일할 수 있습니다. 🎜
  "main": "dist/index.js",  "module": "esm/index.js",  "sideEffects": false,复制代码
🎜 그런 다음 package.json에 두 개의 항목과 no side effect 플래그를 지정합니다. 🎜
"module": "src/index.js",复制代码
🎜 webpack은 모듈을 구문 분석할 때(규칙 구문 분석) 필요에 따라 먼저 esm 디렉터리를 구문 분석합니다. 그리고 부작용이 확인되지 않으면 나무 흔들기를 수행하십시오. 🎜🎜코드 자체가 es6인 경우 다음을 수행할 수도 있습니다.🎜
// vue.config.js
    configureWebpack: () => {        if (isDev && isMp) {            return {
                optimization: {
                    minimize: true,
                },
            }
        }
    }复制代码
🎜타사 사용자 정의 구성 요소🎜🎜타사 WeChat 사용자 정의 구성 요소를 사용하는 경우 참조가 json 파일에 있으므로 webpack은 다음 항목을 전달할 수 없습니다. 컴파일 관련 파일을 분석하므로 컴파일, 압축 등을 하지 않습니다. 이때는 우리가 직접 처리해야 합니다. 그리고 웹팩에서는 이를 처리하지 않기 때문에 트리 쉐이킹을 지원할 수 없으므로 이런 방식으로 컴포넌트를 참조하는 것은 피하는 것이 좋습니다. 🎜🎜하도급🎜🎜미니 프로그램 하도급도 기존의 최적화 솔루션입니다. 🎜

通过分析后,可以将一些较大的页面划分为子包。如果有单页依赖第三方自定义组件,而且第三方组件还挺大,也可以考虑将该页面划分为子包。也因此尽量避免将第三方自定义组件放在 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 巨大的问题,预览时包还是很大。如果有其它好的办法也欢迎留言~

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

위 내용은 유니앱의 작은 패키지 크기 최적화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.im에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
이전 기사:유니앱이 뭐야?다음 기사:유니앱이 뭐야?