Composition: essentie, opbouw van de UI-boom in Compose

Auteur: IT Sectr Gepubliceerd: 2026-06-27 Leestijd: 7 min

Composition — is het centrale proces in Jetpack Compose, waarbij uit beschrijvende Composable-functies een levende UI-boom wordt opgebouwd die op het scherm wordt weergegeven. In tegenstelling tot het View-systeem in Android, waar de layout uit XML werd geladen en omgezet in onveranderlijke objecten, werkt Composition als een dynamisch systeem: functies worden uitgevoerd, creëren slots in het geheugen, vormen een hiërarchie van knooppunten en koppelen deze aan de toestand. Volgens Google Android Developers, 2026 is het begrijpen van Composition cruciaal voor het optimaliseren van de prestaties van Compose-applicaties.

Belangrijkste punten

  • Composition — het uitvoeren van Composable-functies om de UI-boom op te bouwen
  • Slots — geheugencellen die de parameters en toestand van elke functie opslaan
  • Positie in Compose (Positional Memorization) koppelt toestand aan de plaats in de code
  • Eerste doorgang Composition maakt de initiële UI-boom bij het starten van het scherm
  • CompositionLocal geeft gegevens door de boom zonder expliciete parameters

Wat is Composition in Jetpack Compose

Composition — is het proces van het uitvoeren van Composable-functies, resulterend in een interne representatie van de gebruikersinterface in de vorm van een boom van knooppunten. Elk knooppunt van deze boom komt overeen met een ingebouwd component (Text, Button, Image) of een aanroep van een aangepaste Composable-functie. Composition maakt niet direct Android View-objecten — het bouwt een abstracte beschrijving die vervolgens wordt verwerkt door de fasen Layout en Drawing.

Het belangrijkste kenmerk van Composition is de herstartbaarheid (restartability). Elke Composable-functie in de compositie kan op elk moment opnieuw worden gestart als de invoerparameters of de doorgelezen toestandsobjecten zijn gewijzigd. Het systeem herstart niet de hele boom — alleen de functies die daadwerkelijk afhankelijk zijn van de gewijzigde gegevens.

Technisch wordt Composition beheerd via Composer — een interne engine die de Kotlin-compiler in elke Composable-functie inbouwt. Composer schrijft in slots (positiegroepen) informatie over welke functies zijn aangeroepen, met welke parameters en in welke volgorde. Bij volgende aanroepen vergelijkt Composer de nieuwe gegevens met de opgeslagen en beslist over herstart.

Hoe wordt de UI-boom opgebouwd tijdens Composition

Het proces van het opbouwen van de UI-boom begint met het aanroepen van de methode setContent in Activity of Fragment. Deze methode creëert de initiële Composition en start de uitvoering van de root Composable-functie. Vervolgens voegt elke geneste Composable-functie zijn knooppunten toe aan de boom, waardoor een hiërarchie ontstaat: Row bevat Text en Button, Column bevat Image en Card, enzovoort.

Elk knooppunt van de boom krijgt een unieke positiesleutel, gebaseerd op zijn positie in de broncode. Deze sleutel wordt gebruikt voor identificatie van het knooppunt bij herhaalde uitvoeringen. De positiesleutel is de reden waarom de volgorde van het aanroepen van Composable-functies niet van voorwaarden mag afhangen: als in de ene uitvoering A -> B is aangeroepen en in de volgende B -> A, kan Compose de oude en nieuwe knooppunten niet matchen.

kotlin
@Composable
fun AppScreen() {
    Column {                     // Column-knooppunt (positie 1)
        HeaderSection()            // HeaderSection-knooppunt (positie 2)
        ContentSection()           // ContentSection-knooppunt (positie 3)
        FooterSection()            // FooterSection-knooppunt (positie 4)
    }
}

@Composable
fun HeaderSection() {
    Row {                       // Row-knooppunt (positie 2.1)
        Text("Titel")         // Text-knooppunt (positie 2.2)
        Icon(...)                // Icon-knooppunt (positie 2.3)
    }
}

In dit voorbeeld krijgt elke aanroep een positie op basis van de volgorde in de code. Column (positie 1) bevat drie onderliggende knooppunten (posities 2, 3, 4). HeaderSection voegt nog twee onderliggende knooppunten toe (2.1, 2.2, 2.3). Als in de volgende recompositie ContentSection vóór HeaderSection wordt aangeroepen, kan Composer de knooppunten niet correct matchen — vandaar de regel: de volgorde van aanroepen van Composable-functies moet stabiel zijn.

