Почему разработчики JavaScript используют инструменты на Rust

Однажды на мероприятии по тимбилдингу я рассказывал о том, почему разработчики JavaScript переносят свои инструменты на Rust. Ниже  —  версия этого доклада, отредактированная для удобства чтения.

Небольшая справка

Обычно разработчики ПО пишут инструменты для создания приложений на том языке, который использовался в процессе работы над этими приложениями. Например, pip написан на Python, Composer  —  на PHP, Maven  —  на Java и т.д. В большинстве случаев авторы-создатели инструментов сами же их используют, и им проще просто работать на выбранном языке.

JavaScript не является исключением. Мы писали на JavaScript все  —  от Gulp и Bower до babel и Webpack. Все работало хорошо, если не считать нескольких проблем.

Что не так с JavaScript?

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

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

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

Однажды разработчики JavaScript собрались вместе, и после множества горячительных напитков кто-то сказал: “А что если мы не будем писать на JavaScript инструменты, из которых JavaScript состоит?”. Начались ожесточенные споры, но присутствующие все же согласились попробовать этот вариант.

Возможно, это просто мои фантазии, но факт остается фактом: на данный момент мы создаем инструменты для сборки JavaScript на языках, отличных от JavaScript.

Почему именно Rust?

Если говорить вкратце, он обладает высокой скоростью и защищает от переполнения буфера.

Rust  —  это мультипарадигмальный язык программирования общего назначения, разработанный для обеспечения высокой производительности и безопасности. Он представляет собой более современную версию C++. Rust  —  системный язык, обеспечивающий безопасность памяти и “безопасный” параллелизм. Синтаксически он похож на C++ и, что более важно, почти так же быстр, как C++.

Многообещающие заявления

В настоящее время несколько проектов занимаются заменой инструментов JavaScript теми, что написаны на Rust. Например, ParcelJS, Deno, ESBuild и Speedy Web Compiler (SWC). Их авторы утверждают, что могут обеспечить более высокую скорость по сравнению с теми программными средствами, которые они стремятся заменить. Вот одно из сравнений, которое приводит проект esbuild.

Я не буду рассматривать их все, но подробно остановлюсь на SWC в связке с Next.js.

Speedy Web Compiler (SWC)

SWC  —  это расширяемая платформа на основе Rust для нового поколения быстродействующих инструментов разработчика. Другими словами, это фреймворк для создания сборщиков. SWC можно использовать как для компиляции, так и для сборки. Он принимает файлы JavaScript/TypeScript, используя современные возможности JavaScript, и выдает правильный код, который поддерживается всеми основными браузерами.

Новейшие Rust-инструменты Next.js

Next.js представил компилятор Rust в версии 12, основанный на SWC. На сайте Next.js утверждается, что обновление на локальном уровне происходит примерно в 3 раза быстрее, а производственные сборки  —  приблизительно в 5 раз быстрее.

Я решил это проверить и провел собственный тест.

Для этого я создал такой же проект в версиях 11 и 12 и добавил те же 400 сгенерированных компонентов. Я использовал React Benchmark Generator. Единственным различием между проектами была версия Next.js, все остальное было идентичным.

Результаты оказались довольно убедительными.

Next.js 11:

Next.js 12:

Next.js 12 потребовалось 12 секунд, чтобы сделать то, с чем Next.js 11 справился за 1 минуту 40 секунд. Это примерно в 8 раз быстрее.

Неожиданно, что у Next.js 12 работа заняла 12 секунд. Видимо, это было счастливое совпадение.

Стоит ли обращать на это внимание?

Ведь создаваемое нами приложение в конечном итоге остается тем же самым. Вносимые изменения не влияют на опыт конечного пользователя, они только касаются разработчика, так зачем беспокоиться? Зачем исправлять то, что и так прекрасно работает?

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

Представьте, что вы работаете в команде из 20 разработчиков над большим проектом, который развертывается и тестируется на облачном CI. Ежедневно каждый член команды вносит в проект множество исправлений и функций, и это может привести к неприятным последствиям. Если CI допускает неограниченное количество параллельных сборок, но взимает плату за минуту сборки или за секунды процессорного времени, то Next.js в буквальном смысле обойдется в 8 раз дороже, чем Next.js 12.

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

В любом случае медленные сборки обойдутся дороже в плане времени или денег, или и того, и другого.

Заключение

JavaScript  —  потрясающий язык, и без него интернет не был бы таким, каким мы его знаем. Но мы не обязаны использовать его для создания инструментов, потому что для этого есть более подходящие языки, например Rust.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи djangsters: JavaScript Developers Are Using Shiny Rusty Tools. Here’s Why

Предыдущая статьяРепозитории GitHub, которые помогут подготовиться к техническому собеседованию
Следующая статьяКак оптимизировать настройку приложений React Native