Русский
Русский
English
Статистика
Реклама

Перевод 5 приемов по разделению бандла и ленивой загрузке компонентов в React

image


Разделение Javascript-кода на несколько файлов называется разделением бандла или сборки (bundle splitting). Это позволяет загружать только тот код, который который используется приложением в данный момент, другие части загружаются по необходимости (по запросу пользователя).


Распространенные случаи разделения сборки и ленивой или отложенной загрузки (lazy loading) включают в себя следующее:


  • Загрузка дополнительного кода при переходе пользователя к новому представлению (view слой, отвечающий за визуальное отображение)


  • Загрузка такого кода может быть связана с определенным действием, таким как прокрутка или нажатие кнопки


  • Также можно реализовать предварительную загрузку определенных ресурсов, которые представляют потенциальный интерес для пользователя


  • Это приводит к тому, что когда пользователь захочет получить доступ к определенной функциональности, она уже будет готова



    1. Динамический импорт с помощью Webpack



Webpack позволяет загружать модули (компоненты) динамически во время выполнения кода. Рассмотрим пример:


import { useState } from 'react'function MainComponent() {const [isModalDisplayed, setModalDisplayed] = useState(false)const [ModalComponent, setModalComponent] = useState(null)const loadModalComponent = async () => {const loadResult = await import('./components/Modal.js')setModalComponent(() => loadResult.default)}return (<div>{isModalDisplayed && ModalComponent ? <ModalComponent /> : null}<buttononClick={() => {setModalDisplayed(true)loadModalComponent()}}>Load Modal Component</button></div>)}

Динамический импорт может использоваться в любом месте кода. Такой импорт сообщает Webpack о необходимости создания отдельной сборки для конкретного компонента. Поскольку модальное окно отображается только когда пользователь нажимает кнопку, мы можем отложить загрузку соответствующего кода.


Динамический импорт позволяет каждому компоненту выступать в роли микрофронтенда (microfrontend).


2. Split API для загрузки React-компонентов


Пакет fusion-react предоставляет интерфейс split, компонент-обертку для отображения различных компонентов во время загрузки сборки:


  • Резервного компонента при возникновении ошибки


  • Настоящего компонента после загрузки сборки



Рассматриваемый интерфейс облегчает задачу разделения React-компонентов, позволяя избежать повторения шаблонного кода.


import { Link, Switch, Route } from 'react-router-dom'import { split } from 'fusion-react'const Loading = () => <div>Loading...</div>const Error = () => <div>Error</div>const Hello = split({load: () => import('./components/hello.js'),Loading,Error,})const Root = () => (<><div><ul><li><Link to='/'>Home</Link></li><li><Link to='/hello'>Hello</Link></li></ul></div><Switch><Route path='/' exact component={Home} /><Route path='/hello' component={Hello} /></Switch></>)

Разделение компонентов верхнего уровня на основе маршрутов еще одна техника оптимизации, способ уменьшения времени загрузки приложения.


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


Интерфейс split в приведенном примере откладывает загрузку компонента Hello до того момента, когда пользователь перейдет по соответствующему маршруту. Загружаемый компонент указывается в свойстве load.


В данном случае мы также имеем возможность использовать динамический импорт.


Прим. пер.: существуют более специализированные и популярные решения для ленивой загрузки React-компонентов, например, react-loadable или react-lazyload.


3. Создание вендорного бандла (vendor bundle)


Прежде всего, вы можете спросить, для чего нам это нужно? Основная идея заключается в том, что в вендор помещается (выносится) код, который изменяется намного реже, чем код разрабатываемого приложения. Это позволяет использовать эффективные техники по кэшированию кода для повышения скорости загрузки страниц.


Вот как можно извлечь вендорный бандл из директории node_modules:


const path = require('path')module.exports = {entry: path.resolve(__dirname, 'src/index.js'),output: {path: path.resolve(__dirname, 'dist'),filename: '[name].[contenthash].js',},}

Если после этого вы запустите сборку (yarn build или npm run build), то увидите что-то вроде этого:


 webpack: Build Finished webpack: assets by status 128 KiB [emitted]asset 935.js 124 KiB [emitted] [minimized] (id hint: vendors) 2 related assetsasset main.js 3.24 KiB [emitted] [minimized] (name: main) 1 related assetasset index.html 267 bytes [emitted]assets by status 7.9 KiB [compared for emit]asset main.css 7.72 KiB [compared for emit] (name: main) 1 related assetasset 34.js 187 bytes [compared for emit] [minimized] 1 related assetEntrypoint main 135 KiB (326 KiB) = 935.js 124 KiB main.css 7.72 KiB main.js 3.34 KiB 3 auxiliary assets...webpack 5.5.0 compiled successfully in 4856 ms

4. Создание нескольких вендорных бандлов


Обычно, все модули объединяются в один вендорный бандл.


Знаете ли вы, что мы можем создать несколько таких бандлов?


Например, поскольку React не будет меняться между сборками, имеет смысл закэшировать его в виде отдельного пакета в случаях, когда вопрос производительности является критически важным.


Файл с настройками Webpack принимает свойство optimization, позволяющее разделять вендорный бандл:


module.exports = {splitChunks: {chunks: 'async',cacheGroups: {default: {minChunks: 2,reuseExistingChunk: true,},vendor_react: {test: /.*\/node_modules\/react\/index\.js/,name: 'vendor-react',chunks: 'initial',enforce: true,},},},}

После этого вендорный бандл будет разделен на client-vendor.js и clietn-vendor-react.js.


5. Ленивая загрузка компонентов с помощью React.lazy()


React.lazy() это функция, позволяющая рендерить динамически импортируемые компоненты как обычные компоненты.


Обычный импорт:


import MyComponent from './MyComponent'

Динамический импорт с помощью React.lazy():


const OtherComponent = React.lazy(() => import('./OtherComponent')

Компоненты, загружаемые с помощью React.lazy(), должны быть обернуты в компонент Suspense, который позволяет отображать резервный контент (например, индикатор загрузки) до полной загрузки импортируемого компонента:


import { lazy, Suspense } from 'react'const OtherComponent = lazy(() => import('./OtherComponent'))function MyComponent() {return (<><Suspense fallback={<div>Loading...</div>}><OtherComponent /></Suspense></>)}

Проп fallback принимает любой элемент (компонент). Компонент Suspense может быть помещен на любом родительском по отношению к ленивому компоненту уровне.


Suspense может оборачивать как отдельный компонент, так и группу компонентов:


import { lazy, Suspense } from 'react'const OtherComponent = lazy(() => import('./OtherComponent'))const AnotherComponent = lazy(() => import('./AnotherComponent'))function MyComponent() {return (<><Suspense fallback={<div>Loading...</div>}><section><OtherComponent /><AnotherComponent /></section></Suspense></>)}

Заключение


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


Это, безусловно, положительно повлияет на пользовательский опыт работы с приложением, поскольку оно станет более быстрым и отзывчивым.


Также не стоит забывать о том, что загруженный JavaScript-код, должен быть разобран и выполнен, что также требует некоторого времени и вычислительной мощности.




Облачные серверы от Маклауд быстрые и безопасные.


Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!


Источник: habr.com
К списку статей
Опубликовано: 25.05.2021 16:13:10
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании маклауд

Разработка веб-сайтов

Javascript

Reactjs

Разработка сайтов

Vds

Vps

Быстрый vds

Дешевый vds

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru