React Labs: Над чим ми працювали - червень 2022

15 червня, 2022 року від Ендрю Кларка, Дена Абрамова, Яна Кассенса, Джозефа Савона, Джоша Сторі, Лорен Тан, Луни Руан, Менгді Чен, Ріка Хенлона, Роберта Чжана, Сатьї Гунасекаран, Себастьяна Маркбоге та Сюань Хуана


React 18 готувався роками, і разом з цим надав цінні уроки для команди React. Його випуск став результатом багаторічних досліджень та вивчення багатьох шляхів. Деякі з цих шляхів були успішними; багато інших були глухими кутами, які призвели до нових ідей. Один з уроків, який ми вивчили, полягає в тому, що спільнота розчаровується, коли чекає на нові функції, не маючи уявлення про шляхи, які ми досліджуємо.


Зазвичай ми працюємо над кількома проектами в будь-який час, від більш експериментальних до чітко визначених. Забігаючи наперед, ми хотіли б почати регулярно ділитися з спільнотою інформацією про те, над чим ми працюємо в рамках цих проектів.

Визначення очікування - це не дорожня карта з чіткими термінами. Багато з цих проектів перебувають на стадії активних досліджень, і їх важко назвати конкретними точками відправлення. Можливо, вони навіть ніколи не будуть реалізовані в поточній ітерації, залежно від того, що ми дізнаємося. Натомість ми хочемо поділитися з вами проблемними часьинами, над якими ми активно працюємо, і тим, що ми вже дізналися.

Серверні компоненти

Ми анонсували експериментальну демонстрацію Компонентів сервера React (RSC) у грудні 2020 року. З того часу ми дописуємо його залежності в React 18 та працюємо над змінами, натхненні експериментальними відгуками.

Зокрема, ми відмовляємося від ідеї розгалуження бібліотек вводу/виводу (наприклад, react-fetch), і натомість приймаємо модель async/await для кращої сумісності. Це технічно не блокує випуск RSC, оскільки ви також можете використовувати маршрутизатори для отримання даних. Іншою зміною є те, що ми також відходимо від підходу розширення файлів на користь нотування меж.

Ми працюємо разом з Vercel та Shopify над уніфікацією підтримки спільної семантики у пакунках Webpack та Vite. Перед запуском ми хочемо переконатися, що семантика RSC однакова у всій екосистемі React. Це основна перешкода для досягнення стабільності.

Завантаження ресурсів

Наразі такі ресурси, як скрипти, зовнішні стилі, шрифти та зображення, зазвичай попередньо завантажено за допомогою зовнішніх систем. Це може ускладнити координацію між новими середовищами, такими як потокова передача, серверні компоненти тощо. Ми розглядаємо можливість додавання API для попереднього завантаження та завантаження дедукованих зовнішніх ресурсів через React API, які працюють у всіх середовищах React.

Ми також працюємо над тим, щоб вони підтримували Suspense, щоб ви могли використовувати зображення, CSS і шрифти, які блокують відображення до їх завантаження, але не блокують потоковий та одночасний рендеринг. Це допоможе уникнути "попкорну", коли зображення з'являються і макет змінюється.

Оптимізація статичного рендерингу сервера

Статична генерація сайтів (SSG) та інкрементна статична регенерація (ISR) - чудові способи підвищити продуктивність кешованих сторінок, але ми вважаємо, що можемо додати функції для покращення продуктивності динамічного рендерингу на стороні сервера (SSR), особливо коли кешується більша частина, але не весь контент. Ми досліджуємо способи оптимізації серверного рендерингу за допомогою компіляції та статичних передач.

Компілятор, що оптимізує React

На React Conf 2021 ми провели раннє превью React Forget. Це компілятор, який автоматично генерує еквівалент викликів useMemo та useCallback, щоб мінімізувати витрати на повторний рендеринг, зберігаючи при цьому модель програмування React.

Нещодавно ми закінчили переписування компілятора, щоб зробити його більш надійним та функціональним. Ця нова архітектура дозволяє аналізувати та запам'ятовувати складніші патерни, такі як використання локальних мутацій, і відкриває багато нових можливостей оптимізації під час компіляції, не обмежуючись лише хуками запам'ятовування.

Ми також працюємо над ігровим майданчиком для вивчення багатьох аспектів компілятора. Хоча метою ігрового майданчика є спрощення розробки компілятора, ми вважаємо, що він також полегшить його випробування та розвиток інтуїції щодо того, що робить компілятор. Він показує різні деталі роботи компілятора, а також відображає результати роботи компілятора у реальному часі, коли ви вводите текст. Її буде випущено разом з компілятором, коли буде випущено його.

Поза екраном

Сьогодні, якщо ви хочете приховати або показати компонент, у вас є два варіанти. Один з них - додати або повністю видалити його з дерева. Проблема такого підходу полягає у тому, що стан вашого інтерфейсу втрачається кожного разу, коли ви демонтуєте компонент, зокрема стан, збережений у DOM, наприклад, положення прокрутки.

