@KBBS

Как мне использовать React.lazy? Или какие есть альтернативы?

Добрый день.
Предполагается, что на сайте будет некий функционал, который будет использоваться крайне редко.
Данный функционал представлен React-компонентами.
Не хочу включать его в общий бандл (в целях уменьшения размера бандла).
В идеале, было бы неплохо делать ленивую загрузку по требованию.
На данный момент, есть функция-loader, которая принимает URL, по которому необходимо загрузить скрипт, и возвращающая промис.
В нужном месте мы вызываем данную функцию. И в then/catch обрабатываем результат (либо рендерим компонент, либо обрабатываем ошибку.
В общем, имеем что-то вроде этого:
function loadScript(url) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.async = true;
script.onload = resolve;
script.onerror = reject;
script.src = url;
document.body.appendChild(script);
});
}

Использование:
loadScript('/js/lazy-component.js')
.then( ... )
.catch( ... );

В принципе, можно оформить всё несколько иначе. Примерно как описано тут: https://habr.com/ru/post/443124/
Но это уже детали.
В React есть метод lazy.
Пример из документации:
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}

Дополнительно <OtherComponent /> можно обернуть в Suspense.
Проблема в том, что тут используется динамический импорт. Как я понимаю, его поддержка в браузерах пока неочень хорошая. А значит, он мне не подходит.
Далее в документации:

React.lazy принимает функцию, которая должна вызывать динамический импорт: import(). Он должен вернуть Promise, который разрешается в модуль с default
экспортом компонента React.

Использование динамического импорта является обязательным условием?
Либо же есть возможность вместо использования динамического импорта самому вернуть промис?
Если да, то как правильно это написать? Т.к. все мои попытки оказались безуспешными.
В общем, можно ли путём экстримальной селекции и генных мутаций скрестить lazy/Suspense с собственным велосипедом на промисах?
Или может есть ещё какие-либо альтернативы.

Заранее благодарю за любую помощь в решении вопроса.
  • Вопрос задан
  • 326 просмотров
Пригласить эксперта
Ответы на вопрос 3
rockon404
@rockon404 Куратор тега React
Frontend Developer
Проблема в том, что тут используется динамический импорт. Как я понимаю, его поддержка в браузерах пока неочень хорошая. А значит, он мне не подходит.

Если вы в своем проекте не используете сброрщик вроде webpack, то у меня для вас плохие новости.
Ответ написан
Комментировать
lamer350
@lamer350
กำลังสูงสุด
Когда вы уже поймете что один запрос за одним бандлом куда быстрее чем делать ленивую загрузку делая дополнительные запросы на сервер.
Да безусловно, при первой загрузке отрисовка будет чуть дольше, но далее этот файл кешируется. А делая подгрузки отдельно скриптов на страницах где они используются - только замедляет, так как теряется время на загрузку отдельных скриптов. Потому все просто. В шапке грузим стили/js только которые нужны для отрисовки первого экрана страницы, далее все в один банл подгружаем в подвале. Сейчас нет 2g где скорость была 10кб/сек и нужно было бы ждать 1 минуту для загрузки целого бандла) На деле пинг будет выше скорее всего чем скорость загрузки бандла со всеми скриптами, особенно если используете CDN...
Ответ написан
Если у вас есть бандлер (webpack/rollup/etc), то динамический импорт будет вынесен в отдельный чанк а вызов import() сконвертирован во что-то более приемлимое для текущих браузеров, не городите свой велосипед, не нужно. Но если очень уж хочется, то можно самому вернуть промис на обьект es-модуля, react.lazy без разницы откуда вы его взяли.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы