SvelteKit 3 бросает вызов Next.js радикальным подходом к RPC

SvelteKit 3 бросает вызов Next.js радикальным подходом к RPC

The Register сообщает, что релиз-кандидат SvelteKit 3.0 продвигает удалённые функции (remote functions), экспериментальную возможность, доступную с версии SvelteKit 2.27, к статусу, равному традиционным load-функциям фреймворка; официально это равенство должно закрепиться в стабильной версии 3.0, если к моменту её выхода будут устранены оставшиеся баги (точная дата финального релиза в источнике не названа). Команда проекта в анонсе релиз-кандидата не скромничает: «На их фоне всё остальное, включая load-функции и actions самого SvelteKit, выглядит немного неуклюже». По словам сторонников этого подхода, он достаточно радикален, чтобы изменить весь ландшафт RPC-вызовов в вебе.

Удалённые функции решают давнюю проблему веб-разработки: как обновить данные в одном компоненте страницы, не перезагружая её целиком. Раньше разработчикам приходилось городить обходные решения, которые обычно получались громоздкими и на практике теряли типобезопасность. «Это наш взгляд на RPC», говорит Саймон Хольтхаузен, разработчик ядра Svelte в Vercel, в подкасте Svelte Society. Механика простая: функция пишется на JavaScript или TypeScript и заранее компилируется в лёгкую клиентскую RPC-обёртку; на сервере SvelteKit делает стандартную для RPC работу, проверяет входящий запрос, обращается к базе данных или другому источнику данных и возвращает сериализованный результат обратно компоненту. Никакой отдельной маршрутизации или дополнительного шаблонного кода не требуется: разработчик просто импортирует серверную функцию запроса или мутации прямо в обычный Svelte-компонент и вызывает её как рядовую функцию.

Разработчик Скотт Толински в одном из выпусков подкаста Syntax (эпизод озаглавлен «SvelteKit решил проблему загрузки данных») привёл характерный пример: сайт, где статичен весь контент, кроме подвала страницы с постоянно обновляемыми данными. Раньше для этого пришлось бы либо помечать динамической всю страницу целиком (дороже по вычислениям, медленнее грузится), либо писать отдельный загрузчик маршрута сверху вниз (больше кода и мыслительной работы). С удалёнными функциями компонент подвала сам запрашивает и обновляет свои серверные данные напрямую. «Вам не нужно думать о том, где именно выполняется этот код», говорит Толински. По его словам, «изнутри обычного Svelte-компонента можно просто взять и импортировать нужный запрос или мутацию как функцию, а затем вызвать эту функцию в своём коде».

SvelteKit уже некоторое время наступает Next.js на пятки: по данным одного из недавних бенчмарков (издание не называет ни его авторов, ни источник), серверный рендеринг (SSR) SvelteKit для аналогичной страницы товара выдаёт HTML-ответ втрое меньшего размера, чем у Next.js, заметный выигрыш для проектов, где важна производительность. У Next.js есть похожий по духу инструмент, Server Functions (бывшие Server Actions), который тоже позволяет клиентским компонентам напрямую вызывать серверные мутации. Но, как отмечает издание, Server Functions в Next.js изначально проектировались прежде всего для записи данных, а не для их получения или запроса, в этом и заключается отличие от удалённых функций SvelteKit.

У этой конкуренции есть примечательный контекст владения. Svelte создал в 2016 году Рич Харрис, тогда британский журналист, работавший графическим редактором в The New York Times: ему нужен был более простой способ собирать графические веб-компоненты для онлайн-материалов издания, так появился Svelte 1.0, инструмент для сборки компонентов без груза шаблонного кода React. В отличие от React, Svelte компилирует код заранее и отгружает пользователю минимум сопутствующего кода фреймворка; то, что компоненты Svelte строятся из стандартных HTML-элементов, тоже снижает порог входа для разработчика. Позже вокруг Svelte вырос SvelteKit, уже полноценный бэкенд-фреймворк с маршрутизацией и рендерингом, выдержанный в том же духе простоты. Сегодня Харрис работает в Vercel, компании, которая одновременно спонсирует Svelte и владеет Next.js. Тем не менее, по словам представителя Vercel, компания поддерживает оба подхода, поскольку каждый из них отражает «более широкую конвергенцию к типизированным серверным функциям, вызываемым с клиента».

Толински резюмирует свою оценку характерной оговоркой: «Я не утверждаю, что никакая другая RPC-система не делает это так же хорошо, но чтобы я стал ею пользоваться, она должна быть не хуже этой». По его словам, главное достоинство удалённых функций, в том, насколько органично они вписываются в общую архитектуру Svelte.

