Hono vs. H3 vs. HatTip vs. Elysia — современные замены Express для сервера (или без сервера)
- четверг, 21 марта 2024 г. в 00:00:14
H3 отмечает, что Express.js - старый и малоразвивающийся фреймворк, являющийся не оптимальным выбором для новых проектов из-за потенциальных проблем безопасности и утечек памяти, что, к слову, касается и Koa.
В нашей статье мы сделаем акцент на фреймворках, поддерживающих запуск service workers на серверной стороне и современный стандарт Fetch API, поскольку это позволяет им работать в бессерверных и Edge-окружениях, таких как Cloudflare Workers. Это, к слову, и причина, почему Fastify не будет рассматриваться в нашей статье, несмотря на эксперимент fastify-edge, который продолжался два года (кстати, была написана интересная статья о переходе от Node к средам рабочих процессов, с которой я рекомендую ознакомиться).
Worker Runtimes воплощают использование одного языка и возможность обмена кодом между клиентом и сервером, что было первоначальным обещанием NodeJS, однако на практике это не осуществилось, и API Node и браузеров пошли по разным путям. Worker Runtimes вновь объединяют эти возможности, а больше информации можно найти здесь.
Hono, H3, HatTip и Elysia - это современные фреймворки HTTP-серверов, также известные как промежуточные программы веб-сервера нового поколения. Они работают везде, на любом JS-рантайме, включая бессерверные и Edge-среды выполнения, что значит возможность их использования не только на серверах Node.js, и, кроме того, все они поддерживают TypeScript.
Все они поддерживают Web Fetch API (объекты Request/Response), но здесь мы рассмотрим их API, наиболее похожие на Express, чтобы было проще ориентироваться.
Теперь поговорим о каждом их них по отдельности и сравним некоторые различия.
Дата создания репозитория: 12 декабря 2021 года;
Основные участники: 2,5;
Звезды на GitHub сейчас: 12,4 тыс;
Еженедельные загрузки из NPM сейчас: 143 796;
Текущая версия: Hono - 4+;
Слоган: "Быстрый, легкий, соответствует веб-стандартам. Работает на любом JavaScript-рантайме";
Создан прежде всего для Cloudflare Workers, но также имеет адаптер для Node, однако использование Hono на Node может вызывать замедление, но это не отражается в других тестах, например, бенчмарке веб-фреймворков;
Hono сильно ориентирован на соответствие веб-стандартам;
Hono поддерживает RPC;
Hono стремится быть комплексным решением: с встроенными, настраиваемыми и сторонними промежуточными программами и вспомогательными инструментами.
import { Hono } from 'hono';
const app = new Hono();
app.get('/hello', (c) => {
return c.json({ message: 'Hello!' });
});
export default app;
Дата создания репозитория: 15 ноября 2020 года;
Основные участники: 1,5;
Звезды на GitHub сейчас: 2,9 тыс;
Еженедельные загрузки из NPM сейчас: 976 744;
Текущая версия: H3 - 1.11.1;
Слоган: "Веб-фреймворк для современной эры JavaScript: H(TTP) серверный фреймворк, построенный для высокой производительности и переносимости, работающий в любом JavaScript-рантайме;"
"H3 - это компонуемый [и tree-shakeable] фреймворк. Вместо того чтобы предоставлять большое ядро, мы начинаем с легкого экземпляра приложения, и для каждой функции существует встроенная утилита, либо мы можем создать свою собственную. Компонуемые утилиты имеют огромные преимущества по сравнению с традиционными подходами к плагинам/промежуточным программам";
H3 был извлечен из Nitro/Nuxt примерно 2 июля 2023 года (возможно позже, что объяснило бы относительно небольшое количество звезд на GitHub);
Создан в первую очередь для Node, но имеет адаптеры для бессерверных или Edge JS сред выполнения (например, Cloudflare Workers и т. д.). H3 также может работать на Bun с адаптером. Это пока не отражено в bun-http-framework-benchmark, поэтому можете следить за этим вопросом, чтобы узнавать последние обновления;
H3 интегрируется с экосистемой инструментов на JS от UnJS.
NuxtJS (Vue мета-фреймворк) построен на Nitro (расширения для http-сервера), который построен на H3. Nitro добавляет маршрутизацию на основе файлов, обработку ресурсов, абстракцию хранилища и т. д. на H3. (Nitro может выборочно использовать Vite в одном из своих обработчиков маршрутизации, поскольку Vite нужен только для клиентского сервера, а не для статического сервера, согласно Никхилу, автору Vinxi.)
С H3 можно вручную регистрировать экземпляры маршрутизаторов:
import { createApp, createRouter, defineEventHandler, toNodeListener } from "h3";
import { createServer } from "node:http";
export const app = createApp();
const router = createRouter();
app.use(router);
router.get('/', defineEventHandler((event) => {
return { message: 'Hello!' };
}),
);
createServer(toNodeListener(app)).listen(8000);
Дата создания репозитория: 20 февраля 2022 года;
Основные участники: 1,5;
Звезды на GitHub сейчас: 1,1 тыс;
Еженедельные загрузки из NPM сейчас: 1 299;
Текущая версия: HatTip - 0.0.44;
Слоган: "Как Express, но для будущего";
HatTip должен хорошо работать с альтернативами NextJS на основе Vite, такими как Vike (также известный как vite-plugin-ssr) или RakkasJS, так как HatTip создан @cyco130, который также стоит за Rakkas. @cyco130, к слову, тесно сотрудничает с @brillout, который стоит за Vike и вносит свой вклад в HatTip;
HatTip интегрируется с graphql-yoga.
HatTip также предлагает API маршрутизацию в стиле Express, основанную на императивном подходе:
import { createRouter } from "@hattip/router";
import { json } from "@hattip/response";
const router = createRouter();
router.get("/", () => {
return json({ message: "Hello!" });
}
export default router.buildHandler();
Дата создания репозитория: 3 июля 2022 года;
Основные участники: 1;
Звезды на GitHub сейчас: 7,1 тыс;
Еженедельные загрузки из NPM сейчас: 23 837;
Текущая версия: Elysia - 1.0;
Слоган: "Эргономичный фреймворк для людей".
Elysia использует цепочечный / плавный интерфейс для вывода типов, что придает ему уникальный стиль:
import { Elysia } from 'elysia'
new Elysia()
.get('/json', () => ({
message: 'Hello!'
}))
.listen(8080);
Все эти фреймворки очень активно следуют веб-стандартам: Fetch API (существующий стандарт) и WinterCG (стандарт будущего).
Hono и Elysia получили огромное количество звезд на GitHub.
H3 был извлечен из проектов Nitro/Nuxt после 2 июля 2023 года. Возможно, пользователи отдавали предпочтение более высокоуровневым фреймворкам, нежели H3, что объяснило бы, почему H3 имеет меньше звезд на GitHub по сравнению с другими фреймворками, хотя он стал доступен для использования гораздо раньше (с 15 ноября 2020 года).
Для самой актуальной информации смотрите: график истории звезд на GitHub для Hono, H3, HatTip и Elysia.
H3 считается одним из самых скачиваемых по данным Moiva.io, скорее всего, потому что он входит в состав Nitro и NuxtJS (аналог NextJS в мире Vue):
Если не учитывать H3 и более детально рассмотреть ситуацию, то становится видно, что на первом месте находится Hono, за которым следует более молодой Elysia, а затем HatTip (который ещё не достиг версии 1):
А как изменяется их скорость роста? Иными словами, насколько быстро они развиваются?
Hono в настоящее время имеет самый быстрый рост в ежемесячных загрузках NPM - 26,6%. У Elysia - 17,9%, за которым следует HatTip с 17%. Удивительно, что текущий лидер H3 занимает последнее место с ростом на 15,3% в ежемесячных загрузках NPM.
Для самой актуальной информации ознакомьтесь со сравнительной статистикой NPM и GitHub на Moiva.io для Hono vs. H3 vs. HatTip vs. Elysia.
Вероятно, все эти фреймворки будут достаточно быстрыми для большинства сценариев использования. Рассмотрим некоторые бенчмарки.
Бенчмарк веб-фреймворков из репозитория the-benchmarker на GitHub. Результаты представлены в запросах в секунду (RPS) при параллельности 64 (HatTip пока еще не участвует в этом бенчмарке.):
Framework | RPS |
Hono (Bun) | 131 177 |
H3 (Node?): | 75 422 |
Hono (Node?): | 68 263 |
Elysia (Node?): | 64 793 |
Пример бенчмарка HelloWorld с использованием fastify-uws (с использованием инструмента Oha для генерации HTTP-нагрузки для этих фреймворков):
Framework | RPS |
Elysia (Bun) | 145 652 |
Hono (Bun) | 117 491 |
Hono (Node) | 65 704 |
H3 (Node) | 64 489 |
H3 (Bun) | 62 165 |
Результаты бенчмарка HelloWorld от Denosaurs были исключены из этого анализа. Это связано с тем, что в нем не было результатов ни для H3, ни для HatTip, а только для Hono в среде Deno. Сравнение его с Elysia на Bun или с другими бенчмарками, запущенными на другом оборудовании, имеет мало смысла. Однако теперь мы знаем о существовании этого бенчмарка и можем его улучшить, добавив эти фреймворки и/или запустив его самостоятельно.
Далее перейдем к SaltyAom/bun-http-framework-benchmark (от автора ElysiaJS).
"Повторное выполнение того же кода, что и здесь, покажет совершенно разные характеристики производительности по сравнению с более реалистичным профилем нагрузки", - упоминает автор HatTip. Это подтверждается другими пользователями. Возможно, бенчмарк предвзят, когда запускается на Windows?
Результаты, измеренные в запросах в секунду (RPS), на официальном бенчмарке репозитория (запущенном на процессоре Intel-Core-i7-13700K):
Framework | RPS |
Elysia (Bun): | 255 574 |
Hono (Bun): | 203 937 |
H3 (Node): | 96 515 |
Hono (Node): | 29 036 |
Другой человек запустил тот же тест на Linux на медленном компьютере, однако стоит отментить, что он не тестировал другие фреймворки:
Framework | RPS |
Elysia (Bun): | 86 841 |
Hono (Bun): | 73 614 |
Еще один человек, использующий Linux на более медленном процессоре по сравнению с официальным бенчмарком, запустил тест:
Framework | RPS |
Elysia (Bun): | 199 328 |
Hono (Bun): | 196 504 |
H3 (Node): | 95 482 |
Hono (Node): | 20 781 |
По сообщениям, Hono, вероятно, может быть приблизительно на 20 % быстрее в бенчмарке Bun, однако на Node Hono кажется ужасно медленным, но эта проблема не отражается в другом бенчмарке - Бенчмарке веб-фреймворков.
Из проведенных тестов и имеющейся информации следует, что Elysia и Hono приблизительно одинаково быстры, когда запускаются на Bun.
Предположительно, HatTip примерно такой же быстрый, как Hono, при запуске на Bun.
Hono использует более быстрый RegExpRouter вместо маршрутизатора на основе Radix Tree (такого как Radix3, используемого в H3). Но следует следить за этим вопросом, чтобы узнать, реализует ли H3 такой же RegExpRouter или он будет включен в radix3. В общем, вероятно, производительность маршрутизатора не будет иметь большого значения, так как время выполнения пользовательской логики значительно превышает его.
Интересно, что некоторые веб-фреймворки, которые показывают худшие результаты при обработке простого текста (например, helloworld), могут работать лучше других при запросе к базе данных Postgres, вероятно, благодаря специфическим оптимизациям, поэтому рейтинги могут меняться в зависимости от конкретного сценария использования.
Еще один бенчмарк на Node.js утверждает: "Если вы ищете самый производительный фреймворк на Node.js, учтите, что производительность всех фреймворков ухудшается при запросе к базе данных. В этом случае разница в производительности между самым быстрым и самым медленным сокращается, и важны другие факторы".
HatTip уделяет большее внимание стандартам, чем Hono, особенно когда речь идет об универсальных промежуточных программах.
Кроме того, HatTip фокусируется на:
Глубокой интеграции с сервером разработки Vite. (Это обеспечивает более глубокий опыт без настройки для пользователей Vite.)
В то время как "Hono - просто веб-фреймворк. Это не изменится в будущем. По крайней мере, на текущем этапе нет возможности включить CLI." - согласно его автору.
HatTip лучше подходит, то есть глубже интегрирован с Vite, чем Hono, которому требуются плагины.
Инструменты передового уровня, такие как Vinxi (используемые в Solid Start и Tanstack Start), отдают предпочтение H3 вместо Hono:
По мнению Vinxi, гораздо лучше делать ставку на H3, который поддерживается командами Nitro и UnJS и используется Analog и Nuxt. Множество людей работает над тем, чтобы сделать его стабильным, быстрым, без ошибок и работающим везде (и это все еще довольно сложная задача), - сказал Нихил Сараф (автор Vinxi).
Но это также может быть вызвано другими причинами, такими как возможность вручную регистрировать экземпляры маршрутизаторов в H3 (что является основной особенностью Vinxi).
На этом все, спасибо за прочтение! Делитесь своим мнением в комментариях(: