Официальный релиз TypeScript 7 — и он чертовски быстрый!

BBetter Stack
Computing/SoftwareInternet Technology

Transcript

00:00:00Состоялся официальный релиз TypeScript 7, и после более чем года кропотливой разработки
00:00:05перенос компилятора на Go доказал, что всё это можно сделать с помощью ИИ. Так что,
00:00:10уверен, разработчики счастливы. Если вы выполните npm install typescript, то получите версию
00:00:167 с компилятором на Go. Вслед за анонсом от Microsoft,
00:00:20вышедшим пару дней назад, я решил подробно разобраться, как именно они добились столь гигантского
00:00:25прироста производительности. Результаты действительно впечатляют. Новый компилятор собирает кодовую базу VS Code,
00:00:31а это 1,3 миллиона строк кода в почти 8000 файлов, всего за 10 секунд — по сравнению со 125
00:00:39секундами у старого компилятора. И теперь, когда TypeScript гордо занимает первое место среди языков на
00:00:44GitHub, хотите верьте, хотите нет, новый компилятор изменит жизнь многих. У меня аж эмоции наворачиваются,
00:00:49когда я об этом думаю! Но вместо того чтобы разбирать почти идентичные функции версий 6 и 7, я хотел изучить,
00:00:54как именно достигается такая скорость. Давайте взглянем на новый компилятор и узнаем,
00:00:59что делает его таким быстрым. Зачем вообще переписывать? Создатель C# и заслуженный инженер Microsoft
00:01:09Андерс Хейлсберг высказался прямо: JavaScript оптимизирован для UI и браузеров,
00:01:16но не для ресурсоемких задач и компиляторов. И понятно почему: он однопоточный,
00:01:22и обработка чего-то вроде абстрактного синтаксического дерева или проверки типов упирается в потолок
00:01:27при работе лишь на одном ядре. Технически можно распараллелить работу через воркеры, но тогда
00:01:32придется сериализовать и десериализовать данные, а это медленно и требовательно к памяти, да и
00:01:38управлять всем этим очень сложно. Поэтому они остановились на Go, который дает колоссальный
00:01:43прирост скорости благодаря языку, идеально подходящему для этих целей. Go — компилируемый язык,
00:01:48что позволяет выполнять скомпилированный код прямо на процессоре без интерпретации, и у Go
00:01:54отличная модель многопоточности, то есть можно легко запускать несколько потоков одновременно
00:02:00с общей памятью. Это позволяет задействовать все ядра вашего процессора, а не только
00:02:06одно. Прирост делится примерно пополам: до половины ускорения дает нативный код,
00:02:12а остальное — параллельное выполнение с общей памятью. Go идеально подходить для этого,
00:02:17дело не только в том, что он быстрее, у него банально больше ресурсов для решения задачи, и результаты
00:02:23говорят сами за себя. Посмотрим на цифры: VS Code с 1,3 млн строк кода собирался за 125,7 секунды на старом
00:02:32компиляторе и за 10,6 секунды на новом — это ускорение в 11,9 раза. В Bluesky время упало с 24,3 до 2,8 — в 8,7 раза,
00:02:42а в Playwright — с 12,8 до 1,5 секунды, тоже в 8,7 раза. Забавно, что подписка на Better Stack занимает всего секунду.
00:02:49И этот разрыв будет только расти, ведь сами ядра перестали расти в скорости с прежним темпом,
00:02:54зато их становится больше. Я, например, работаю на M3 Max
00:03:00с 14 ядрами — это просто безумие. Помню, как в колледже собирал ПК с
00:03:06четырехъядерным Intel i7 и думал, что это невероятный монстр. Компилятор JavaScript использовал бы
00:03:11лишь одно из тех ядер, но с Go раскрываются они все. Естественно, чем больше ядер, тем выше
00:03:17производительность. Если компилировать крупный проект на этом ПК в версии 6, это займет 45
00:03:24секунд, а в версии 7 время сокращается всего до трех секунд. Процесс компиляции состоит из
00:03:29нескольких фаз, и проверка типов — лишь одна из них. Для этого Go
00:03:34запускает четыре средства проверки типов, каждое из которых обрабатывает по четверти кодовой базы, но это можно
00:03:39ускорить еще сильнее. Во время компиляции можно задать значение checkers=12 для максимальной скорости.
00:03:45Я скачал репозиторий VS Code, чтобы сравнить разницу между TypeScript 7 и 6.
00:03:51По умолчанию tsc на моей системе указывает на TypeScript 7, так что просто запустим диагностику.
00:03:57Как видите, это заняло 5,4 секунды, причем большая часть времени ушла именно на
00:04:02проверку — 4,7 секунды. Но мы можем ускорить и это, если добавим флаг
00:04:08checkers=12. Общее время снизилось с 5,4 до 3,5 секунды, и вся разница
00:04:15пришлась на время проверки: с 4,7 она упала до 2,9 секунды. Теперь выполним ту же
00:04:20команду, но используя TypeScript 6. Это займет некоторое
00:04:23время, так что перемотаем. И вот мы видим, что TypeScript 6 справился за
00:04:2845,3 секунды по сравнению с 3,5 секунды, которые мы получаем при задействовании всех ядер.
00:04:36Это прирост в 15 раз на чипе M3 Max! Вот откуда у меня выходят эти 3,5 секунды.
00:04:43Конечно, это отбирает ресурсы у других процессов, но если вы больше ничего не делаете,
00:04:47то почему бы не использовать все ресурсы машины? Посмотрим на реальный код
00:04:52нового компилятора, чтобы понять, как Go добивается такой скорости. Вот функция bindSourceFiles,
00:04:57функция bindSourceFiles, задача которой — собрать каждое объявление в файле и определить, к какому области видимости оно относится
00:05:03Мы обрабатываем тысячи файлов: проходим по каждому, ставим в очередь функцию связывания
00:05:09и ждем завершения. Прелесть в том, что нам не нужно думать,
00:05:14как распределить работу по ядрам: среда выполнения Go берет это на себя. Мы не создаем потоки и не
00:05:20управляем связью между ядрами — мы просто передаем задачу, а Go сам решает, как её выполнить.
00:05:26На JavaScript можно написать аналогичный код, но для задач с высокой нагрузкой на ЦП это бессмысленно —
00:05:32всё равно все будет выполняться в одном потоке последовательно, даже если промисы создают иллюзию параллелизма.
00:05:38Технически воркеры позволяют обойти это, но между ними нельзя передавать объекты — только байты
00:05:43через SharedArrayBuffer. Передача синтаксического дерева в воркер требует его полной сериализации,
00:05:48копирования и повторной сборки на той стороне. Для большого файла это может стоить дороже самой работы.
00:05:53Именно такие вещи делают Go значительно лучше для вычислительных задач. У него есть
00:05:58среда исполнения, взявшая на себя параллелизм, и общая память, позволяющая передавать объекты
00:06:03без их копирования. Помимо времени компиляции, сильнее всего вы заметите
00:06:07скорость работы языкового сервера. Каждый, кто работал с крупной кодовой базой на TypeScript, знает,
00:06:13как мучительно ждать проверки типов — и, боже, Mac на Intel это прочувствовали в полной мере! Помню,
00:06:20как пару лет назад открываешь репозиторий и буквально ждешь
00:06:24до двух минут просто чтобы появились красные подчеркивания. И каждое правка
00:06:29превращалась в пытку. Опыт разработки ужасный, и никто не хочет
00:06:34поддерживать этот код. Новый же языковой сервер дает мгновенный отклик в IDE:
00:06:40можно открыть файл, внести изменение и увидеть ошибки буквально за миллисекунды даже в
00:06:46гигантских кодовых базах. Помимо производительности, новый языковой сервер стал стабильнее,
00:06:51поэтому перезапускать IDE из-за сбоя проверки типов придется намного реже. В TypeScript 7
00:06:57число сбоев команд сервера снизилось более чем на 80%, а падений сервера — более чем на 60%.
00:07:04Это значит, что меньше ноутбуков полетит в стену, что весьма полезно для экологии!
00:07:08Кто знал, что Microsoft заботится о планете? Стоит упомянуть, что это именно перенос,
00:07:13а не переписывание с нуля. Команда TypeScript постаралась обеспечить практически полную
00:07:19совместимость нового компилятора со старым. Вы вряд ли заметите разницу, за исключением скорости.
00:07:24И хотя вы уже можете запустить TypeScript 7 в своих проектах, придется подождать,
00:07:29пока обновятся ваши любимые пакеты. Программный API пока отсутствует, поэтому всем зависимым
00:07:35пакетам придется ждать релиза 7.1. Так что такие библиотеки, как typescript-eslint, ts-jest или ts-node, пока
00:07:42будут отставать. Полноценный релиз TypeScript 7 уже доступен для скачивания, но вам
00:07:47нужно вручную установить расширение TypeScript 7 для VS Code. Стандартный пакет позже
00:07:53обновится, но пока просто установите расширение TypeScript 7 из магазина, и
00:07:58все заработает как надо. Если хотите узнать больше о возможностях TypeScript 7, у нас
00:08:03есть отдельное видео на эту тему, которое можно посмотреть здесь. А если вам нравятся такие разборы, подписывайтесь
00:08:08на Better Stack. Надеюсь, вы узнали что-то новое и теперь сможете оценить
00:08:12высокую скорость разработки с TypeScript 7. Я точно буду рад
00:08:16его использовать! Спасибо за просмотр, и, конечно же, до встречи в следующем видео.

