Чем отличаются виды компиляции в Dart

В языке программирования Dart существуют разные виды компиляции, каждый из которых используется в зависимости от контекста: отладки, финальной сборки, целевой платформы и особенностей среды выполнения. Dart — это язык, ориентированный как на клиентскую разработку (в первую очередь под Flutter), так и на серверную, и он поддерживает несколько стратегий компиляции для достижения наилучшей производительности или удобства разработки.

🔧 Основные виды компиляции в Dart

1. JIT-компиляция (Just-In-Time)

JIT-компиляция означает, что код компилируется во время выполнения (runtime).

Как работает:

  • Код на Dart сначала интерпретируется и компилируется динамически, по мере запуска приложения.

  • JIT используется в режиме разработки (debug), чтобы ускорить процесс изменения кода и его немедленного тестирования.

Преимущества:

  • Быстрый цикл разработки: можно внести изменения и сразу их увидеть (hot reload).

  • Не требует предварительной сборки всего проекта.

Недостатки:

  • Медленнее работает по сравнению с AOT при запуске.

  • Более тяжёлое использование памяти.

  • Не оптимизирован для production.

Используется в:

  • Flutter при запуске приложения в debug-режиме (flutter run).

  • В браузере — при использовании dart run для CLI-приложений.

2. AOT-компиляция (Ahead-Of-Time)

AOT-компиляция преобразует Dart-код в машинный код до запуска программы.

Как работает:

  • Компиляция происходит заранее, создавая нативный исполняемый файл.

  • Используется в production-сборках Flutter-приложений (и мобильных, и настольных).

Преимущества:

  • Высокая производительность и быстрое время запуска.

  • Оптимизация на уровне машинного кода.

  • Меньший размер рантайма (нет необходимости в JIT-компиляторе в дистрибутиве).

Недостатки:

  • Долгое время сборки.

  • Нет поддержки hot reload — только hot restart.

  • Более трудная отладка, особенно при ошибках времени выполнения.

Используется в:

  • flutter build apk / flutter build ios

  • Компиляции серверных Dart-приложений через dart compile exe

3. Компиляция в JavaScript (Dart2JS)

Dart может компилироваться в JavaScript для выполнения в браузере.

Как работает:

  • Dart-код преобразуется в JavaScript-код, который может исполняться в любом современном браузере.

  • Используется в веб-приложениях, разработанных на Dart (включая Flutter Web).

Инструмент:

  • dart2js — основной компилятор из Dart в JS.

  • Пример: dart compile js main.dart -o main.js

Преимущества:

  • Позволяет разрабатывать клиентские приложения на Dart и запускать их в браузере.

  • Глубокая оптимизация JS-кода (минификация, tree shaking и т.д.).

  • Хорошая производительность при должной настройке.

Недостатки:

  • Не полная поддержка всех Dart-фич (например, некоторых типов из dart:io).

  • Компиляция может быть медленной.

  • Зависимость от JavaScript-движков браузера (V8, SpiderMonkey и др.).

Используется в:

  • Flutter Web (flutter build web)

  • Веб-приложения на чистом Dart

4. Компиляция в Kernel IR

Kernel — это внутреннее промежуточное представление кода, которое используется Dart VM и компилятором.

Как работает:

  • Dart-код компилируется в промежуточное представление (IR).

  • IR может интерпретироваться или использоваться как вход для дальнейшей JIT/AOT-компиляции.

Используется:

  • Для оптимизации процесса компиляции.

  • В DevTools, VM, при работе IDE с анализом кода.

🔁 Сравнение по режимам

Характеристика JIT AOT dart2js (в JS)
Время компиляции Быстрое (в рантайме) Долго (на стадии сборки) Среднее/медленное
--- --- --- ---
Время запуска Дольше Быстро Зависит от браузера
--- --- --- ---
Производительность Средняя Высокая Хорошая
--- --- --- ---
Hot reload Частично
--- --- --- ---
Размер исполняемого Большой (включает VM) Компактный JS-файл может быть большим
--- --- --- ---
Поддержка платформ Dev, Mobile, CLI Mobile, Server, Desktop Web
--- --- --- ---

📦 Дополнительно: компиляция в нативный код

dart compile — универсальный инструмент

dart compile exe bin/main.dart -o main.exe # exe: нативный бинарник

dart compile js web/main.dart -o main.js # js: для браузера

dart compile aot-snapshot main.dart # AOT snapshot

dart compile kernel main.dart # Kernel IR

🧪 Когда использовать что?

  • Во время разработки: JIT (для hot reload, быстрое тестирование).

  • Для продакшена на мобильных/десктоп: AOT-компиляция.

  • Для веба: Компиляция в JavaScript через dart2js или flutter build web.

  • Для CLI или серверов: AOT через dart compile exe или dart compile aot-snapshot.

Каждый из этих подходов служит определённой цели: быстрое прототипирование, высокая производительность, возможность запуска в браузере или на сервере. Dart предоставляет гибкость выбора нужной стратегии компиляции под конкретную задачу.