Ленивая загрузка
Это руководство является небольшим продолжением Разбиения кода. Если вы еще не прочли это руководство, пожалуйста, сделайте это сейчас.
Ленивая, или «по требованию», загрузка — отличный способ оптимизировать ваш сайт или приложение. Эта практика по существу заключается в разделении вашего кода по логическим точкам разрыва и последующей загрузке его после того, как пользователь выполнил действие, требующее или предполагающее новый блок кода. Это ускоряет первоначальную загрузку приложения и уменьшает его общий размер, поскольку некоторые блоки могут вообще не загружаться.
Пример
Давайте возьмем пример из Разбиения кода и немного его изменим, чтобы продемонстрировать этот концепцию более наглядно. Код там действительно вызывает генерацию отдельного фрагмента, lodash.bundle.js, и технически «лениво загружает» его сразу после запуска скрипта. Проблема в том, что для загрузки пакета не требуется никакого взаимодействия пользователя — это означает, что каждый раз при загрузке страницы будет выполняться запрос. Это не очень помогает и отрицательно повлияет на производительность.
Давайте попробуем что-то другое. Мы добавим взаимодействие, чтобы записывать текст в консоль, когда пользователь нажимает на кнопку. Однако мы будем загружать этот код (print.js) только после первого взаимодействия. Для этого мы вернемся и переработаем пример последнего динамического импорта из Разбиения кода и оставим lodash в основном фрагменте.
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- /src |- index.js + |- print.js |- /node_modules
src/print.js
console.log('The print.js module has loaded! See the network tab in dev tools...');
export default () => {
console.log('Button Clicked: Here\'s "some text"!');
}; src/index.js
+ import _ from 'lodash';
+
- async function getComponent() {
+ function component() {
const element = document.createElement('div');
- const _ = await import(/* webpackChunkName: "lodash" */ 'lodash');
+ const button = document.createElement('button');
+ const br = document.createElement('br');
+ button.innerHTML = 'Click me and look at the console!';
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+ element.appendChild(br);
+ element.appendChild(button);
+
+ // Note that because a network request is involved, some indication
+ // of loading would need to be shown in a production-level site/app.
+ button.onclick = e => import(/* webpackChunkName: "print" */ './print').then(module => {
+ const print = module.default;
+
+ print();
+ });
return element;
}
- getComponent().then(component => {
- document.body.appendChild(component);
- });
+ document.body.appendChild(component()); Обратите внимание, что при использовании
import()с модулями ES6 необходимо ссылаться на свойство.default, поскольку именно этот объектmoduleбудет возвращен при разрешении обещания.
Теперь давайте запустим webpack и посмотрим на нашу новую функциональность ленивой загрузки:
...
Asset Size Chunks Chunk Names
print.bundle.js 417 bytes 0 [emitted] print
index.bundle.js 548 kB 1 [emitted] [big] index
index.html 189 bytes [emitted]
... Фреймворки
Многие фреймворки и библиотеки имеют свои рекомендации по реализации этого в рамках своих методологий. Вот несколько примеров:
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://v4.webpack.js.org/guides/lazy-loading