Key Takeaway

Перевод компилятора и языкового сервера TypeScript 7 на язык Go обеспечил ускорение сборки крупных проектов до 15 раз за счет эффективного использования многопоточности и общей памяти на всех ядрах процессора.

Highlights

  • Перенос компилятора TypeScript 7 на язык Go ускорил сборку кодовой базы VS Code (1,3 млн строк кода) с 125,7 до 10,6 секунды — в 11,9 раза.

  • На процессоре Apple M3 Max с 14 ядрами использование флага checkers=12 сокращает время проверки типов и полной компиляции VS Code до 3,5 секунды.

  • Прирост производительности достигается за счет компиляции Go в нативный машинный код (до 50% ускорения) и работы с общей памятью на всех ядрах процессора без сериализации данных.

  • В TypeScript 7 число сбоев команд языкового сервера снизилось более чем на 80%, а количество полных падений сервера — более чем на 60%.

  • Программный API временно отсутствует и появится в версии 7.1, поэтому инструменты вроде typescript-eslint, ts-jest и ts-node пока не поддерживают новую версию.

Timeline

Официальный релиз TypeScript 7 и результаты бенчмарков

  • Официальный релиз TypeScript 7 поставляется с новым компилятором, переписанным на язык Go.
  • Сборка кодовой базы VS Code из 1,3 млн строк кода ускорилась со 125 до 10 секунд.
  • Проекты Bluesky и Playwright демонстрируют ускорение компиляции в 8,7 раза.