Ключевые факты

  • SvelteKit 3.0 (сейчас релиз-кандидат) продвигает удалённые функции, экспериментальные с версии 2.27, к статусу, равному традиционным load-функциям; официальное равенство закрепится в стабильной версии 3.0 после устранения оставшихся багов (точная дата не названа).
  • Удалённые функции позволяют Svelte-компоненту напрямую запрашивать или изменять серверные данные без перезагрузки страницы: серверная функция на JavaScript или TypeScript импортируется в компонент и вызывается как обычная функция, без ручной маршрутизации и дополнительного кода.
  • По данным одного из недавних (неназванных) бенчмарков, серверный рендеринг SvelteKit выдаёт HTML-ответ втрое меньшего размера, чем у Next.js, для аналогичной страницы товара.
  • У Next.js есть похожая возможность, Server Functions (бывшие Server Actions), но, как отмечает издание, она рассчитана прежде всего на запись данных, а не на их запрос или получение.
  • Vercel одновременно владеет Next.js и спонсирует Svelte, а создатель Svelte Рич Харрис теперь работает в Vercel; представитель компании называет обе разработки частью общей конвергенции к типизированным серверным функциям, вызываемым с клиента.

Почему это важно

SvelteKit давно теснит Next.js, а удалённые функции, не косметическое дополнение, а попытка переосмыслить саму архитектуру RPC-вызовов в вебе: команда проекта прямо заявляет, что на их фоне даже собственные load-функции и actions SvelteKit выглядят неуклюже. Раньше точечное обновление данных в одном компоненте без перезагрузки всей страницы решалось обходными путями, которые обычно теряли типобезопасность; удалённые функции складывают RPC-вызов, типобезопасность и точечное обновление компонента в один простой механизм. Сторонники подхода говорят, что он способен изменить весь ландшафт RPC-вызовов в вебе, это заявка не на рядовое обновление минорной версии, а на новый стандарт того, как фронтенд разговаривает с сервером.

Кому это важно

В первую очередь, фронтенд- и фулстек-разработчикам, которые уже работают со Svelte и SvelteKit или выбирают между этим стеком и связкой React/Next.js для нового проекта. Важно и командам, для которых критичен размер SSR-ответа и скорость отдачи страниц. Отдельно это касается всех, кто следит за экосистемой Vercel: компания теперь одновременно спонсирует Svelte и владеет Next.js, и конкуренция этих двух подходов внутри одной корпоративной орбиты, сюжет сам по себе.

Как это применить

Удалённые функции доступны как экспериментальная возможность уже с версии SvelteKit 2.27; официально они встанут наравне с load-функциями в стабильной версии 3.0, которая выйдет из статуса релиз-кандидата после устранения оставшихся багов (точная дата в источнике не названа). На практике серверная функция запроса или мутации пишется на JavaScript или TypeScript, компилируется в лёгкую клиентскую RPC-обёртку и импортируется прямо в обычный Svelte-компонент, вызывается она как рядовая функция, без создания отдельного маршрута или дополнительного шаблонного кода. Иллюстрация из подкаста Syntax: на сайте, где весь контент статичен, кроме подвала с постоянно обновляемыми данными, компонент подвала сам запрашивает и обновляет свои данные напрямую, вместо того чтобы помечать динамической всю страницу или писать отдельный загрузчик маршрута.

Можно ли доверять

Материал построен на именных источниках: разработчик ядра Svelte в Vercel Саймон Хольтхаузен и представитель Vercel говорят на запись, плюс независимый комментарий разработчика Скотта Толински из подкаста Syntax, для отраслевой заметки The Register это нормальный уровень проверки. Но у материала есть два слабых места. Во-первых, единственная цифра, подтверждающая заявку на превосходство над Next.js (SSR-ответ втрое меньше), взята из «недавнего бенчмарка», который издание не называет и на который не даёт ссылку, проверить эту цифру независимо нельзя. Во-вторых, Vercel одновременно владеет Next.js и спонсирует Svelte, а создатель Svelte работает в Vercel, поэтому оценка «оба подхода одинаково хороши» исходит от стороны, объективно заинтересованной в обоих продуктах сразу, а не от независимого арбитра; отдельного комментария от команды, отвечающей именно за Next.js, в материале нет.

Риски и подводные камни

Формально удалённые функции остаются экспериментальными до выхода стабильной версии 3.0 из статуса релиз-кандидата, а сам переход зависит от устранения «оставшихся багов», каких именно и когда именно, в материале не сказано, так что команды, которые начнут строить на этой возможности сейчас, ориентируются на движущуюся цель. Ключевой аргумент в пользу SvelteKit, тройное преимущество по размеру SSR-ответа, держится на неподтверждённом источнике и не может быть перепроверен читателем. Наконец, поскольку Vercel контролирует ресурсы обоих фреймворков сразу, сравнение SvelteKit и Next.js в этом материале ближе к внутреннему позиционированию продуктов одной компании, чем к независимому тестированию, это стоит учитывать, оценивая заявленное превосходство SvelteKit.

«Я не утверждаю, что никакая другая RPC-система не делает это так же хорошо, но чтобы я стал ею пользоваться, она должна быть не хуже этой»

— Скотт Толински, разработчик, подкаст Syntax