Ленивая подгрузка Реакт-компонентов для оптимизации производительности
Ғылым және технология
Улучшаем производительность Реакт-приложений за счет code-splitting'а и "ленивой" загрузки компонентов. Смотрим на примере SPA-приложения, но данный подход с использованием React.lazy и React.Suspense актуален и для других кейсов.
Мои курсы по вебу с купонами:
✅ mishanep.com/
📢 Поддержка канала:
/ mishanep
www.tinkoff.ru/rm/nepomnyasch...
paypal.me/mishanep
Пікірлер: 84
Очень круто, что ты затрагиваешь темы, которые прям как-будто из повседневной рабочей рутины) буквально недавно этим же вопросом занимался в продакшене)
@mishanep
Жыл бұрын
А кто-то рядом пишет, что видео "скатились" 😄 Мне тоже нравится рассказывать что-то такое, о чем на курсах обычно не говорят, но в реальной жизни пригождается.
@michaelveselov589
Жыл бұрын
@@mishanep Михаил, не читайте рядом!)) Мне тут надо было написать числительные словами, я помнил, что у Вас есть хорошее, короткое видео на эту тему. Пять минут - и все было готово!
@user-hi6mo5bm4h
Жыл бұрын
@@mishanep я как и многие - считаю вас одним из лучших учителей рунета )
@joyStackk
Жыл бұрын
@@mishanep да не вообще норм просто такие видосы не для новичков вот и просмотров меньше но те кто смотрят до конца смотрят)
@sergeys4732
11 ай бұрын
@@joyStackk То есть по вашему новичок не может понять настолько простую тему?
Быстро, чётко, по делу. Спасибо большое, Михаил!
Функционал уже знал, но Михаил, как всегда, добавил очень полезный *практический* пример использования! Спасибо!
Мое почтение, особенно понравился рецепт с оберткой outlet
Спасибо Михаил, отличное видео!
Вижу видео Миши, ставлю лайк!
ты экономил аж 2кб в данном примере :D круто конеш что такие ролики выходят, а то новички часто вообще не знают про такую штуку, а на более менее крупных проектах это ой как актуально :)
классный инструмент. объяснение чёткое!
Спасибо большое за видео!
Спасибо, как раз скоро нужно будет
Приветствую Михаил! Спасибо большое за видео, как всегда всё понятно и приятно :) Было бы здорово увидеть видео по архитектуре. Какую сами на работе используете. Особенно для больших проектов.
@mishanep
Жыл бұрын
То, с чем я сталкивался на последних проектах, просто стыдно показывать 😄
@Mike37373
7 ай бұрын
например@@mishanep
Михаил, как всегда лучший контент! Помню, смотрел вас еще как начинал интересоваться разработкой. С тех пор пишу на Flutter (как-то так получилось). Ваши видео до сих пор смотрю, продолжайте в то же духе. Поговаривают что скоро Реакт будет обходиться без API запросов, если такое воплотиться в жизнь, увидим ли мы от вас уроки по этой теме?
@mishanep
Жыл бұрын
Приветствую. Nextjs сейчас работает над server actions, они уже в альфе. Выглядит как отсутствие API запросов. Будут ли другие окружения поддерживать такую штуку - большой вопрос. Пока серверные компоненты тоже только в Next доступны.
полезное видео, быстро и подробно объяснил
Спасибо за урок)
А как быть когда на lazy-странице есть еще и фетчинг данных? Получится что есть два пендинга 1 от саспенса, а второй от фетча. Как это правильно обрабатывать, чтобы показывать 1 прелоадер?
Просто и со вкусом❤
От души😊 спасибо
Сразу лайк. Потом посмотрю.
React React React с ума сойду но не разберусь.... Спасибо Вам огромное Михаил за помощь в обучении.
Здравствуйте, Михаил! Благодарю за полезное видео, прочитал в статье что lazy не дружит с SSR, что порекомендуете делать в данном случае?
@mishanep
2 ай бұрын
Использовать NextJS
Михаил, спасибо за видос! Круто и понятно объяснил как lazy работает. Только судя по комментам - не все понимают зачем это, ведь "экономия на спичках" вроде бы - типа экономия даже в 100кб не имеет смысла в 21 веке. Но тут дело не в весе бандла как такового, а в том - что происходит с js после его загрузки. Ваш скрипт парсится браузером, затем строится синтаксическое дерево, потом скрипт может быть частично скомпилирован в байткод(), потом там проходят оптимизационные процессы и наверное, что-то еще что я забыл:) И вот только после этого он "передается" на выполнение и начнает строить нам DOM дерево и пр. ништяки. Т.е. все эти процессы могут занимать значительное время, которое может быть дольше в несколько раз чем сама загрузка бандла, особенно на слабых машинах. Поэтому при ленивой загрузке бандл "разбивается", чтобы быстрее происходила обработка кода, а не его загрузка.
That you very much от меня подписка и лайк
Здравствуйте, Михаил! Благодарю за хороший и ясный пример! Есть вопрос: "Какую цветовую схему для VS Code вы используете в данном уроке? Очень понравилась ;)" Заранее благодарю.
@mishanep
7 ай бұрын
CodeSandbox 2021
Только смотрел другое видео про эту тему и бам новое видео про это
Привет! Спасибо за видео! Наверное довольно глупый вопрос: при общем весе bundle 410kb на каждую страничку мы выигрываем по 300b (очень мало). По мере роста контента вес странички будет расти, но всё равно всегда 90% веса же будет приходиться не на контент, а ээ общий bundle, который от lazy не зависит? Т.е. эта оптимизация хороша, но не имеет особого смысла в масштабе всего приложения. Или на больших проектах совсем другие цифры?
@mishanep
5 ай бұрын
Конечно на реальном проекте будут другие показатели. Для примера использовались пустышки. Тогда как отдельные страницы по факту, помимо непосредственной реализации, могут импортировать библиотеки, которые не задействованы в других частях сайта.
Михаил, берите выше!
@mishanep
Жыл бұрын
Это куда? =)
Спасибо! Очено хочется увидеть от вас полный чеклист подготовки приложения к продакшену. Я слышал, что не надо все компоненты в одну папку пихать - можете рассказать как надо?
@mishanep
Жыл бұрын
Приветствую! Здесь вряд ли найдется универсальное решение. Есть большие проекты, есть не очень. Есть SPA, есть SSR, есть как часть монолита с тяжелым бэкендом, есть куча всяких абстракций на все случаи жизни. Иногда инструмент, с которым мы работаем, задает четкие правила как надо. Но чаще нет. Я не вижу проблемы для маленького приложения сложить все компоненты в одну папку. А в большое часто бывает разбито на микрофронтенды с разными репозиториями или с монорепозиторием. Словом, нет универсально ответа на вопрос "как правильно". Делайте как вам это кажется удобным сегодня. И какой бы вариант вы не выбрали, через пару лет вы скорее всего придете к чему-то другому.
Михаил, здравствуйте! Хотел задать вопрос под видео о useCallback, но там закрыты комменты... Хотел бы спросить: Правильно ли я понимаю - если есть дочерний компонент, ререндеры которого очень дорогостоящие, то, в таком случае, мы оборачиваем функцию, которую передаем в него, в useCallback. Вопрос вот в чем - допустим, в этот дочерний компонент мы передаем 5 функций. Если я не оберну хотя бы одну функцию в useCallback, то обернутые остальные 4 функции не имеют смысла(т к при ререндере родительского компонента, из которого мы эти функции передаем в дочерний, ререндерится эта одна единственная необернутая функция, что заставляет ререндерится дочерний компонент)? Заранее спасибо за ответ!
Миша, спасибо огромное! Применил данную технологию у себя на сайте. Вроде бы как работает шустрее. Возник такой вопрос: у меня есть несколько страниц с ссылками на видео KZread. Внутри страниц есть вкладки аккордеон. Возможно ли применить lazy к отдельной вкладке и если это возможно, то как это сделать? Заранее благодарю за ответ!
@mishanep
Ай бұрын
Привет, @tirthadeva_yoga Можно и для отдельной вкладки. Но насколько понимаю, внутри аккардеонов всё равно используется один и тот же компонент. Поэтому делать ленивым этот компонент не сильно поможет. Здесь можно посмотреть в сторону условной отрисовки для дочерних элементов аккардиона - т.е. не рендерить их вовсе, пока аккордеон закрыт (здесь немного придется возиться с анимацией). И/или можно поискать внешнюю библиотеку, которая не грузит весь youtube до момента клика на видео. Например такой www.npmjs.com/package/react-youtube
@tirthadeva_yoga
Ай бұрын
@@mishanep благодарю 🙏🏻
Добрый день Михаил! очень хотелось бы увидеть видео по Angular
@mishanep
Жыл бұрын
Я не работал с Angular и пока не планировал в него погружаться.
@animus9935
Жыл бұрын
@@mishanep спасибо за ответ)
А как тогда сделать, если все данные приходят из json файла? Приходит json с маcсивом объектов по типу: [ {id: "page1", title: "Page 1", order: 0, path: "pages/page1.js"}, {id: "page2", title: "Page 2", order: 1, path: "pages/page2.js"} ]
Михаил, спасибо большое за видео) Есть вопрос: Мы с одной стороны все собираем в один бандл, чтобы добиться чтобы наши приложение имело крутую откликаемость после полной загрузки, а теперь с приходом саспенса, мы подгружаем каждую страницу отдельно. В чем профит?) Почему нельзя просто повесить лоадер при инициализации сайта и первой загрузки) Прошу прощения, если вопрос тупой, но не вижу бенифитов, кроме как случаев, когда у нас отдельно взятые компоненты по-настоящему тяжеловесные)
@olegsh2888
Жыл бұрын
Это хорошо может работать в связке с «тепловой картой сайта», например. Если мы понимаем, что в нашем продукте есть функциональность, которую пользователь задействует редко, а она связана с тяжелой внешней либой, то имеет смысл эту функциональность сделать ленивой. Так что это не руководство к немедленному оборачиванию всего в ленивую загрузку, а лишь дополнительный инструмент)
@mishanep
Жыл бұрын
Спасибо, Олег. Отличное дополнение.
Сябки
Добрый день. Является ли использование данной технологии во всех проектах (больших и маленьких) хорошей практикой?
@mishanep
8 ай бұрын
Да, является. Хотя очень часто ей пренебрегают.
Лайк за то, что вспомнил
конечно это все полезно если инет стабильный. а если в момент когда нужен этот блок с инетом будет затруднение? и получим пустое место или лоадер будет показан долго-долго. в том и смысл спа что все открывается практически мгновенно.
@mishanep
Жыл бұрын
А теперь представьте, что у вас сотня-другая страниц. И чтобы они мгновенно работали, их надо все разом загрузить. И это при том же самом нестабильном интернете. Как долго пользователь будет ждать? Да и дождется ли?
Михаил, добрый день, было бы круто если бы вы показали Next js
@mishanep
Жыл бұрын
Планирую в ближайшее время
Привет что за тему кода ты используешь?
@mishanep
Жыл бұрын
CodeSandbox
А Как долго будет хранится в кеше страницы? Например на сайте вышло обновление, а у человека старый кеш страниц, как быть в данном случае?)
@mishanep
Жыл бұрын
Здесь немного о другом. В примере мы не рассматривали как сама страница получает данные. Здесь уйма сценариев. Например, вы можете доверить этот вопрос react-query и отдать вопросы по кэшированию ему.
Как насчёт разобрать новую lazy от react router dom? Вроде как он должен быстрее отрабатывать чем от react
@mishanep
Жыл бұрын
Я видел у них новый проп в документации. Выглядит удобно за счет отсутствия Suspense, но на первый взгляд не очевидно как fallback указать. Согласен, что любопытная штука, но реактовская парочка lazy+Suspense не только для роутинга подходит.
Как тяжело даётся Typescript. Когда я уже пойму и стану програмистом .
А стили так же лениво будут подгружаться или обязательно использовать стайлед-компонентс?
@mishanep
Жыл бұрын
Стили импортированные в JS файл также подгружаются лениво.
прикольно, а как понять нужно ли это использовать? какие минусы?
@mishanep
Жыл бұрын
Есть разные подходы к данному вопросу. Кто-то в принципе всегда использует ленивую загрузку для всех страниц, кто-то оставляет в бандле наиболее часто посещаемые. А есть подходы, когда в целях оптимизации в бандл поставляется только самое необходимое для первичной загрузки контента, и даже в рамках одной отдельно взятой страницы реализуют lazy loading всего подряд. Касаемо минусов можно спорить, потому что мы получаем разный пользовательский опыт. Надо анализировать кто является нашей аудиторией, с каких устройств и при каком интернете, как они взаимодействуют с приложением и так далее.
@TpyrBo3Db
Жыл бұрын
@@mishanep спасибо за ответ
👏👍
Здравствуйте, Михаил! Спасибо за разбор темы. У меня возникла такая проблема: не вижу подuрузки чанков, один бандл на все страницы, но вроде всё сделал как вы объясняли. Вот мой код: import React from 'react'; import {lazy, Suspense } from 'react'; import ReactDOM from 'react-dom'; import App from './components/app/App'; import MainPage from './components/pages/main'; import './style/style.scss'; import { ClipLoader } from 'react-spinners'; import { createBrowserRouter, RouterProvider} from 'react-router-dom'; const ComicsPage = lazy(() => import('./components/pages/comicsPage')); const SingleComicPage = lazy(() => import('./components/pages/singleComicPage')); const ComicsList = lazy(() => import('./components/comicsList/ComicsList')); const router = createBrowserRouter([ { path: '/', element: , children: [ { index: true, element: }, { path: 'comics', element: , children : [ { index: true, element: }, { path: ':id', element: } ] }, ] } ] ) ReactDOM.render( , document.getElementById('root') ); Подскажите, пожалуйста, что не так. Внутри lazy компонентов export default везде
@mishanep
6 ай бұрын
На первый взгляд выглядит как надо. Возможно нюансы сборки, если вы используете не Webpack. Сходу не скажешь, разбираться надо.
@Wether_Report
6 ай бұрын
@@mishanep у меня дефолтный create react app с апнутым реактом до последней версии, я через development mode запускаю сборку, может build только нужно запускать? у вас в видео не понятно какой mode
@mishanep
6 ай бұрын
Попробуйте обновить еще версию react-script, чтобы он пятым вебпаком собирал, а не четвертым.
Первый коментарий, Спасибо огромное автору, ты крутой !!!
top
ssr like in next
@mishanep
Жыл бұрын
Ssr оно о другом.
@boyywnkobe
Жыл бұрын
@@mishanep но кейс по сути тот же, оно не будет грузить пока не будет в поле зора
@mishanep
Жыл бұрын
@@boyywnkobe next это делает, но это не про ssr :)