Введение

Несколько хороших лет назад PHP был популярен потому, что позволял разработчикам встраивать серверную логику непосредственно в HTML-подобный шаблон, позволяя им извлекать данные и отображать их на уровне представления. Это сделало невероятно простым создание динамических веб-сайтов, управляемых данными, без необходимости использования отдельных клиентских скриптов. Аналогичным образом, в экосистеме .NET Razor Pages предлагает модель программирования на основе страниц, в которой вы можете совместить представление и логику на стороне сервера, что упрощает получение и отображение данных.

Перенесемся в сегодняшний день: у нас есть серверные компоненты React (RSC), современное решение, повторяющее простоту PHP и Razor Pages, но с дополнительными преимуществами компонентной архитектуры React. Как и в PHP и Razor Pages, серверные компоненты React позволяют вам напрямую получать доступ к серверным ресурсам, но они привносят в себя мощь экосистемы React, включая встроенную поддержку async/await и плавную интеграцию с клиентскими компонентами.

В чем разница между обычными компонентами React и серверными компонентами React?

Представьте себе кухню ресторана в качестве вашего веб-приложения. На этой кухне есть два типа поваров: «Обычный повар» и «Шеф-сервер».

Обычный шеф-повар (обычные компоненты React)

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

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

Server Chef (компоненты сервера React)

С другой стороны, Server Chef похож на серверный компонент React. Этот шеф-повар готовит блюда в отдельной комнате (на сервере) еще до того, как они попадают в обеденную зону (браузер). Серверный повар сосредотачивается на тяжелой работе, такой как маринование мяса или приготовление сложных соусов (получение данных из внешнего источника), передавая их, чтобы обычный повар мог быстро собрать и подать блюдо (при условии, что вам нужна интерактивность).

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

Вкратце

  • Обычные компоненты React похожи на обычных поваров, которые готовят и подают блюда прямо на главной кухне (в браузере), предлагая интерактивность, но иногда за счет производительности.
  • Серверные компоненты React подобны серверным поварам, которые заранее готовят блюда в отдельной комнате (на сервере), повышая эффективность и производительность, но с меньшей интерактивностью. Недостатком является то, что они не могут взаимодействовать с клиентами.

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

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

Магия компонентов «нулевого размера»

Одной из наиболее привлекательных особенностей серверных компонентов React является их способность уменьшать размер пакета JavaScript на стороне клиента. В мире, где на счету каждый килобайт, это значительное преимущество. Серверные компоненты работают исключительно на сервере, а это означает, что они не добавляют никакого веса клиентскому пакету. Это особенно полезно для сокращения времени начальной загрузки страницы и оптимизации общей производительности вашего веб-сайта.

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

Однако важно отметить, что эффект нулевого размера пакета достижим только в том случае, если ваше приложение состоит исключительно из серверных компонентов. В большинстве реальных приложений вы, скорее всего, будете использовать смесь серверных и клиентских компонентов. Клиентские компоненты необходимы для интерактивных элементов, таких как кнопки, и всего остального, что требует логики на стороне клиента, например интерактивности.

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

Компромисс: производительность против интерактивности

Ключевой вывод здесь заключается в том, что серверные компоненты React предлагают компромисс. Они могут значительно уменьшить размер вашего пакета на стороне сервера, но могут немного увеличить размер пакета на стороне клиента, если у вас также есть интерактивные клиентские компоненты. Хитрость заключается в том, чтобы найти правильный баланс между серверными и клиентскими компонентами для оптимизации производительности и интерактивности вашего приложения.

Хотя серверные компоненты React обещают мир компонентов с нулевым размером пакета, реальность немного более тонкая. Клиентский пакет для новой парадигмы React будет немного больше, чем раньше.

Полный доступ к серверным ресурсам

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

Традиционно компоненты внешнего интерфейса извлекали данные из серверной части через API-интерфейсы RESTful или запросы GraphQL. Эта настройка требовала от разработчиков создания конечных точек API, сериализации данных, а затем их получения на стороне клиента. Серверные компоненты React упрощают это, позволяя вам напрямую получать доступ к таким базам данных, как PostgreSQL, MySQL или любой другой базе данных, которую вы используете, прямо внутри самого компонента.

Поддержка Async/Await: упрощение получения данных

Встроенная поддержка async/await в серверных компонентах меняет правила игры. Эта функция позволяет асинхронно получать данные во время процесса рендеринга компонента. Это, в свою очередь, ускорит загрузку вашего приложения и уменьшит его общий вес.

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

Бесшовная интеграция с клиентскими компонентами

Хотя серверные компоненты React предлагают невероятные преимущества с точки зрения извлечения данных и оптимизации производительности, их истинная мощь раскрывается при использовании в сочетании с традиционными клиентскими компонентами React.

Передача данных в качестве реквизита: мост между сервером и клиентом

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

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

Пример: передача пользовательских данных в клиентский компонент

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

async function fetchUserData(userId) { 
  const result = await db.query('SELECT * FROM users WHERE id = $1', [userId]); 
  return result.rows[0]; 
} 
 
async function UserProfile({ userId }) { 
  const userData = await fetchUserData(userId); 
 
  return ( 
    <UserProfileClient userData={userData} /> 
  ); 
} 
 
// Client Component must be in a separate file  