При выполнении команды npm install typescript по умолчанию устанавливается 7-я версия. Новый компилятор сохраняет функциональную совместимость с TypeScript 6, но кардинально меняет скорость работы на крупных кодовых базах. Для VS Code время сборки сократилось со 125,7 до 10,6 секунды, для Bluesky — с 24,3 до 2,8 секунды, а для Playwright — с 12,8 до 1,5 секунды.

Архитектурные ограничения JavaScript и преимущества Go

  • Однопоточная природа JavaScript создавала барьер производительности при обходе AST и проверке типов.
  • Использование воркеров в JavaScript требует дорогостоящей сериализации данных через SharedArrayBuffer.
  • Компиляция Go в нативный код и параллелизм с общей памятью делят прирост скорости примерно пополам.

JavaScript оптимизирован для браузеров и UI, но упирается в вычислительный потолок одного ядра при обработке синтаксических деревьев. Передача объектов между воркерами в JS требует полных копирований и сериализации, что часто превышает время самих вычислений. Среда выполнения Go позволяет исполнять нативный код напрямую на процессоре и параллельно обрабатывать данные в общей памяти на всех доступных ядрах.

Практическое тестирование компилятора на многоядерной системе

  • Параметр checkers=12 позволяет масштабировать параллельную проверку типов на 12 потоков.
  • На процессоре M3 Max время проверки типов VS Code снижается с 4,7 до 2,9 секунды.
  • Итоговое время работы TypeScript 7 против 45,3 секунды у TypeScript 6 составило 3,5 секунды.

Компиляция включает несколько стадий, где проверка типов занимает наибольшую долю времени. По умолчанию Go распределяет проверку на 4 потока, но флаг checkers=12 позволяет задействовать больше ресурсов. На 14-ядерном чипе M3 Max TypeScript 6 выполняет диагностику VS Code за 45,3 секунды, тогда как TypeScript 7 с задействованием всех ядер справляется за 3,5 секунды, показывая 15-кратный прирост.

Механизмы параллелизма Go и работа языкового сервера

  • Функция bindSourceFiles передает задачи среде выполнения Go без ручного управления потоками.
  • Отклики языкового сервера в IDE снизились до нескольких миллисекунд даже в гигантских репозиториях.
  • Количество сбоев команд сервера сократилось на 80%, а падений — на 60%.

В коде компилятора функция bindSourceFiles связывает объявления во всех файлах, распределяя задачи в очередь. Среда Go берет на себя планирование и балансировку по ядрам без создания явных потоков. В IDE это дает мгновенную подсветку ошибок и существенно повышает стабильность: падения языкового сервера сократились более чем вдвое.

Совместимость, экосистема и процесс установки

  • TypeScript 7 является переносом кодовой базы, сохраняющим почти 100% совместимости.
  • Программный API появится только в релизе 7.1, что задерживает обновление сторонних утилит.
  • Для работы в VS Code требуется ручная установка расширения TypeScript 7 из магазина.

Новый компилятор полностью воспроизводит поведение старого, поэтому код проектов не требует изменений. Однако из-за отсутствия программного API внешние инструменты вроде typescript-eslint, ts-jest и ts-node временно не могут использовать TypeScript 7. Для полноценной интеграции с VS Code сейчас необходимо отдельно установить соответствующее расширение.

Community Posts

View all posts