Оптимизация небольшого размера пакета (uni-app)

Апплет WeChat

задний план

В процессе разработки мини-программ WeChat по мере того, как бизнес-логика становилась все больше и больше, выявлялись некоторые проблемы.

Во-первых, мы обнаружили, что в режиме разработки размер локального пакета достиг 4 млн. В этом случае уже невозможно использовать отладку реальной машины в режиме разработки.

Во-вторых, на данный момент после сборки апплета тоже около 1.8M. И в будущем еще довольно много дел нужно развивать, и размер пакета определенно будет больше.

В настоящее время мы хотим оптимизировать небольшой размер пакета. Позвольте мне поделиться своим процессом позиционирования и идеями решения ниже. Хотя мы используем uni-app для разработки, но идея общая, я надеюсь помочь вам.

Как уменьшить размер пакета

анализ кода

Во-первых, где в большой упаковке.

Откройте локальный каталог кода, чтобы просмотреть размер файла. Можно обнаружить, что на js приходится большинство компонентов common/vendor.js и page.

В режиме компиляции сборки включено сжатие кода, и необходимо рассмотреть другие методы оптимизации. В это время вы можете использоватьwebpack-bundle-analyzerплагин. Это может помочь проанализировать, какие модули js находятся в vendor.js, а какие модули больше, чтобы мы могли дополнительно оптимизировать код.

Через этот плагин были обнаружены следующие две проблемы.

Проблема 1: встряхивание дерева при компиляции в режиме пользовательского компонента uni-app недопустимо

Если вы не используете разработку uni-app, вы можете пропустить этот абзац.

В результате анализа кода было обнаружено, что некоторые модули должны быть встряхнуты, но упакованы. В основном точно известно, что встряхивание дерева не действует.

Также вебпак4 + бабел7. При условии использования vue-cli для создания проекта напрямую, без использования uni-app, встряхивание дерева не является проблемой. При использовании uni-app для создания нового проекта встряхивание дерева неэффективно.

Когда я проверил конфигурацию babel, было обнаружено, что uni-app устанавливает модули: «commonjs» при создании проекта. После модификации качание дерева демо в порядке. Но когда я вернулся к проекту для компиляции, я снова получил ошибку. Продолжайте находить и обнаруживать, что этопроблема компиляции режима пользовательского компонента uni-app. В настоящее время уни-приложениеуже исправленоОшибка, которую я упомянул, хотя она официально не выпущена.

Конечно, вы также можете решить эту проблему без компиляции в режиме пользовательского компонента uni-app, uni-app также поддерживаетtemplate模板模式, но будут некоторые различия в разработке и пробелы в производительности, если вам интересно, вы можете взглянутьэта статья

Проблема 2: Некоторые библиотеки не поддерживают встряхивание дерева

Некоторые библиотеки (например, lodash) изначально не используют импорт/экспорт, поэтому веб-пакет не может их трясти. Мы можем оптимизировать эти библиотеки в зависимости от ситуации.

В первую очередь можно узнать, есть ли в интернете версия esm, соответствующая библиотеке, которую можно заменить, например lodash-es.

Во-вторых, из анализа кода мы можем видеть, что если каждая библиотека модулей находится в другом файле, файл ввода представляет собой просто унифицированный вход, то мы можем загружаться по запросу, изменив формулировку, например

import add from "lodash/add";
import Button from 'ant-design-vue/lib/button';

Мы также можем использоватьbabel-plugin-importПлагин реализует загрузку по требованию для этих библиотек единообразно, его суть заключается в единообразном изменении пути загрузки в соответствии с конфигурацией во время компиляции, и вам не нужно вручную модифицировать код самостоятельно.

В конце концов, если это не сработает, либо примите это, либо перепишите сами, чтобы внести свой вклад в сообщество~

Разработка модуля спецификации

Чтобы избежать проблем, связанных с невозможностью встряхивания дерева, нам также необходимо следовать определенным спецификациям при разработке модулей npm, тем самым уменьшая размер упакованных модулей.

Поддержка модулей commonjs и es

Наш модуль должен поддерживать как модуль commonjs, так и модуль es. Таким образом, он может не только удовлетворить пользователей разработки commonjs, но и поддерживать встряхивание дерева.

Как этого добиться? Если ваш код является машинописным, возьмите @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 будет сначала проанализирован по мере необходимости. И встряхивание дерева выполняется, когда не выявлено никаких побочных эффектов.

Если ваш код сама ES6, вы также можете сделать это

"module": "src/index.js",

Сторонние пользовательские компоненты

Если используется третье лицоПользовательские компоненты WeChat, так как ссылка находится в файле json, вебпак не может анализировать соответствующие файлы через запись при компиляции, поэтому он не будет компилироваться, сжиматься и т.д. Вот когда нам нужно разобраться с этим самим. А так как вебпак с этим не справляется, тряска дерева естественно поддерживаться не может, поэтому рекомендуетсяпопытайся избежатьКомпоненты упоминаются таким образом.

Субподрядчик

Небольшая программа субподрядЭто также обычная схема оптимизации.

После анализа некоторые большие страницы можно разделить на подпакеты. Если есть одна страница, которая зависит от стороннего пользовательского компонента, а сторонний компонент довольно большой, вы также можете рассмотреть возможность разделения страницы на подпакеты. ТакСтарайтесь не размещать сторонние пользовательские компоненты в globalStyle., иначе вы не сможете поместить его в подпакет.

Большая картинка не упаковывается

Большая картинка в апплете, старайтесь не запаковывать ее, она должна быть размещена в CDN и загружена через URL. Наш подход заключается в загрузке локальных образов во время разработки, автоматической публикации изображений в ссылке CI/CD и перезаписи адресов.

Как решить проблемы отладки реальных машин

Во-первых, посмотрите на скомпилированный файл и найдите, чтоcommon/vendor.jsОгромный, достаточно иметь 1.5M. Второйpagesа такжеcomponentsЕсть также 1,4M, что составляет размер js и подавляющее большинство.

Почему файл js такой большой? В основном потому, что в режиме разработки по умолчанию нет сжатия и, конечно же, нет сотрясения дерева.

Мой выборИзмените конфигурацию компиляции, чтобы сжать код js в режиме разработки.. Нативный код был уменьшен до 2M. Размер превью уменьшен до 1.4M. Эталонная конфигурация выглядит следующим образом:

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

Это не кажется хорошим решением, но оно простое и эффективное. Мы также рассматривали избыточный пакет, но подпакет не может решить огромную проблему common/vendor.js, пакет все еще очень велик в предварительной версии. Если у вас есть другие лучшие решения, оставьте сообщение~