Small package size optimization (uni-app)

 

background

In the process of developing WeChat applets, as the business logic became larger and larger, some problems emerged.

First of all, we found that in dev mode, the local package size has reached 4m+. In this case, it is no longer possible to use real device debugging in dev mode.

Secondly, at this time, there are about 1.8M after the applet is built. Moreover, there are quite a lot of business requirements to be developed in the future, and the package size will definitely be larger.

At this time, you want to optimize the small package size. Let me share my positioning process and solution ideas. Although we use uni-app development, but the idea is general, I hope to give you some help.

How to reduce package size

code analysis

First analyze where the package size is.

Open the native code directory to see the file size. It can be found that js accounts for most of common/vendor.js and page and components.

In the build compilation mode, code compression has been enabled, and other optimization methods need to be considered. At this time, you can use the webpack-bundle-analyzer plug-in . It can help analyze which js modules are in vendor.js, which modules are relatively large, so that we can further optimize the code

Through this plug-in, the following two problems were found.

Question 1: Compiling tree shaking in uni-app custom component mode is invalid

If you are not using uni-app development, you can skip this paragraph

Through code analysis, it is found that some modules should be tree shaking but they are packaged. It is basically determined that tree shaking does not take effect.

The same is webpack4 + babel7. On the premise of directly using the vue-cli create project without using uni-app, tree shaking is no problem. However, when using uni-app to create a new project, tree shaking is invalid.

When checking the babel configuration, it was found that uni-app set modules: 'commonjs' when creating the project. After modification, the tree shaking of the demo is ok. But when I went back to the project and compiled it, another error occurred. Continue to locate and find that it is a compilation problem of uni-app custom component mode . At present, uni-app has fixed the bug I mentioned, although it has not been officially released yet.

Of course, you can solve it without using uni-app custom component mode compilation. uni-app also supports it template模板模式, but there will be some development differences and performance gaps. If you are interested, you can read this article

Problem 2: Some libraries do not support tree shaking

Some libraries (such as lodash) do not use import/export themselves, so webpack cannot tree shake them. We can optimize these libraries according to the situation.

First of all, you can find out whether there is an esm version corresponding to the library on the Internet that can be replaced, such as lodash-es.

Secondly, it can be seen from the code analysis that if each module of the library is in a different file and the entry file is only a unified entry, then we can load it on demand by modifying the writing method, such as

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

We can also use babel-plugin-importplug-ins to uniformly implement on-demand loading for those libraries. Its essence is to uniformly modify the loading path according to the configuration at compile time, without manually modifying the code by yourself.

In the end, if it doesn’t work, either accept it, or rewrite it yourself to contribute to the community~

Specification module development

In order to avoid the trouble of not being able to tree shaking, we also need to follow certain specifications when developing npm modules, so as to reduce the size of the packaged modules.

Support commonjs and es module at the same time

Our module needs to support both commonjs and es module. Only in this way can we not only satisfy the users developed by commonjs, but also support tree shaking.

How? If your code is typescript, take @sentry/browser as an example, you can compile both cjs and esm specification codes at compile time, as follows

// 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",
复制代码

Then specify two entries and no side effects in package.json

  "main": "dist/index.js",
  "module": "esm/index.js",
  "sideEffects": false,
复制代码

In this way, when webpack parses modules ( parsing rules ), it will prioritize parsing the esm directory as needed. And perform tree shaking when no side effects are identified.

If your code itself is es6, you can also do this

"module": "src/index.js",
复制代码

Third-Party Custom Components

If you use a third-party WeChat custom component , since the reference is in the json file, webpack cannot analyze the relevant file through the entry when compiling, so it will not compile or compress it. At this time, we need to deal with it ourselves. And because webpack does not handle it, tree shaking naturally cannot support it, so it is recommended to avoid referencing components in this way as much as possible.

Subcontract

Small program subcontracting is also a common optimization solution.

After analysis, some larger pages can be divided into subpackages. If there is a single page that depends on a third-party custom component, and the third-party component is quite large, you can also consider dividing the page into subpackages. Therefore, try to avoid placing third-party custom components in globalStyle , otherwise it cannot be placed in subpackages.

Big picture don't pack

For large images in small programs, try to avoid packaging them, and put them on CDN to load them through url. Our approach is to load local images during development, automatically publish images in the CI/CD link, and rewrite the address.

How to solve the real machine debugging problem

First of all, check the compiled file and find that common/vendor.jsit is huge, 1.5M in size. Secondly pages, componentsthere is also 1.4M, which accounts for most of the size of js.

Why is the js file so big? The main reason is that there is no compression by default in dev mode, and of course there is no tree shaking.

My choice is to modify the compilation configuration and compress the js code in dev mode . Native code reduced to 2M. The preview size is reduced to 1.4M. The reference configuration is as follows:

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

This doesn't seem like a good solution, but it's simple and effective. I have also considered subpackaging, but subpackaging cannot solve the huge problem of common/vendor.js, and the package is still very large when previewing. If there are other good ways, welcome to leave a message~

 

Guess you like

Origin blog.csdn.net/std7879/article/details/127823537