Інший варіант - залишити компонент змонтованим і перемикати вигляд візуально за допомогою CSS. Це збереже стан вашого інтерфейсу користувача, але за це доведеться заплатити продуктивністю, оскільки React повинен продовжувати рендерити прихований компонент і всі його дочірні компоненти щоразу, коли він отримує нові оновлення.

Offscreen вводить третій варіант: приховати інтерфейс візуально, але депріоритизувати його вміст. Ідея схожа за духом на властивість CSS content-visibility: коли вміст приховано, йому не потрібно залишатися синхронізованим з рештою інтерфейсу. React може відкласти роботу рендерингу, поки решта програми не буде працювати, або поки вміст не стане знову видимим.

Offscreen - це низькорівнева можливість, яка розблоковує високорівневі функції. Подібно до інших паралельних можливостей React, таких як startTransition, у більшості випадків ви не будете взаємодіяти з Offscreen API напряму, але будете через фреймворк для реалізації патернів на кшталт:

  • Миттєві переходи. Деякі фреймворки маршрутизації вже виконують попередню вибірку даних для пришвидшення подальшої навігації, наприклад, при наведенні на посилання. За допомогою параметра Offscreen вони також зможуть попередньо відрендерити наступний екран у фоновому режимі.
  • Багаторазовий стан. Аналогічно, під час переходу між маршрутами або вкладками ви можете скористатися параметром Екран для збереження стану попереднього екрана, щоб ви могли повернутися і продовжити з того місця, де зупинилися.
  • Відображення віртуалізованих списків. Під час показу великих списків елементів фреймворки віртуалізованих списків попередньо показуватимуть більше рядків, ніж є видимими. Ви можете скористатися параметром "Поза екраном" для попереднього відображення прихованих рядків з нижчим пріоритетом, ніж видимих елементів списку.
  • Фоновий вміст. Ми також досліджуємо споріднену можливість депріоритизації вмісту у фоновому режимі без його приховування, наприклад, при показі модального накладання.

Трасування переходів

Наразі React має два інструменти профілювання. оригінальний профілювальник показує огляд всіх коммітів у сеансі профілювання. Для кожного комміту він також показує всі компоненти, які було відрендерено, і час, який було витрачено на їх рендеринг. У нас також є бета-версія Timeline Profiler, представленого в React 18, який показує, коли компоненти планують оновлення і коли React працює над цими оновленнями. Обидва ці профілювальники допомагають розробникам виявляти проблеми з продуктивністю в їхньому коді.

Ми зрозуміли, що розробникам не дуже корисно знати про окремі повільні комміти або компоненти поза контекстом. Набагато корисніше знати про те, що насправді спричиняє повільні комміти. І що розробники хочуть мати можливість відстежувати конкретні взаємодії (наприклад, натискання кнопки, початкове завантаження або навігацію по сторінці), щоб спостерігати за регресом продуктивності і розуміти, чому взаємодія була повільною і як це виправити.

Раніше ми намагалися вирішити цю проблему, створивши API відстеження взаємодій, але він мав деякі фундаментальні недоліки, які знижували точність відстеження причин повільної взаємодії, а іноді призводили до того, що взаємодія ніколи не завершувалася. Зрештою ми видалили цей API через ці проблеми.

Ми працюємо над новою версією API трасування взаємодії (попередньо названою Transition Tracing, оскільки вона ініціюється за допомогою startTransition), яка вирішує ці проблеми.

Нові документи React

Минулого року ми анонсували бета-версію нового сайту документації React (пізніше випущену як react.dev) нового сайту документації React. Нові навчальні матеріали в першу чергу навчають хукам і містять нові діаграми, ілюстрації, а також багато інтерактивних прикладів і завдань. Ми зробили перерву в цій роботі, щоб зосередитися на випуску React 18, але тепер, коли React 18 вийшов, ми активно працюємо над завершенням і відправкою нової документації.

Наразі ми пишемо детальний розділ про ефекти, оскільки ми чули, що це одна з найскладніших тем як для нових, так і для досвідчених користувачів React. Синхронізація з ефектами - це перша опублікована сторінка з цієї серії, і протягом наступних тижнів будуть опубліковані інші. Коли ми почали писати детальний розділ про ефекти, ми зрозуміли, що багато поширених шаблонів ефектів можна спростити, додавши до React новий примітив. Ми поділилися деякими початковими думками про це в useEvent RFC. Наразі ми перебуваємо на ранній стадії дослідження, і ми все ще ітераційно розвиваємо цю ідею. Ми вдячні спільноті за коментарі до цього RFC, а також за фідбек та внесок у поточне переписування документації. Ми хотіли б особливо подякувати Херішу Кумару за надання та перевірку багатьох покращень у реалізації нового веб-сайту.

Дякуємо Софі Алперт за перегляд цієї статті!