FlutterMiddleTechnical

В чём разница между hot reload и hot restart во Flutter?

Hot reload патчит код в памяти, сохраняя State виджетов и навигацию, но не вызывает initState повторно. Hot restart полностью перезапускает Dart VM, сбрасывая всё состояние — как перезапуск приложения.

Hot Reload vs Hot Restart во Flutter

Оба инструмента ускоряют разработку, но работают на разных уровнях рантайма Dart VM.

Hot Reload

Команда: r в терминале, или кнопка молнии в IDE.
Принцип: Dart VM получает новый исходник, компилирует изменённые библиотеки и патчит классы в памяти. Дерево виджетов пересобирается с вызовом build(), но объекты State не пересоздаются — они остаются живыми.

Что сохраняется:

  • Все поля State (счётчики, текст в контроллерах, позиция скролла).
  • Текущий маршрут навигации.
  • Подписки, таймеры, стримы, открытые сокеты.

Что не применяется через hot reload:

  • Изменения в initState(), didInitDependencies() — они не вызываются повторно.
  • Изменения в main() и глобальных переменных верхнего уровня.
  • Изменения в enum и generics (требуют hot restart).
  • Добавление новых полей в существующий State — новые поля будут null, пока не будет hot restart.
class _CounterState extends State<Counter> {
  int _count = 0; // сохранится при hot reload

  @override
  void initState() {
    super.initState();
    // изменения здесь не применятся при hot reload
    _count = 10;
  }

  @override
  Widget build(BuildContext context) {
    return Text('$_count'); // изменения в build() применятся мгновенно
  }
}

Hot Restart

Команда: R (заглавная) в терминале, или кнопка перезапуска в IDE.
Принцип: Dart VM полностью останавливается и запускается заново. Все объекты уничтожаются, main() вызывается с нуля. Занимает 2-5 секунд против ~0.3 с для hot reload.

Что сбрасывается:

  • Весь State приложения.
  • Навигационный стек.
  • Глобальные переменные и singleton-и.
  • Зависимости, инициализированные в main().

Когда обязательно нужен hot restart:

  • Изменили main(), провайдеры верхнего уровня, тему приложения.
  • Добавили новый platform channel или плагин.
  • Поменяли enum, type alias, extension.
  • Получили сообщение "Reload not applied. Unable to hot reload".

Практическое сравнение

# Запуск
flutter run

# В терминале:
# r  — hot reload (сохраняет State)
# R  — hot restart (сбрасывает всё)
# q  — выход
# p  — показать границы виджетов (debugPaintSizeEnabled)

Подводные камни

  • Hot reload не вызывает initState повторно — если логика инициализации изменилась, нужен hot restart.
  • Новые поля State после hot reload будут иметь значение null вместо инициализированного — может вызвать NPE в runtime.
  • Изменения в нативном коде (Kotlin/Swift, plugin) не применяются ни hot reload, ни hot restart — нужен полный пересбор flutter run.
  • Hot reload в web работает через HMR браузера и медленнее, чем на мобильных платформах.
  • При использовании Riverpod ProviderScope или BLoC глобальные провайдеры могут накапливать устаревшее состояние после серии hot reload.
  • Изменения в assets (картинки, переводы) не подхватываются hot reload — только hot restart.

Common mistakes

  • Сводить «hot reload и hot restart во Flutter» к синтаксису и не объяснять platform channel.
  • Игнорировать жизненный цикл, основной поток или момент освобождения ресурсов в сценарии flutter-4.
  • Выбирать API по привычке, не проверяя состояние, ошибки, доступность и платформенные ограничения.

What the interviewer is testing

  • Формулирует точную модель для «hot reload и hot restart во Flutter» и подтверждает ее корректным примером.
  • Умеет связать ответ с widget tree, тестированием и отладкой на устройстве.
  • Называет ограничения подхода flutter-4, включая производительность, память и сопровождение.

Sources

Related topics