Toestandsbeheer in Composition

Toestand in Composition wordt beheerd via objecten van het type State<T>. Wanneer een Composable-functie een waarde uit State leest via een gedelegeerde eigenschap (by), registreert deze een afhankelijkheid van die State. Bij wijziging van de waarde worden alle functies die deze State hebben gelezen, gemarkeerd voor herstart in de volgende compositiefase.

Het mechanisme voor het registreren van afhankelijkheden heet het snapshotsysteem. Elke keer dat State verandert, registreert de snapshot alle wijzigingen en stelt Composer op de hoogte van welke functies afhankelijk zijn van deze State. Het is belangrijk om te begrijpen: het lezen van State in niet-Composable-code (bijvoorbeeld in een onClick-lambda) registreert geen afhankelijkheid — alleen lezen binnen een Composable-functie of in lambda's die in de context van de compositie worden uitgevoerd.

Het snapshotsysteem werkt transactioneel: meerdere wijzigingen van State binnen één gebeurtenis worden samengevoegd tot één transactie, wat meerdere recomposities voorkomt. Dit is vooral belangrijk bij het verwerken van gebaren: tijdens één beweging veranderen meerdere State-objecten, maar Compose voert slechts één recompositie uit.

kotlin
@Composable
fun StateExample() {
    var text by remember { mutableStateOf("Hello") }
    var isVisible by remember { mutableStateOf(true) }

    Column {
        Text(text)  // registreert afhankelijkheid van text

        if (isVisible) {  // registreert afhankelijkheid van isVisible
            TextField(value = text, onValueChange = { text = it })
        }

        Button(onClick = { isVisible = !isVisible }) {
            Text(if (isVisible) "Verbergen" else "Tonen")
        }
    }
}

Wijziging van text leidt tot recompositie van alleen Column, Text en TextField. Button en de voorwaarde isVisible blijven ongewijzigd. Een dergelijke isolatie van recompositie is een belangrijk voordeel van Compose ten opzichte van systemen die het hele scherm opnieuw tekenen. Elke Composable-functie volgt alleen die State-objecten die hij direct leest.

Composition vs Recomposition: belangrijke verschillen

Composition (compositie) en Recomposition (recompositie) — zijn twee verschillende uitvoeringsmodi van Composable-functies. Composition vindt eenmalig plaats bij het maken van het scherm: het systeem voert alle Composable-functies uit met beginwaarden en bouwt de initiële UI-boom. Recomposition vindt meerdere keren plaats bij wijziging van gegevens: het systeem herstart alleen de functies die afhankelijk zijn van de gewijzigde toestand.

Modus Composition activeert alle knooppunten van de boom, wijst slots toe voor elke functie, registreert alle afstammelingen. Recomposition werkt selectief: Composer vergelijkt nieuwe en oude parameterwaarden van elke functie, en als ze niet zijn gewijzigd — wordt de functie niet uitgevoerd (skipping).

Composition en Recomposition verschillen in kosten. De eerste Composition is duurder, omdat deze volledige opbouw van de boom en toewijzing van slots vereist. Recomposition is goedkoper, vooral als de meeste functies stabiel zijn — hun parameters worden vergeleken via equals en Compose slaat hun aanroep over. Voor maximale prestaties moet men ernaar streven dat zo min mogelijk functies door recompositie worden getroffen.

KenmerkCompositionRecomposition
Wanneer vindt plaatsEenmalig, bij eerste weergaveMeerdere keren, bij gegevenswijziging
OmvangHele boomAlleen gewijzigde functies
ParametervergelijkingNiet uitgevoerdUitgevoerd voor skipping
Aanmaken slotsJa, alle slots worden aangemaaktAlleen voor nieuwe knooppunten

CompositionLocal: gegevens doorgeven via de boom

CompositionLocal — een mechanisme voor het impliciet doorgeven van gegevens via de compositieboom. Het lost het probleem op wanneer een parameter moet worden doorgegeven via tientallen geneste Composable-functies die hem niet direct gebruiken. In plaats van een expliciete parameterketen worden gegevens op het hoogste niveau ingesteld en in elke geneste functie gelezen via CompositionLocal.current.

