Как да използваме React.lazy и Suspense за лениво зареждане на компоненти

React 16.6 доведе до разделяне на кода на ново ниво. Вече можете да зареждате компонентите си, когато това наистина е необходимо, без да инсталирате допълнителни библиотеки.

Какво представляват разделянето на кода и мързеливото зареждане?

Webpack определя разделянето на кода като:

„Техника за разделяне на вашия код на различни пакети, които след това могат да бъдат заредени при поискване или паралелно“. [Източник]

Друг начин да се каже: „зареждане при поискване или паралелно“ е мързеливо зареждане .

Противопоставянето на мързеливото натоварване е нетърпеливо . Тук всичко се зарежда без значение дали го използвате или не.

Защо бихме използвали разделяне на кода и мързеливо зареждане?

Понякога трябва да въведем голяма част от кода, за да покрием някои функционалности. Този код може да импортира зависимост от трета страна или да го напише сам. Тогава този код влияе върху размера на основния пакет.

Изтеглянето на няколко MB е парче за днешната скорост на интернет. Все още трябва да мислим за потребителите с бавна интернет връзка или използване на мобилни данни.

Как се правеше преди React 16.6?

Може би най-популярната библиотека за мързеливо зареждане на компонентите на React е react-loadable.

Важно е, че responsejs.org все още препоръчва, react-loadableако приложението ви се изобразява на сървъра. [Източник]

react-loadableвсъщност е доста подобен на новия подход на React. Ще покажа това в следващата демонстрация.

Необходимо ли е нещо за настройка?

Нека да видим какво може да каже reakjs.org за това:

"Ако използвате Create React App, Next.js, Gatsby или подобен инструмент, ще имате настройка на Webpack от кутията, за да групирате приложението си. Ако не сте, ще трябва да настроите себе си групиране . Например вижте ръководствата за инсталиране и започване на работа в документите на Webpack. “

- реакция.org

Добре, значи се изисква Webpack , който обработва динамично импортиране на пакетите.

Следващата демонстрация се генерира с помощта Create React App.и в този случай Webpack вече е конфигуриран и сме готови за работа.

ДЕМОНСТРАЦИЯ

За тази демонстрация ще използваме react-pdf. react-pdfе страхотна библиотека, използвана за създаване на PDF файлове в браузъра, мобилния телефон и сървъра. Можем да генерираме PDF на сървъра, но ако предпочитаме да го направим от страна на клиента, той идва с цена: размер на пакета.

Използвам разширение за импортиране на разходи за Visual Studio Code, за да видя размерите на използваните библиотеки.

Да приемем, че нашето изискване е да генерираме PDF файл, когато потребителят щракне върху бутона.

Сега това е проста форма само с един случай на употреба. Опитайте се да си представите огромно уеб приложение, където това е малка част от възможностите. Може би тази функционалност не се използва много често от потребителите.

Нека се поставим в тази ситуация. Генерацията на PDF не се използва много често и няма смисъл да се зарежда целият код за всяка заявка за страница.

Ще се опитам да покажа как можем да разработим решение с мързеливо натоварване и без него.

Нетърпелива VS витрина за мързеливо зареждане

И за двата случая ще използваме един компонент, който импортира зависимости от react-pdfи изобразява прост PDF документ.

Тук не се случва нищо грандиозно. Ние внасяме PDFViewer, Document, Page, Text, Viewот react-pdf. Всички те се използват в renderметода на PDFPreviewкомпонент.

PDFPreviewполучава само един propизвикан title. Както подсказва името, той се използва като заглавие в новосъздаден PDF файл.

pdfStyles.js изглежда така:

Нетърпеливо натоварване

Нека първо видим как може да изглежда родителският компонент без лениво зареждане:

което прави следния изглед в браузъра:

Нека да разгледаме кода заедно:

На ред 2 импортираме PDFPreviewкомпонент.

На ред 6 инициализираме състоянието със стойности по подразбиране. nameе поле, използвано като заглавие в PDF файла, докато полето PDFPreviewе булева стойност, която показва или скрива PDFPreview.

Сега, нека да преминем към renderметода и да проверим какво ще се изобрази.

На ред 19 и 25 правим вход и бутон. Когато потребителят въведе входа, nameсъстоянието се променя.

След това, когато потребителят кликне върху „Генериране на PDF“, showPDFPreviewсе задава на true. Компонентът рендерира и показва PDFPreviewкомпонента.

Въпреки че използваме PDFPreviewсамо при кликване от потребителя, целият код, свързан с него, е включен в пакета с приложения:

Това е среда за развитие. При производството размерите ще бъдат значително по-малки. Все пак не разделяме кода оптимално.

Мързеливо зареждане

Направихме само малки промени и нека да преминем през тях.

Ред 2 се заменя със:

const LazyPDFDocument = React.lazy(() => import("./PDFPreview"));

Нека да видим какво казват документите на React за React.lazy:

React.lazyвзема функция, която трябва да извика динамика import(). Това трябва да върне a, Promiseкойто се разрешава в модул с defaultекспортиране, съдържащ React компонент.

- реакция.org

На ред 27 използваме Suspense, който трябва да е родител на лениво натоварен компонент. Когато showPDFPreviewе зададено на true, LazyPDFDocumentзапочва да се зарежда.

Докато дъщерният компонент не бъде разрешен, Suspenseпоказва всичко , което е предвидено за fallbackподпомагане.

Крайният резултат изглежда така:

Можем да видим теглото на 0.chunk.js значително по-малко от преди и 4.chunk.js и 3.chunk.js се зареждат при натискане на бутона.

Заключение

Всеки път, когато въвеждаме нова зависимост в нашия проект, нашата отговорност е да оценим неговите разходи и да проверим как влияе на основния пакет.

След това трябва да попитаме дали тази функционалност ще се използва рядко и можем ли да я заредим при поискване, без да жертваме потребителския опит.

Ако отговорът е да, тогава React.Lazyи Suspenseнаистина да ни помогне с тази задача.

Благодаря ви, че прочетохте! Моля, споделете го с всеки, който може да го намери за полезен и оставете отзиви.