Побудова React-застосунку з нуля
Якщо ваш застосунок містить обмеження, які не спрацюють із наявними фреймворками, або ви бажаєте побудувати власний фреймворк чи розібратися в основах, побудуйте React-застосунок з нуля.
Deep Dive
Початок з нуля — це простий спосіб використати React, але пам’ятайте, що в обмін цей шлях часто схожий на створення власного спеціалізованого фреймворку. З розвитком вимог вам треба буде вирішувати більше системних проблем, для яких наші рекомендовані фреймворки вже мають якісно розроблені та підтримувані рішення.
Наприклад, якщо згодом ваш застосунок потребуватиме рендеринг із боку сервера (SSR), генерацію статичного сайту (SSG) та/або серверні компоненти React (RSC), вам доведеться реалізувати їх самостійно. Так само доведеться самотужки вбудовувати майбутні функції React, які вимагатимуть інтеграції рівня фреймворку, якщо ви захочете їх використовувати.
Наші рекомендовані фреймворки допоможуть вам створювати ефективніші застосунки. Наприклад, зменшення або усунення каскадів (waterfalls) із мережевих запитів покращує UX. Це не завжди в пріоритеті, коли ви створюєте “іграшкові” проєкти, але якщо вашим застосунком активно користуватимуться, ви захочете кращу продуктивність.
Крім того, самостійний шлях також ускладнює підтримування, оскільки спосіб розробки маршрутизації, отримання даних та інших функцій буде унікальним для вашої ситуації. Вам слід вибрати цей варіант, лише якщо вам зручно вирішувати ці проблеми самотужки або якщо ви впевнені, що ці функції вам ніколи не знадобляться.
Щоб отримати список рекомендованих фреймворків, перегляньте розділ “Створення React-застосунку”.
Крок 1: Установіть інструмент збирання
Першим кроком є встановлення інструменту збирання, наприклад, vite
, parcel
або rsbuild
. Вони надають функції для пакування та виконання вихідного коду, сервер для локальної розробки та команду збирання, щоб розгорнути застосунок на робочому сервері.
Vite
Vite — це інструмент збирання, який має на меті забезпечити швидшу та ефективнішу розробку сучасних вебпроєктів.
Vite є досить розсудливим і постачається відразу з виваженими початковими налаштуваннями. Він має багату екосистему плагінів для підтримування швидкого оновлення, JSX, Babel/SWC та інших поширених функцій. Найперше перегляньте плагін React або плагін React SWC і приклад проєкту з React SSR.
Vite вже використовується як інструмент збирання в одному з наших рекомендованих фреймворків — React Router.
Parcel
Parcel поєднує в собі чудовий досвід розробки без додаткових налаштувань із масштабованою архітектурою, що може привести ваш проєкт на самому початку до великого та готового до впровадження застосунку.
Parcel відразу підтримує швидке оновлення, JSX, TypeScript, Flow і стилізацію. Найперше перегляньте рецепт React від Parcel.
Rsbuild
Rsbuild — це інструмент збирання на основі Rspack, який забезпечує безшовну розробку React-застосунків. Він постачається з ретельно налаштованими початковими параметрами й оптимізаціями продуктивності, готовими до використання.
Rsbuild відразу підтримує такі функції React, як швидке оновлення, JSX, TypeScript і стилізація. Найперше перегляньте посібник React від Rsbuild.
Крок 2: Вибудуйте загальні патерни застосунку
Наведені вище інструменти розпочинають із суто клієнтського односторінкового застосунку (SPA), але не мають рішень для іншої звичної функціональності, як-от маршрутизація, отримання даних чи стилізація.
Екосистема React має багато інструментів для вирішення цих проблем. Ми перерахували деякі розповсюджені з них для початку, але сміливо вибирайте інші, якщо вони вам годяться.
Маршрутизація
Маршрутизація (routing) визначає, що відображати, коли користувач відвідує певну URL-адресу. Вам треба налаштувати маршрутизатор, щоб зіставляти URL-адреси з різними частинами застосунку. Вам також потрібно обробляти вкладені маршрути, параметри маршруту та параметри запиту (query parameters). Маршрутизатори можуть бути налаштовані у коді або визначені на основі каталогу компонентів та файлової структури.
Маршрутизатори є основною частиною сучасних застосунків і, як правило, інтегровані з отриманням даних (включно з попереднім отриманням даних для всієї сторінки з метою швидшого завантаження), розділенням коду (для мінімізації розмірів клієнтських бандлів) і підходами до рендерингу сторінок (щоб вирішити, як генерувати кожну сторінку).
Пропонуємо використовувати:
Отримання даних
Отримання даних (data fetching) із сервера чи іншого джерела даних є ключовою частиною більшості застосунків. Щоб робити це належно, потрібно опрацьовувати стани завантаження, стани помилок і кешування отриманих даних, що може бути складно.
Спеціально розроблені бібліотеки отримання даних виконують важку роботу з отримання та кешування даних за вас, даючи вам змогу зосередитися на тому, які саме дані потрібні вашому застосунку та як їх відображати. Ці бібліотеки зазвичай використовуються безпосередньо у ваших компонентах, але також можуть бути інтегровані в завантажувачі маршрутизатора для швидшого попереднього отримання даних та кращої продуктивності, а також під час рендерингу з боку сервера.
Зауважте, що отримання даних безпосередньо в компонентах може призвести до сповільнення завантаження через каскади мережевих запитів, тому ми рекомендуємо якомога частіше попередньо запитувати дані в завантажувачі маршрутизатора або на сервері! Це дає змогу отримувати всі дані сторінки в момент відображення.
Якщо ви отримуєте дані з більшості серверних частин або API у формі REST, пропонуємо використовувати:
Якщо ви отримуєте дані з API у формі GraphQL, пропонуємо використовувати:
Розділення коду
Розділення коду (code-splitting) — це процес розбиття вашого застосунку на менші бандли, які можна завантажувати на вимогу. Розмір коду застосунку збільшується з кожною новою функцією чи доданою залежністю. Застосунки можуть повільно завантажуватися, оскільки перед використанням потрібно надіслати весь код для всього застосунку. Кешування, зменшення функцій/залежностей і перенесення деякого коду для виконання на сервері радше пришвидшать завантаження, але є неповними рішеннями, які можуть пожертвувати функціональністю у разі надмірного використання.
Також якщо ви покладаєтеся на те, щоб застосунки на базі вашого фреймворку розділяли код, ви можете зіткнутися із ситуаціями, коли завантаження стає повільнішим, ніж якби розділення коду не відбувалося взагалі. Наприклад, ліниво завантажена діаграма затримує надсилання коду, необхідного для її рендерингу, відділяючи свій код від решти застосунку. Parcel підтримує розділення коду за допомогою React.lazy. Однак, якщо діаграма завантажує свої дані після свого початкового рендерингу, ви тепер чекаєте двічі. Це каскад: замість одночасного отримання даних для діаграми та надсилання коду для її рендерингу, ви повинні чекати, поки кожен крок завершиться один за одним.
Розділення коду за маршрутом, інтегроване з бандлером й отриманням даних, може зменшити час початкового завантаження вашого застосунку та рендерингу найбільшого видимого вмісту застосунку (малювання найбільшого вмісту, LCP).
Для інструкцій з розділення коду перегляньте документацію вашого інструменту збирання:
Покращення продуктивності застосунку
Оскільки вибраний вами інструмент збирання підтримує лише односторінкові застосунки (SPA), вам треба самостійно реалізувати інші патерни рендерингу, як-от рендеринг із боку сервера (SSR), генерація статичного сайту (SSG) та/або серверні компоненти React (RSC). Хоч спочатку вони рідко потрібні, згодом SSR, SSG або RSC можуть оптимізувати деякі маршрути вашого застосунку.
-
Односторінкові застосунки (SPA) завантажують одну HTML-сторінку та динамічно оновлюють її, коли користувач взаємодіє із застосунком. SPA є швидкими та чуйними, але часто повільніші під час початкового завантаження. SPA є стандартною архітектурою для більшості інструментів збирання.
-
Потоковий рендеринг із боку сервера (SSR) рендерить сторінку на сервері та надсилає повністю відрендерену сторінку клієнту. SSR може покращити продуктивність, але його налаштування та обслуговування радше складніші, ніж для односторінкового застосунку. З додаванням потоковості SSR це може бути ще складнішим. Перегляньте посібник із SSR від Vite.
-
Генерація статичного сайту (SSG) генерує статичні HTML-файли для вашого застосунку під час збирання. SSG може покращити продуктивність, але його налаштування та обслуговування можуть бути складнішими, ніж для рендерингу з боку сервера. Перегляньте посібник із SSG від Vite.
-
Серверні компоненти React (RSC) дають змогу змішувати компільовані, суто серверні та інтерактивні компоненти в одному React-дереві. RSC може покращити продуктивність, але наразі необхідні глибокі знання для його налаштування та обслуговування. Перегляньте приклади RSC від Parcel.
Ваші стратегії рендерингу мають бути інтегровані з вашим маршрутизатором, щоб застосунки, створені за допомогою вашого фреймворку, могли вибирати стратегію рендерингу для кожного маршруту. Це дає змогу використовувати різні стратегії рендерингу без переписування всього застосунку. Наприклад, головна сторінка вашого застосунку може мати користь від статичної генерації (SSG), а сторінка з інформаційною стрічкою — від рендерингу з боку сервера.
Використання слушної стратегії рендерингу для відповідних маршрутів може зменшити час до завантаження першого байта вмісту (час до першого байта), рендерингу першого фрагмента вмісту (малювання першого вмісту, FCP) і рендерингу найбільшого видимого вмісту застосунку (малювання найбільшого вмісту, LCP).
І більше…
Це були лише кілька прикладів функцій, які необхідно враховувати фреймворку під час побудови з нуля. Багато обмежень, з якими ви зіткнетеся, можуть стати заскладними, оскільки кожна проблема взаємопов’язана з іншими та може потребувати глибоких знань у сфері, з якою ви часом не будете знайомі.
Якщо ви не хочете вирішувати ці проблеми самотужки, розпочніть роботу з фреймворком, який вже надає ці функції.