Het MaterialTheme-thema — het bekendste voorbeeld van CompositionLocal. Alle Compose-componenten lezen kleuren, typografie en vormen via MaterialTheme.colorScheme, MaterialTheme.typography, MaterialTheme.shapes, zonder ze via parameters te ontvangen. De ontwikkelaar kan eigen CompositionLocal maken voor gegevens zoals de huidige gebruiker, lokalisatie-instellingen of schermconfiguratie.

Belangrijke beperking: CompositionLocal moet niet worden gebruikt voor frequent veranderende gegevens (scrollpositie, tekst in een invoerveld). Het component dat CompositionLocal leest, wordt bij elke waardewijziging herstart, daarom is het voor dynamische gegevens beter om expliciete parameters of State te gebruiken. CompositionLocal is optimaal voor configuratiegegevens die zelden of nooit veranderen.

kotlin
val LocalUser = compositionLocalOf<User?> { null }

@Composable
fun AppRoot(user: User, content: @Composable () -> Unit) {
    CompositionLocalProvider(LocalUser.provides(user)) {
        content()
    }
}

@Composable
fun UserAvatar() {
    val user = LocalUser.current  // lezen zonder expliciete parameter
    AsyncImage(model = user?.avatarUrl, contentDescription = "Avatar")
}

CompositionLocalProvider creëert een zichtbaarheidsbereik waarbinnen LocalUser.current de ingestelde waarde retourneert. UserAvatar leest de gebruiker zonder expliciete parameteroverdracht via tussenliggende functies. Dit is vooral waardevol in diepe hiërarchieën waar gegevens slechts in enkele bladknooppunten nodig zijn.

Veelgestelde vragen

Wat gebeurt er als State wordt gewijzigd tijdens Composition?

Wijziging van State tijdens Composition plant een nieuwe recompositie die wordt uitgevoerd nadat de huidige is voltooid. Er treedt geen lus op: Compose garandeert dat elke recompositie in een aparte transactie van het snapshotsysteem wordt uitgevoerd.

Hoe lang duurt Composition van een complex scherm?

Op moderne apparaten duurt Composition van een scherm met 50–100 Composable-functies 1–5 ms. Google adviseert om binnen 16 ms per frame bij 60fps te blijven. Als Composition deze limiet overschrijdt, gebruik dan LazyColumn of verdeel het scherm in kleinere functies.

Kan Composition handmatig worden gestart?

Direct handmatig starten van Composition is niet mogelijk — het wordt automatisch beheerd door Composer. Men kan echter geforceerd een recompositie plannen door State te wijzigen of invalidate() aan te roepen op de root-composite, indien toegang tot CompositionContext beschikbaar is.

Waarin verschilt Composition van de View-hiërarchie in klassiek Android?

View-hiërarchie — is een onveranderlijke boom van Java-objecten die eenmalig wordt gemaakt. Composition — een virtuele boom die bij elke gegevenswijziging wordt herbouwd. View behoudt zijn toestand in instantievariabelen, Composition — in slots die zijn gekoppeld aan de aanroeppositie van de functie.

Hoe gaat Composition om met het verwijderen van knooppunten?

Als een Composable-functie niet meer wordt aangeroepen (bijvoorbeeld de voorwaarde if wordt false), verwijdert Composition het knooppunt en roept de opschoning van DisposableEffect aan. Bij terugkeer (if wordt weer true) wordt een nieuw knooppunt aangemaakt — het oude wordt niet hersteld.

Samenvatting

  • Composition — proces van het uitvoeren van Composable-functies voor het opbouwen van de UI-boom met koppeling aan toestand
  • Composer beheert slots, registreert functieaanroepen en vergelijkt parameters bij recompositie
  • Snapshotsysteem registreert afhankelijkheden van functies van State en voegt wijzigingen samen in transacties
  • Composition wordt eenmalig uitgevoerd bij start, Recomposition — bij gegevenswijziging
  • CompositionLocal geeft configuratiegegevens door de boom zonder expliciete parameterketen
  • Positie van functieaanroep dient als unieke identificatie in de compositieboom
  • Aanbeveling: maak Composable-functies klein met onveranderlijke parameters voor effectieve skipping

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook