Ленивая подгрузка Реакт-компонентов для оптимизации производительности

Поделиться
HTML-код
  • Опубликовано: 9 май 2023
  • Улучшаем производительность Реакт-приложений за счет code-splitting'а и "ленивой" загрузки компонентов. Смотрим на примере SPA-приложения, но данный подход с использованием React.lazy и React.Suspense актуален и для других кейсов.
    Мои курсы по вебу с купонами:
    ✅ mishanep.com/
    📢 Поддержка канала:
    / mishanep
    www.tinkoff.ru/rm/nepomnyasch...
    paypal.me/mishanep
  • НаукаНаука

Комментарии • 84

  • @olegsh2888
    @olegsh2888 Год назад +16

    Очень круто, что ты затрагиваешь темы, которые прям как-будто из повседневной рабочей рутины) буквально недавно этим же вопросом занимался в продакшене)

    • @mishanep
      @mishanep  Год назад +9

      А кто-то рядом пишет, что видео "скатились" 😄
      Мне тоже нравится рассказывать что-то такое, о чем на курсах обычно не говорят, но в реальной жизни пригождается.

    • @michaelveselov589
      @michaelveselov589 Год назад +1

      @@mishanep Михаил, не читайте рядом!)) Мне тут надо было написать числительные словами, я помнил, что у Вас есть хорошее, короткое видео на эту тему. Пять минут - и все было готово!

    • @user-hi6mo5bm4h
      @user-hi6mo5bm4h Год назад +3

      @@mishanep я как и многие - считаю вас одним из лучших учителей рунета )

    • @joyStackk
      @joyStackk Год назад

      @@mishanep да не вообще норм просто такие видосы не для новичков вот и просмотров меньше но те кто смотрят до конца смотрят)

    • @sergeys4732
      @sergeys4732 11 месяцев назад

      @@joyStackk То есть по вашему новичок не может понять настолько простую тему?

  • @FoldyH3ro
    @FoldyH3ro Год назад +1

    Быстро, чётко, по делу. Спасибо большое, Михаил!

  • @victormog
    @victormog Год назад +2

    Функционал уже знал, но Михаил, как всегда, добавил очень полезный *практический* пример использования!
    Спасибо!

  • @user-mu4my8fq2e
    @user-mu4my8fq2e 5 месяцев назад

    Мое почтение, особенно понравился рецепт с оберткой outlet

  • @user-vm2db5cq1g
    @user-vm2db5cq1g Год назад

    Спасибо Михаил, отличное видео!

  • @andreytsapko4213
    @andreytsapko4213 Год назад

    Вижу видео Миши, ставлю лайк!

  • @snatvb
    @snatvb Год назад +2

    ты экономил аж 2кб в данном примере :D
    круто конеш что такие ролики выходят, а то новички часто вообще не знают про такую штуку, а на более менее крупных проектах это ой как актуально :)

  • @matvienko_p
    @matvienko_p Год назад

    классный инструмент. объяснение чёткое!

  • @user-hd7mi3tj5r
    @user-hd7mi3tj5r Год назад

    Спасибо большое за видео!

  • @crn05
    @crn05 Год назад

    Спасибо, как раз скоро нужно будет

  • @dimameshkov9933
    @dimameshkov9933 Год назад +2

    Приветствую Михаил! Спасибо большое за видео, как всегда всё понятно и приятно :) Было бы здорово увидеть видео по архитектуре. Какую сами на работе используете. Особенно для больших проектов.

    • @mishanep
      @mishanep  Год назад +3

      То, с чем я сталкивался на последних проектах, просто стыдно показывать 😄

    • @Mike37373
      @Mike37373 7 месяцев назад

      например@@mishanep

  • @user-js1wo5xl1m
    @user-js1wo5xl1m Год назад +2

    Михаил, как всегда лучший контент! Помню, смотрел вас еще как начинал интересоваться разработкой. С тех пор пишу на Flutter (как-то так получилось). Ваши видео до сих пор смотрю, продолжайте в то же духе.
    Поговаривают что скоро Реакт будет обходиться без API запросов, если такое воплотиться в жизнь, увидим ли мы от вас уроки по этой теме?

    • @mishanep
      @mishanep  Год назад +1

      Приветствую. Nextjs сейчас работает над server actions, они уже в альфе. Выглядит как отсутствие API запросов. Будут ли другие окружения поддерживать такую штуку - большой вопрос. Пока серверные компоненты тоже только в Next доступны.

  • @andygr1n1
    @andygr1n1 4 месяца назад

    полезное видео, быстро и подробно объяснил

  • @meiirzhanilesh7347
    @meiirzhanilesh7347 Год назад

    Спасибо за урок)

  • @klubkov
    @klubkov 10 месяцев назад +2

    А как быть когда на lazy-странице есть еще и фетчинг данных? Получится что есть два пендинга 1 от саспенса, а второй от фетча. Как это правильно обрабатывать, чтобы показывать 1 прелоадер?

  • @ichigorn
    @ichigorn Год назад

    Просто и со вкусом❤

  • @mrrappbit
    @mrrappbit 5 месяцев назад

    От души😊 спасибо

  • @andrewsam224
    @andrewsam224 Год назад

    Сразу лайк. Потом посмотрю.

  • @andrewsam224
    @andrewsam224 Год назад

    React React React с ума сойду но не разберусь.... Спасибо Вам огромное Михаил за помощь в обучении.

  • @K.Partisanov
    @K.Partisanov 2 месяца назад

    Здравствуйте, Михаил! Благодарю за полезное видео, прочитал в статье что lazy не дружит с SSR, что порекомендуете делать в данном случае?

    • @mishanep
      @mishanep  2 месяца назад

      Использовать NextJS

  • @XAH30
    @XAH30 2 месяца назад

    Михаил, спасибо за видос! Круто и понятно объяснил как lazy работает.
    Только судя по комментам - не все понимают зачем это, ведь "экономия на спичках" вроде бы - типа экономия даже в 100кб не имеет смысла в 21 веке.
    Но тут дело не в весе бандла как такового, а в том - что происходит с js после его загрузки. Ваш скрипт парсится браузером, затем строится синтаксическое дерево, потом скрипт может быть частично скомпилирован в байткод(), потом там проходят оптимизационные процессы и наверное, что-то еще что я забыл:)
    И вот только после этого он "передается" на выполнение и начнает строить нам DOM дерево и пр. ништяки.
    Т.е. все эти процессы могут занимать значительное время, которое может быть дольше в несколько раз чем сама загрузка бандла, особенно на слабых машинах.
    Поэтому при ленивой загрузке бандл "разбивается", чтобы быстрее происходила обработка кода, а не его загрузка.

  • @user-uo9nx4tz8u
    @user-uo9nx4tz8u Год назад

    That you very much от меня подписка и лайк

  • @user-yb1ek6xv3w
    @user-yb1ek6xv3w 7 месяцев назад

    Здравствуйте, Михаил!
    Благодарю за хороший и ясный пример!
    Есть вопрос: "Какую цветовую схему для VS Code вы используете в данном уроке? Очень понравилась ;)"
    Заранее благодарю.

    • @mishanep
      @mishanep  7 месяцев назад

      CodeSandbox 2021

  • @dev_islom
    @dev_islom Год назад

    Только смотрел другое видео про эту тему и бам новое видео про это

  • @frich22
    @frich22 5 месяцев назад

    Привет! Спасибо за видео! Наверное довольно глупый вопрос: при общем весе bundle 410kb на каждую страничку мы выигрываем по 300b (очень мало). По мере роста контента вес странички будет расти, но всё равно всегда 90% веса же будет приходиться не на контент, а ээ общий bundle, который от lazy не зависит? Т.е. эта оптимизация хороша, но не имеет особого смысла в масштабе всего приложения. Или на больших проектах совсем другие цифры?

    • @mishanep
      @mishanep  5 месяцев назад

      Конечно на реальном проекте будут другие показатели. Для примера использовались пустышки. Тогда как отдельные страницы по факту, помимо непосредственной реализации, могут импортировать библиотеки, которые не задействованы в других частях сайта.

  • @user-888azim-97
    @user-888azim-97 Год назад

    Михаил, берите выше!

  • @biLLie_wiLLie
    @biLLie_wiLLie Год назад +1

    Спасибо! Очено хочется увидеть от вас полный чеклист подготовки приложения к продакшену. Я слышал, что не надо все компоненты в одну папку пихать - можете рассказать как надо?

    • @mishanep
      @mishanep  Год назад +5

      Приветствую!
      Здесь вряд ли найдется универсальное решение. Есть большие проекты, есть не очень. Есть SPA, есть SSR, есть как часть монолита с тяжелым бэкендом, есть куча всяких абстракций на все случаи жизни. Иногда инструмент, с которым мы работаем, задает четкие правила как надо. Но чаще нет.
      Я не вижу проблемы для маленького приложения сложить все компоненты в одну папку. А в большое часто бывает разбито на микрофронтенды с разными репозиториями или с монорепозиторием.
      Словом, нет универсально ответа на вопрос "как правильно". Делайте как вам это кажется удобным сегодня. И какой бы вариант вы не выбрали, через пару лет вы скорее всего придете к чему-то другому.

  • @ivanMoldovanu
    @ivanMoldovanu 11 месяцев назад

    Михаил, здравствуйте! Хотел задать вопрос под видео о useCallback, но там закрыты комменты...
    Хотел бы спросить:
    Правильно ли я понимаю - если есть дочерний компонент, ререндеры которого очень дорогостоящие, то, в таком случае, мы оборачиваем функцию, которую передаем в него, в useCallback. Вопрос вот в чем - допустим, в этот дочерний компонент мы передаем 5 функций. Если я не оберну хотя бы одну функцию в useCallback, то обернутые остальные 4 функции не имеют смысла(т к при ререндере родительского компонента, из которого мы эти функции передаем в дочерний, ререндерится эта одна единственная необернутая функция, что заставляет ререндерится дочерний компонент)? Заранее спасибо за ответ!

  • @tirthadeva_yoga
    @tirthadeva_yoga Месяц назад

    Миша, спасибо огромное! Применил данную технологию у себя на сайте. Вроде бы как работает шустрее.
    Возник такой вопрос: у меня есть несколько страниц с ссылками на видео RUclips. Внутри страниц есть вкладки аккордеон. Возможно ли применить lazy к отдельной вкладке и если это возможно, то как это сделать?
    Заранее благодарю за ответ!

    • @mishanep
      @mishanep  Месяц назад +1

      Привет, @tirthadeva_yoga
      Можно и для отдельной вкладки. Но насколько понимаю, внутри аккардеонов всё равно используется один и тот же компонент. Поэтому делать ленивым этот компонент не сильно поможет. Здесь можно посмотреть в сторону условной отрисовки для дочерних элементов аккардиона - т.е. не рендерить их вовсе, пока аккордеон закрыт (здесь немного придется возиться с анимацией). И/или можно поискать внешнюю библиотеку, которая не грузит весь youtube до момента клика на видео. Например такой www.npmjs.com/package/react-youtube

    • @tirthadeva_yoga
      @tirthadeva_yoga Месяц назад

      @@mishanep благодарю 🙏🏻

  • @animus9935
    @animus9935 Год назад

    Добрый день Михаил! очень хотелось бы увидеть видео по Angular

    • @mishanep
      @mishanep  Год назад +1

      Я не работал с Angular и пока не планировал в него погружаться.

    • @animus9935
      @animus9935 Год назад

      @@mishanep спасибо за ответ)

  • @paljm345
    @paljm345 7 месяцев назад

    А как тогда сделать, если все данные приходят из 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"}
    ]

  • @kirillpodolinniy309
    @kirillpodolinniy309 Год назад +2

    Михаил, спасибо большое за видео) Есть вопрос: Мы с одной стороны все собираем в один бандл, чтобы добиться чтобы наши приложение имело крутую откликаемость после полной загрузки, а теперь с приходом саспенса, мы подгружаем каждую страницу отдельно. В чем профит?) Почему нельзя просто повесить лоадер при инициализации сайта и первой загрузки) Прошу прощения, если вопрос тупой, но не вижу бенифитов, кроме как случаев, когда у нас отдельно взятые компоненты по-настоящему тяжеловесные)

    • @olegsh2888
      @olegsh2888 Год назад +6

      Это хорошо может работать в связке с «тепловой картой сайта», например. Если мы понимаем, что в нашем продукте есть функциональность, которую пользователь задействует редко, а она связана с тяжелой внешней либой, то имеет смысл эту функциональность сделать ленивой.
      Так что это не руководство к немедленному оборачиванию всего в ленивую загрузку, а лишь дополнительный инструмент)

    • @mishanep
      @mishanep  Год назад +2

      Спасибо, Олег.
      Отличное дополнение.

  • @MaTwist-oz6xo
    @MaTwist-oz6xo Год назад

    Сябки

  • @dmitry8994
    @dmitry8994 8 месяцев назад

    Добрый день.
    Является ли использование данной технологии во всех проектах (больших и маленьких) хорошей практикой?

    • @mishanep
      @mishanep  8 месяцев назад

      Да, является. Хотя очень часто ей пренебрегают.

  • @user-hp1ow7cu7o
    @user-hp1ow7cu7o 9 месяцев назад

    Лайк за то, что вспомнил

  • @romanmed9035
    @romanmed9035 Год назад

    конечно это все полезно если инет стабильный. а если в момент когда нужен этот блок с инетом будет затруднение? и получим пустое место или лоадер будет показан долго-долго. в том и смысл спа что все открывается практически мгновенно.

    • @mishanep
      @mishanep  Год назад

      А теперь представьте, что у вас сотня-другая страниц. И чтобы они мгновенно работали, их надо все разом загрузить. И это при том же самом нестабильном интернете. Как долго пользователь будет ждать? Да и дождется ли?

  • @kaber6400
    @kaber6400 Год назад +1

    Михаил, добрый день, было бы круто если бы вы показали Next js

    • @mishanep
      @mishanep  Год назад +2

      Планирую в ближайшее время

  • @MrEmil-cf8wo
    @MrEmil-cf8wo Год назад

    Привет что за тему кода ты используешь?

  • @quick6response
    @quick6response Год назад

    А Как долго будет хранится в кеше страницы? Например на сайте вышло обновление, а у человека старый кеш страниц, как быть в данном случае?)

    • @mishanep
      @mishanep  Год назад

      Здесь немного о другом. В примере мы не рассматривали как сама страница получает данные. Здесь уйма сценариев. Например, вы можете доверить этот вопрос react-query и отдать вопросы по кэшированию ему.

  • @user-pd3wv9eb8w
    @user-pd3wv9eb8w Год назад

    Как насчёт разобрать новую lazy от react router dom? Вроде как он должен быстрее отрабатывать чем от react

    • @mishanep
      @mishanep  Год назад +1

      Я видел у них новый проп в документации. Выглядит удобно за счет отсутствия Suspense, но на первый взгляд не очевидно как fallback указать. Согласен, что любопытная штука, но реактовская парочка lazy+Suspense не только для роутинга подходит.

  • @andrewsam224
    @andrewsam224 Год назад

    Как тяжело даётся Typescript. Когда я уже пойму и стану програмистом .

  • @druf5962
    @druf5962 Год назад

    А стили так же лениво будут подгружаться или обязательно использовать стайлед-компонентс?

    • @mishanep
      @mishanep  Год назад +1

      Стили импортированные в JS файл также подгружаются лениво.

  • @TpyrBo3Db
    @TpyrBo3Db Год назад

    прикольно, а как понять нужно ли это использовать? какие минусы?

    • @mishanep
      @mishanep  Год назад +1

      Есть разные подходы к данному вопросу. Кто-то в принципе всегда использует ленивую загрузку для всех страниц, кто-то оставляет в бандле наиболее часто посещаемые. А есть подходы, когда в целях оптимизации в бандл поставляется только самое необходимое для первичной загрузки контента, и даже в рамках одной отдельно взятой страницы реализуют lazy loading всего подряд.
      Касаемо минусов можно спорить, потому что мы получаем разный пользовательский опыт. Надо анализировать кто является нашей аудиторией, с каких устройств и при каком интернете, как они взаимодействуют с приложением и так далее.

    • @TpyrBo3Db
      @TpyrBo3Db Год назад

      @@mishanep спасибо за ответ

  • @jamjam3337
    @jamjam3337 Год назад

    👏👍

  • @Wether_Report
    @Wether_Report 6 месяцев назад

    Здравствуйте, Михаил! Спасибо за разбор темы. У меня возникла такая проблема: не вижу под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
      @mishanep  6 месяцев назад

      На первый взгляд выглядит как надо. Возможно нюансы сборки, если вы используете не Webpack. Сходу не скажешь, разбираться надо.

    • @Wether_Report
      @Wether_Report 6 месяцев назад

      @@mishanep у меня дефолтный create react app с апнутым реактом до последней версии, я через development mode запускаю сборку, может build только нужно запускать? у вас в видео не понятно какой mode

    • @mishanep
      @mishanep  6 месяцев назад +1

      Попробуйте обновить еще версию react-script, чтобы он пятым вебпаком собирал, а не четвертым.

  • @Ivan-ee4pz
    @Ivan-ee4pz Год назад

    Первый коментарий, Спасибо огромное автору, ты крутой !!!

  • @telepuzzzik1
    @telepuzzzik1 Год назад

    top

  • @boyywnkobe
    @boyywnkobe Год назад

    ssr like in next

    • @mishanep
      @mishanep  Год назад

      Ssr оно о другом.

    • @boyywnkobe
      @boyywnkobe Год назад

      @@mishanep но кейс по сути тот же, оно не будет грузить пока не будет в поле зора

    • @mishanep
      @mishanep  Год назад +1

      @@boyywnkobe next это делает, но это не про ssr :)