Hot Reload — teknik som gör det möjligt att uppdatera koden i en fungerande mobilapp utan omstart och förlust av aktuellt tillstånd. Utvecklaren ändrar källkoden — inom en sekund visas ändringarna på enhetens eller emulatorns skärm. Detta är en nyckelfunktion i Flutter och React Native som radikalt påskyndar utvecklingsiterationer: tiden för redigerings-visningscykeln minskar från 5–10 sekunder (omkompilering) till 300–500 millisekunder. Enligt Flutter Documentation, 2025 utför hot reload inkrementell kompilering av ändrad kod och skickar uppdateringen till Dart VM.
Huvudpunkter
Hot Reload — en utvecklingsmekanism där källkoden ändras och tillämpas på en redan igång app utan att stoppa den. Utvecklaren redigerar filen, sparar den och efter 0.3–2 sekunder visas det uppdaterade gränssnittet på skärmen. Appens tillstånd (räknare, rullningsposition, inmatade data) bevaras — utvecklaren förlorar inte sammanhanget.
Konceptet hot reload uppstod i tidiga webbverktyg (LiveReload, 2010) och anpassades för mobilutveckling av ramverken Flutter (2017) och React Native (2015). Idag är hot reload en obligatorisk funktion i moderna mobila ramverk, tillsammans med debug-konfiguration och profilering. Utan hot reload anses UI-utveckling vara ineffektiv: varje visning av en ändring kräver 10–30 sekunder för omkompilering och start.
Tekniskt sett består hot reload av tre steg: upptäckt av ändring (file watcher), kompilering av ändrad kod (incremental compiler) och tillämpning (hot patching). Varje ramverk implementerar dessa steg på olika sätt, men resultatet är detsamma: minimal fördröjning mellan redigering och visning.
Hot Reload i Flutter är byggd på Dart VM-arkitekturen och JIT-kompilering. När utvecklaren trycker på „Hot Reload” i IDE eller sparar en fil, utför Flutter inkrementell kompilering av ändrade Dart-bibliotek till kernel-filer (.dill). Dart VM laddar dessa filer och ersätter implementeringarna av ändrade funktioner i den fungerande appen.
// Flutter widget med tillstånd som bevaras vid hot reload
class CounterWidget extends StatefulWidget {
@override
State createState() => _CounterState();
}
class _CounterState extends State {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Räknare: $_counter'),
ElevatedButton(
onPressed: () => setState(() => _counter++),
child: Text('Öka'),
),
],
);
}
}
I exemplet bevarar StatefulWidget CounterWidget fältet _counter under hot reload. Dart VM återskapar tillståndet (State) genom att anropa reassemble(), men nollställer inte _counter — värdet bevaras om widgeten inte återskapas helt. Flutter anropar reassemble() för alla State-objekt, och build() körs igen med aktuell kod och bevarat tillstånd.
När hot reload inte fungerar: om en statisk initialiseringsvariabel (static const), global variabel, main(), enum/mixin-klassdeklaration, kod i @override initState() har ändrats. I dessa fall krävs Hot Restart. Enligt uppgifter från Flutter Team (2025) är hot reload framgångsrikt i 85–90% av fallen; 10–15% av ändringarna kräver full omstart.
Dart VM fungerar i debug-läge som en JIT-kompilator: den tolkar Dart-kod via kernel-formatet (analogt med bytekod). Hot reload laddar den nya kernel-filen och ersätter gamla funktionsdefinitioner. VM startar inte om isolat (isolates) — alla asynkrona operationer (Future, Stream) fortsätter att fungera. I release-läge kompileras Dart AOT (dart2native) och hot reload är inte tillgängligt.
Fast Refresh (tidigare Hot Reloading) i React Native använder Metro bundler — en JavaScript-modulbundlare som spårar filändringar. När utvecklaren sparar en fil kompilerar Metro endast den ändrade modulen (HMR — Hot Module Replacement) och skickar uppdateringen via WebSocket till den fungerande appen.
// React Native-komponent med tillståndsbevarande vid hot reload
import React, { useState } from 'react';
import { View, Text, Button } from 'react-native';
const Counter = () => {
const [count, setCount] = useState(0);
return (
<View>
<Text>Räknare: {count}Text>
<Button title="Öka"
onPress={() => setCount(c => c + 1)} />
View>
);
};
Fast Refresh bevarar React-tillståndet (useState, useReducer) vid uppdatering av modulen. Metro HMR skickar endast diffen av den ändrade modulen — inte hela bundlen. React Native använder React Fast Refresh, utvecklad av React-teamet (Dan Abramov, 2019): den genererar en ny rendering för komponenten men bevarar hook-tillstånd och props om komponentens signatur inte har ändrats.
Fast Refresh fungerar inte vid ändring av: export av komponent, hooks (useEffect, useMemo), modulberoenden och inbyggda moduler (Java/Objective-C). För sådana ändringar krävs Reload (fullständig omladdning av JS-bundle) eller Rebuild (omkompilering av inbyggd kod). Fast refresh-tid — 200–800 ms, full reload — 2–5 sekunder.
Hot Reload och Hot Restart — två lägen för koduppdatering med olika användningsscenarier. Hot Reload är lämpligt för UI-ändringar (stilar, layout, färger, texter) när klassstrukturen och tillståndstypen inte ändras. Hot Restart är nödvändigt vid ändring av metodsignaturer, tillägg av nya widgets/komponenter i rot-trädet, ändring av initState och inbyggda moduler.
| Egenskap | Hot Reload | Hot Restart |
|---|---|---|
| Hastighet | 0.3–2 sekunder | 2–10 sekunder |
| Bevarande av tillstånd | Ja (variabler, state, navigeringsstack) | Nej (appen startas om) |
| Kompilering | Inkrementell (endast ändringar) | Fullständig omkompilering Dart/JS |
| När ska användas | UI-justeringar, stilar, texter, layout | Strukturändring, nya moduler, inbyggd kod |
| Flutter | Hot Reload (R) | Hot Restart (Shift + R) |
| React Native | Fast Refresh | Reload (Cmd + R) |
Rekommenderad strategi: börja med hot reload. Om ändringarna inte har tillämpats (IDE visar „Reload needed”) — utför hot restart. I Flutter ändras knappikonen: blixt (⚡) för hot reload, överkryssad blixt — om restart krävs. Utvecklingseffektivitet med hot reload är 40–60% högre jämfört med fullständiga omkompileringar (data från JetBrains Developer Survey 2024).
Kodinsprutning (code injection) — en gemensam hot reload-mekanism som används av alla ramverk. Den omfattar tre faser. Första — upptäckt av ändring: file watcher (inbyggd i IDE) eller filsystemet (FSNotify) registrerar en ändring i en .dart-, .js-, .tsx-fil. Andra — kompilering: den inkrementella kompilatorn omvandlar endast den ändrade filen till en mellanliggande representation (kernel .dill för Dart, HMR-module för JS). Tredje — tillämpning: ny kod skickas till enheten och ersätter gamla definitioner i minnet av den fungerande appen.
Het ersättning av funktioner (hot patching) — teknik där runtime ersätter funktionspekaren (function pointer) i den virtuella metodtabellen. Dart VM använder ClassTable — en intern struktur som innehåller alla laddade klasser. Vid hot reload hittar VM klassen i ClassTable och ersätter dess funktionsdefinitioner med nya från kernel-filen. Alla befintliga instanser av klassen får automatiskt det nya beteendet.
// Flutter: reassemble-callback för tillståndshantering efter hot reload
class MyWidget extends StatefulWidget {
@override
State createState() => _MyState();
}
mixin ReloadAware on State {
@override
void reassemble() {
super.reassemble();
// Återställ cache eller data efter hot reload
clearCache();
}
}
I exemplet åsidosätter mixin ReloadAware metoden reassemble(), som Dart VM anropar på varje State-objekt efter hot reload. Utvecklaren kan återställa cacheminnet, återinitiera resurser eller utföra tillståndsmigrering. Utan denna metod kan gamla data finnas kvar i cachen och orsaka inkonsekvens efter uppdatering av widgets.
Het ersättning fungerar inte för ändringar som kräver omfördelning av minne för nya fält, ändring av variabeltyp i en klass, tillägg av nya fält i StatefulWidget, ändring av enum-värden eller generiska parametrar. Dessa ändringar är inkompatibla med befintliga objekt i minnet — Dart VM kan inte „omorganisera” fält i redan allokerade objekt. För sådana fall krävs het omstart (hot restart) eller fullständig omkompilering.
Native Android och iOS-utveckling har traditionellt inte fullständig hot reload. Android Studio med Android 11+ och AGP 4.2+ stöder Apply Changes: koduppdatering utan omstart av appen. Apply Changes fungerar via Android Runtime (ART) — det ersätter metodimplementeringar i dex-filer i farten. Apply Changes är dock begränsad: fungerar inte för ändringar av resurser (layout.xml, drawable), manifest och inbyggda bibliotek.
Apple introducerade Previews (SwiftUI Preview) i Xcode 15 (2023) — detta är inte hot reload i klassisk mening. Previews kompilerar förhandsgranskningssektionen separat från huvudappen och visar resultatet i Xcode-ytan. När en fil sparas uppdateras Preview inom 1–3 sekunder, men appens tillstånd bevaras inte. För UIKit-projekt är hot reload tillgängligt via tredjepartsverktyg: InjectionIII (John Holdsworth) och SwiftHotReload.
Kotlin Multiplatform (KMP) fick från 2024 experimentellt stöd för hot reload från JetBrains. Mekanismen är baserad på Kotlin/Native runtime med ersättning av funktioner i objektfilen (.klib). JetBrains Compose Multiplayer använder sin egen hot reload-implementering, liknande Flutter: inkrementell kompilering och ersättning av klasser i Kotlin/Native runtime. Hastighet — 1–3 sekunder, endast tillgängligt för UI-ändringar.
Apply Changes — en mekanism i Android Studio som använder ART runtime API. När kod sparas avgör Android Studio vilka klasser som har ändrats och skickar deras dex-filer till enheten via adb. ART ersätter metodimplementeringar i den fungerande appen utan att stoppa den. Apply Changes fungerar i tre lägen: Instant Run (snabb metodersättning), Swap (ersättning av klass med återskapande av instanser) och Restart Activity (om ändringarna är inkompatibla med aktuellt tillstånd).
Vanliga frågor
Hot Reload uppdaterar koden utan omstart av appen och bevarar tillståndet. Live Reload laddar om hela appen eller webbsidan när filer ändras. Live Reload är enklare att implementera men långsammare och förlorar tillståndet. Flutter och React Native använder hot reload, webbverktyg använder live reload.
Hot Reload fungerar inte vid ändringar som kräver omfördelning av minne (nya fält i en klass), ändring av statiska konstanter (static const), omdöpning av widgets, ändring av enum eller generiska parametrar. Dessa ändringar är inkompatibla med befintliga objekt i minnet för Dart VM eller JavaScript runtime.
Ja, hot reload fungerar både på en fysisk enhet och på en emulator. Flutter skickar kernel-filer till enheten via USB (adb forward) eller Wi-Fi. React Native använder WebSocket via metro bundler. Fördröjningen på en fysisk enhet är vanligtvis 10–30% högre än på en emulator.
Xcode Previews (sedan 2021) — motsvarigheten till hot reload för SwiftUI, men med begränsningar: förhandsgranskningen kompileras separat, stöder inte navigering genom appen och komplexa tillstånd. Apple tillhandahåller inte officiell hot reload för iOS. Tredjepartsverktyg: InjectionIII och SwiftHotReload använder Objective-C Runtime för kodinsprutning.
Om UI visas felaktigt efter hot reload: utför hot restart. Om problemet ligger i data — kontrollera reassemble()-callback i Flutter eller useEffect cleanup i React Native. För ihållande problem använd Flutter Clean eller Reset Metro Cache. Om felet bara uppträder efter reload — är detta ett tecken på inkompatibilitet mellan ändringarna och det befintliga tillståndet.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också