'use client' 
function UserProfileClient({ userData }) { 
  return ( 
    <div> 
      <h1>{userData.name}</h1> 
      <button onClick={() => {/* Some logic */}> 
        Edit Profile 
      </button> 
      {/* More interactive elements */} 
    </div> 
  ); 
}

В этом примере компонент UserProfileServer извлекает пользовательские данные и передает их в качестве свойства компоненту UserProfileClient. Клиентский компонент затем может использовать эти данные для любых интерактивных функций, таких как кнопка «Редактировать профиль».

Лучшее из обоих миров: производительность и интерактивность

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

Как приостановка улучшает серверные компоненты React: удобство взаимодействия с пользователем

Что происходит, когда вам нужно получить данные асинхронно? Именно здесь в игру вступает приостановка React.

Задача: асинхронные серверные компоненты

Рассмотрим простой серверный компонент, который асинхронно извлекает данные:

export default async function Post() { 
  const data = await fetch(...); 
  return <div>{data}</div>; 
}

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

Решение: введение режима ожидания для серверных компонентов

Функция Suspense в React предлагает идеальное решение этой проблемы. Обернув асинхронный серверный компонент в тег ‹Suspense /›, вы можете предоставить резервный вариант, который React будет отображать и отправлять клиенту, пока компонент извлекает данные.

async function Post() { 
  const data = await fetch(...); 
  return <div>{data}</div>; 
} 
 
export default function Wrapper() { 
  return ( 
    <Suspense fallback={<div>Loading ...</div>}> 
      <Post /> 
    </Suspense> 
  ); 
}

В этом примере оболочка ‹Suspense />< отображает сообщение «Загрузка…» в качестве резервного варианта. После получения данных React заменяет этот резерв фактическим содержимым из компонента Post.

Стриминг: будущее веб-производительности

Этот процесс отправки клиенту нескольких фрагментов HTML с течением времени известен как потоковая передача. Это гарантирует, что пользователь увидит что-то значимое во время ожидания загрузки данных, что повышает общее удобство работы пользователя. Более подробно этот процесс мы описали в нашем посте о Next.js 13.

Как избежать каскадов клиент-сервер

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

Что такое клиент-серверные водопады?

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

Проблема: почему они плохи для производительности?

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

Решение: прямой доступ к серверным данным

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

Как серверные компоненты решают эту проблему

Серверные компоненты React предлагают мощное решение этой проблемы. Предоставляя прямой доступ к серверным ресурсам, таким как базы данных, серверные компоненты устраняют необходимость многократного обращения для получения данных. Они извлекают и визуализируют необходимые данные на самом сервере перед отправкой их клиенту, эффективно сокращая количество «остановок» или «автоматов», которые замедляют процесс рендеринга.

Интеграция серверных компонентов React в существующее приложение

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

Файл сервера: новый центр управления вашим приложением

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

Практический пример можно найти в Демо-версии компонентов сервера React на GitHub. В этой демонстрации используется сервер Express для обслуживания конечных точек API и преобразования серверных компонентов в специальный формат, читаемый клиентом.

Действия, которые необходимо выполнить для добавления серверных компонентов в существующее приложение

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

  1. Установите необходимые зависимости. Убедитесь, что у вас установлен Node 18 LTS. Запустите npm install —legacy-peer-deps, чтобы установить необходимые пакеты.
  2. Создайте файл сервера. Создайте новый файл, обычно с именем server.js, в корне вашего проекта. Этот файл будет содержать логику вашего сервера. Помните, что вы должны объявить свои маршруты здесь, в файле сервера.
  3. Запуск сервера. Запустите сервер с помощью npm start. Если все настроено правильно, ваше приложение теперь должно обслуживаться по адресу http://localhost:4000 или указанному вами порту.
  4. Интеграция серверных компонентов. Теперь вы можете начать заменять или дополнять части своего приложения серверными компонентами. Эти компоненты будут визуализированы на сервере и отправлены клиенту в виде HTML.
  5. Тестирование. Перед развертыванием тщательно протестируйте новую настройку, чтобы убедиться, что серверные компоненты работают должным образом вместе с вашими клиентскими компонентами.

Заключение: путь вперед с серверными компонентами React

Как мы уже выяснили, серверные компоненты React предлагают преобразующий подход к созданию веб-приложений, обеспечивая сочетание эффективности на стороне сервера и интерактивности на стороне клиента. Важно отметить, что вам не нужно выбирать конкретную платформу, например Next.js, чтобы начать использовать серверные компоненты; их можно относительно легко интегрировать в существующие приложения React.

Краткое описание основных преимуществ

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

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

Бесшовная интеграция: серверные компоненты могут легко передавать данные клиентским компонентам, что обеспечивает гармоничное сочетание серверной и клиентской логики.

Уменьшение размера пакета. Хотя это преимущество зависит от наличия клиентских компонентов, серверные компоненты могут значительно уменьшить размер пакета вашего приложения.

Улучшенное взаимодействие с пользователем. Такие функции, как приостановка и прямой доступ к серверной части, делают работу пользователя более удобной и увлекательной.

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

И последнее, но не менее важное: если вы рассматриваете возможность внедрения серверных компонентов React в свой проект и вам может понадобиться помощь экспертов, не стесняйтесь обращаться к нам. Мы здесь, чтобы помочь вам разобраться в замечательных возможностях, которые предоставляют серверные компоненты React.

Так зачем ждать? Сделайте шаг вперед и начните оптимизировать свои веб-приложения с помощью серверных компонентов React уже сегодня.

Оригинально опубликовано на https://www.itmagination.com.

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