В процессе разработки модульность может предотвратить загрязнение переменных и методов, и необходимо сосредоточиться только на части реализации логики, что эффективно уменьшает связь с глобальным и облегчает последующее обслуживание и расширение.
Конечно, я считаю, что дети, разбирающиеся в истории фронтальной модульной разработки, должны были о ней слышать.IIFE
,AMD
,CommonJS
и так далее, все они являются спецификациями, обеспечивающими модульность, покаES2015
После того, как он вышел, модульность была официально включена в его стандарт. Прежде чем говорить о сегодняшней теме, давайте кратко объясним реализацию и различия нескольких вышеописанных модульных методов.webpack模块化优化
Немного помощи.
IIFE
Прежде чем появились различные модульные спецификации,ES5
Он не поддерживает модульную разработку, но в то время были и большие коровы, чтобы лучше избегать функций.副作用
и инкапсуляции, начал ловко придумывать использованиеIIFE
Для достижения модульности (Примечание: сам JS не имеет области на уровне блоков):
Видно, что в оригиналеES5
На базе могут быть инкапсулированы некоторые логические модули, то есть простой闭包行为
, чтобы предотвратить влияние внешней среды на внутренние переменные.
Однако дефект также явно выявляется, он не может реализовать зависимости между модулями, а код выделяется на основной процесс, что создает трудности для последующего обслуживания и модификации.
CommonJS
CommonJS规范
Реализация представляет собой метод синхронной загрузки, который часто используется на стороне сервера.Его конечной целью является предоставление модульной стандартной библиотеки, аналогичной Python, Ruby и Java.
с этой целью,NodeJS
Появление также официально знаменует собойJavascript模块化编程
рождение. На стороне сервера модули должны взаимодействовать с операционной системой или приложениями.NodeJS的模块系统
является ссылкойCommonJS规范
написано.
В спецификации указано, чтоexports
илиmodule.exports
(Примечание: разница между использованием этих двух методов экспорта, заинтересованная детская обувь может посмотреть наОбъяснение API Руан Ифэн) для экспорта внешних переменных или интерфейсов черезrequire方法
Импортируйте выходные данные других модулей в текущую область модуля. Непосредственно на каштаны:
В это время могут быть допрошены детская обувь, затемCommonJS
Можно ли его использовать на стороне клиента?
Ответ положительный. Поскольку в клиенте отсутствуют четыре переменные среды Node.js:module、exports、require、global
, что делает клиент недоступнымCommonJS规范
. Для этого сторонние инструменты или библиотеки (например,require1k,tiny-browser-requireи т. д.) для реализации клиентомCommonJS规范
.
AMD
ввидуES5
внутренний пропускIIFE
Реализованная модуляризация не может быть модульной в том смысле, в каком она существует (аналогично Java, Python и т. д.), поэтому некоторые большие коровы предложилиAMD规范
, он может импортировать модули асинхронно, а модули вполне могут инкапсулировать некоторые логические функции в файл, чтобы их импортировал основной процесс. вRequireJS
Библиотека очень хорошо реализованаAMD规范
, непосредственно на примере:
RequireJS APIнезащищенныйrequire
а такжеdefine
Два глобальных метода могут быть переданы, когда основной процесс или модуль должны зависеть от других модулей.require
а такжеdefine
Два глобальных метода в первом параметре. В то же время мы можем видеть, чтоAMD规范
Реализация представляет собой асинхронную загрузку модулей (несколько модулей будут загружаться параллельно при их вводе, что эффективно повышает эффективность выполнения и неблокирует загрузку страниц). Для каждого модуля вам нужно делать только то, что должен делать модуль, и связь между модулем и основным процессом эффективно уменьшается.
CMD
CMD规范
Также называемое общим определением модуля, оно также реализует асинхронную загрузку модулей.SeaJS库
Эту спецификацию очень легко реализовать, в основном она имеет следующие характеристики:
- Использовать на: и
AMD规范
аналогично, используйтеrequire
а такжеdefine
два глобальных метода, но с использованиемrequire
метод, код модуля выполняется синхронно, что аналогичноCommonJS规范
очень похожий; - Реализация:
CMD规范
Ядро загружается рано, выполняется лениво иAMD规范
Ядро ранняя загрузка, раннее исполнение, конечноCommonJS规范
Ядро — ленивая загрузка и отложенное выполнение;
должны знать о том,CMD规范
использоватьrequire
Причина этого метода в том, что в процессе предварительной загрузки модулей загруженные модули будут храниться в памяти, так что когда клиент выполняет основной процесс и импортирует модули по требованию, модули, хранящиеся в памяти, выполняются синхронно. (Заинтересовала детская обувь, можете прочитать эту статью -Как работает SeaJS)
я считаю,CMD规范
Механизм ленивого выполнения может эффективно улучшить производительность взаимодействия со страницей, так как нет необходимости выполнять другие временно неиспользуемые модули до завершения процесса взаимодействия со страницей (конечно, это только мое личное мнение, если есть детская обувь с разными видами, Вы можете прокомментировать область. Напишите об этом, чтобы обсудить и изучить вместе. Для сравнения производительности детская обувь также может взглянуть.Сравнение AMD и CMD на github SeaJS очень интересно.). И этот механизм также для следующего я хочу упомянутьwebpack模块化优化
тесно связаны.
Сразу перейти к следующемуSeaJS
Проверьте каштаныCMD规范
(Если вас интересует детская обувь, вы также можете посмотретьAPI SeaJS):
UMD
UMD规范
Его можно рассматривать как решение для решения кроссплатформенной загрузки модулей внешнего и внутреннего интерфейса, поддержкиAMD规范
а такжеCommonJS规范
. Проще говоря, он стремится использовать метод реализации, который может загружать модули, совместимые с интерфейсом и сервером.
Нечего сказать, заинтересованная детская обувь может взглянутьОфициальное представление и каштаны UMD. Следующее также использует простой каштан, чтобы оценитьUMD规范
записывается как:
можно увидеть,UMD规范
Метод реализации заключается в том, чтобы сначала определить, поддерживать лиAMD规范
, а затем определить, следует ли поддерживатьCommonJS规范
, когда оба не поддерживаются, модуль определяется непосредственно в глобальном объекте
ES6 Module
из-заES5
Отсутствие модульной концепции загрузки, поэтому вES6
официально включает модульную загрузку в свой стандарт
ES6
Средний модуль — это выходной интерфейс во время компиляции, а различные спецификации загрузки модулей, упомянутые выше, — это выходной интерфейс во время выполнения, как вы можете видеть.ES6 Module
Производительность оптимизирована до определенной степени. Заинтересованная детская обувь может посмотретьВведение Руан Yifeng в модуль ES6. Возьмем ниже каштан:
В настоящее время клиент в основном используетES6 Module
метод загрузки модуля для загрузки модулей и дляNode
Сервер все еще постепенно приближается к этому способу загрузки модулей, но он все еще используется в большинстве случаев.CommonJS规范
.
Я считаю, что после прочтения описанных выше различных реализаций загрузки модулей у вас должно сложиться определенное представление о модульности. Ну что, приступим к сегодняшней теме, вWebpack
как идти правильноApplication
Оптимизирована ли модульность?
возникшие проблемы
При ежедневной модульной разработке страница будет состоять из множества компонентов, и эти компоненты нужно вводить по мере необходимости.Нет сомнений, что сейчас мы используемVue
Как каштан, структура проекта (Ниже показаны только основные каталоги и файлы, остальные каталоги и файлы не показаны.)следующим образом:
|- src
|--- components
|------ message.vue // 详细信息框组件
|------ main.vue // 首页需要的组件
|------ goods.vue // 商品页面组件
|--- router
|------ index.js // 路由文件
|--- App.vue // 入口vue文件
Обычно мы пишем страницу так:
App.vue
файл маршрутизации index.js
Компонент домашней страницы main.vue
Компонент страницы продукта goods.vue
Компонент информации о продукте message.vue
Каштан выше, введенный по URL-адресу во время выполненияlocalhost:8080/#/
будет использоваться напрямуюMain.vue
Домашний компонент, при вводеlocalhost:8080/#/goods
Отображение времениgoods.vue
Товарный компонент, нажмите кнопку, чтобы отобразить его напрямуюmessage.vue
Детальная составляющая.
На данный момент, я хотел бы спросить, вышесказанное простоSPA
Есть ли более оптимизированное решение для каштанов? Что делать, если я хочу ускорить загрузку главной страницы для лучшего взаимодействия с пользователем?
По вышеуказанным проблемам мы будем часто сталкиваться с ними, и вы также можете высказать свое мнение в области комментариев. Вот, я не продам, если это я, первое, что я думаю начать, этоWebpack
, и это основной контент, который следует упомянуть сегодня:用Webpack如何更好地优化复杂程序的模块化
.
Dynamic Import
В настоящее время пытаетсяstage 3
сценаСинтаксис import() для предложений ECMAScript, я полагаю, что многие производители детской обуви знали или слышали об этом, так для чего же это нужно? Согласно официальному заявлению:
ECMAScript modules are completely static, import() enables dynamic loading of ECMAScript modules.
Проще говоря, текущая загрузка модуля загружается статически, а import() позволяет нам загружать соответствующий модуль по требованию. Потом приходит проблема, каштаны выше тоже подгружаются по требованию, домашняя страница нужна толькоMain
Компонент домашней страницы и страница продукта загружаются толькоgoods
а такжеmessage
компоненты. Затем присмотритесь и посмотрите, действительно ли каштаны выше сделали это.按需加载
?
Ответ нет, как я уже упоминал вышеES6 Module
Интерфейс выводится на этапе компиляции, поэтому когда мы используемWebpack
После упаковки все необходимые модули будут внесены вjs文件
середина. Поэтому в процессе загрузки домашней страницы необходимо загрузить всюjs文件
Конечно, для того, чтобы пользователи могли испытать эффект, мы все знаем, что этоjs文件
Есть также некоторые логики модулей, которые нам пока не нужно использовать, и это проблема, с которой мы будем иметь дело дальше.
import()
Возникновение грамматики, рекомбинацияwebpack 4
(Вы также можете выбратьwebpack 3
), вышеуказанная проблема может быть решена изящно. Конечно такжеbabel
трансформация. Вот реализация обработки:
Частичная конфигурация webpack.config.js
Затем измените файл маршрутизации следующим образом:
Вы можете увидеть это, когда мы снова посетимlocalhost:8080/#/
, вы обнаружите, что загрузкаjs文件
Он меньше, чем раньше, и самое главное, что нетGoods
Код товарной составляющей. при повторном посещенииlocalhost:8080/#/goods
, он будет загружаться с сервера асинхронно0.js
файл и измените файл, чтобы он содержалGoods
Код товарной составляющей. Видно, что не только редуцируется основной процессjs
Размер файла, ускоряющий загрузку страницы, а также асинхронную загрузку необходимых файлов модулей по запросу.
Хорошо, вот и мы, если я хочу снова оптимизировать егоGoods
в компоненте продуктаMessage
Компонент Details, поскольку он загружается только при нажатии кнопки, можем ли мы также разрешить его ленивую загрузку, пустьlocalhost:8080/#/goods
Следующая страница загружается быстрее?
Ответ да, но вам нужно использоватьVue
серединаcomponent
Грамматика, без лишних слов, давайте изменим ее:
Компонент страницы продукта goods.vue
когда мы приедем сноваlocalhost:8080/#/goods
, ты найдешьjs文件
меньше, чем раньшеMessage
Подробный информационный код компонента для ускорения процесса загрузки, и после нажатия кнопки он будет представлен динамически.1.js
файл, который также загружается асинхронно с сервераMessage
Детальная составляющая.
В это время могут возникнуть вопросы по тестированию детской обуви.Message
Когда появится компонент с подробной информацией, а затем снова нажмите кнопку, вам нужно повторноrender
, разве это не требует определенной производительности? Ответ заключается в том, что будут потери, поэтому, если вы хотите оптимизировать его, что вы можете сделать? Это просто, просто используйтеVue API
незащищенный<keep-alive>组件
завернуть наш<component>
Вот и все, это позволит эффективно сохранить компонент в памяти, и его можно будет прочитать прямо из памяти при следующем доступе.
В этот момент, возможно, некоторые детские туфли снова зададут вопросы, указанные выше0.js
документы и1.js
Какой к черту файл? Будьте терпеливы и посмотрите вниз, может быть, вы хотите сюрприз, ха-ха 🙊
Magic Comments
Почему появляется вышеуказанное0
а также1
, причина в том, что для динамического введенияimport()
Не указывать имя модуляchunkName
час,Webpack
По умолчанию следующие динамически импортируемые файлы именуются последовательно от 0 до n.
Однако для этих чисел 0 или n у нас нет возможности узнать динамическое введениеjs文件
Какому модулю принадлежит, для этогоWebpack
также предоставляет намMagic Comments
, поэтому вы можете настроить имя модуля.
Возьмем за каштан динамический импорт вышеуказанного файла маршрутизации, он очень прост в использовании:
В это время изlocalhost:8080/#/
доступ вlocalhost:8080/#/goods
, вы обнаружите, что загрузка не0.js
, ноgoods.js
, что позволяет легко узнать, какие модули динамически импортируются. Конечно, если вас интересует детская обувь, вы также можете подумать об указанииMessage详细信息组件
при динамическом импортеchunkName
.
Пока упомянутые выше решения могут эффективно оптимизировать наш нынешний этап модульной разработки, конечно, можно попробовать и детскую обувь.
Extension
На самом деле, на мой взгляд, его можно еще оптимизировать. возьми вышеперечисленноеGoods
Товарный компонент, при нажатии кнопки, если загруженный модуль относительно большой, пользователю приходится ждать полной загрузки.message.js
Файл может отображаться только во всплывающем окне (конечно, таких случаев не так много, т.к. запакованные js файлы вообще хранятся на кдн, а запрос будет загружаться по принципу близости, что эффективно избегает этой проблемы, но мы все же можем обсудить, как можно избежать этой проблемы). По этой причине, есть ли у нас план по эффективному устранению этой задержки? Я не буду продавать здесь,Webpack 4.6
, указывая на явную поддержкуprefetching and preloading
, и эти две вещи способны решить проблему, с которой мы только что столкнулись.
Preload And PreFetch
Preload
Предварительно загружен,PreFetch
это модуль, который, по прогнозам, будет загружен, оба из которыхlink
свойства под этикеткой. Интересует детская обувь, можете посмотретьОтносительно приоритета этих двух исполнений на стороне клиента
Проще говоря,Preload
приоритетHeight
,а такжеPreFetch
тогдаLow
. Это разница между двумя:
-
preload
: В основном используется для предварительной загрузки текущей страницы, собрания и основного файла.bundle.js
Параллельная загрузка и приоритетное получение могут использоваться для предварительной загрузки некоторых необходимых модулей. -
prefetch
: В основном используется для следующей операции или страницы, она будет загружена, когда браузер неактивен, с самым низким приоритетом.
Кроме того, следует отметить, что,preload
а такжеprefetch
Текущий уровень поддержки существующих браузеров не так дружелюбен. В частности, вы можете посмотреть на две совместимости:Совместимость с предварительной загрузкойа такжеСовместимость с предварительной выборкой
Хоть совместимость и не такая дружная,preload
а такжеprefetch
Все они декларативные, поэтому даже если они не поддерживаются, они не повлияют ни на какие функции существующей страницы.
Видя это, считается, что каждый должен также думать об использованииprefetch
Он может решить проблему ожидания с задержкой, с которой мы столкнулись выше, так как же его написать? Здесь нам также нужно использоватьWebpack
изpreload-webpack-plugin
Плагин, конфигурация написана следующим образом:
Частичная конфигурация webpack.config.js
В это время будетWebpack 4.6+
В версии модифицированные компоненты страницы продукта выглядят следующим образом:
Компонент страницы продукта goods.vue
Как видите, просто добавьтеwebpackPrefetch: true
рекомбинация аннотацийpreload-webpack-plugin
Плагины могут импортировать динамически импортируемые модулиPrefetch
.
когда мы приедем сноваlocalhost:8080/#/goods
, вы обнаружите, что после загрузки основного процессаjs文件
а потом при простое в браузере автоматически загрузитсяmessage.js文件
И вы можете увидеть его приоритетLow
из. Кроме того, мы также можем видеть, что в<head>
этикетка, через<link>
использование ярлыкаrel="prefetch"
загрузитьmessage.js文件
. В это время, если вы снова нажмете кнопку, вам больше не нужно будет ждать, пока задержка загрузится напрямую.Message组件
.
Что касается визуализаций вышеописанной операции, то скриншоты делать не буду, интересующиеся детской обувью могут попробовать и убедиться в них лично, чтобы было более глубокое впечатление. Если возникнут неудобства, извиняюсь здесь 🙈
дляWebpack模块化加载优化
, могут быть некоторые лучшие и лучшие решения, и вы можете делиться ими и учиться вместе в области комментариев. Вышеупомянутая схема оптимизации действительно может использоваться в повседневной модульной разработке, но, пожалуйста, оптимизируйте ее в соответствии с анализом сценария приложения для ваших собственных потребностей.При неправильном использовании оптимизация может привести к снижению производительности.