Slide 1

Slide 1 text

Performance in a Compose world Dinorah Tovar Google Developer Expert Android @ddinorahtovar @ddinorahtovar

Slide 2

Slide 2 text

Recomposition Disclaimer: This talk is about ✨ Because performance has to do EVERYTHING with recomposition ✨ @ddinorahtovar

Slide 3

Slide 3 text

Compose aims for Perfomance Great @ddinorahtovar @Composable fun HelloWorld() { Text("Hello World") }

Slide 4

Slide 4 text

Compose already give you some tips First of all - if you are having trouble with ur perfomance • Make sure you are doing the proper configuration in gradle • Debug mode is always slower that Release Mode + R8 enable • Do a macrobenchmark and optimize some flows • But first, you need to check if you are doing recomposition @ddinorahtovar

Slide 5

Slide 5 text

Compose already give you some tips First of all - if you are having trouble with ur perfomance • But first, you need to check if you are doing too many recomposition @ddinorahtovar (maybe after the gradle) (maybe a little bit (not so little) too much

Slide 6

Slide 6 text

Composition @ddinorahtovar

Slide 7

Slide 7 text

@Composable fun view(data: Int) data: Int Composition emit Compositions shoots! 🥂 @ddinorahtovar

Slide 8

Slide 8 text

Compositions shoots! 🥂 First Interaction Composition Insert “A” Insert “B” Second Interaction Re-composition @ddinorahtovar

Slide 9

Slide 9 text

@ddinorahtovar @Composable fun SomeText() { var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { text = it } ) } Field Input

Slide 10

Slide 10 text

Composition 
 Slot Table Composer Compose Runtime The composition is the state maintained by the memory Compose @ddinorahtovar

Slide 11

Slide 11 text

Compose Runtime Composition 
 Compose Runtime Slot Table Composer •Fundamental building blocks of Compose's programming model and state management, and core runtime for the Compose Compiler Plugin to target. •Handle everything for the states @ddinorahtovar

Slide 12

Slide 12 text

Slot Table Composition 
 Slot Table Composer Compose Runtime •Current state of the Composition •Updates with every composition •Gap Buffer - data structure •Positional Memorization @ddinorahtovar

Slide 13

Slide 13 text

Composition 
 Slot Table Composer Compose Runtime Unused Used B Used A Internal array Gap Collection Emit Collect B Collect A Slot Table @ddinorahtovar

Slide 14

Slide 14 text

Composer •Reusable logic - for reusable purpose Composition 
 Composer Compose Runtime Slot Table @ddinorahtovar

Slide 15

Slide 15 text

@ddinorahtovar Composition 
 Composer Compose Runtime Slot Table fun MultiMeasureLayout( modifier: Modifier = Modifier, content: @Composable () -> Unit, measurePolicy: MeasurePolicy ) { val materialized = currentComposer.materialize(modifier) val density = LocalDensity.current val layoutDirection = LocalLayoutDirection.current ReusableComposeNode>( factory = LayoutNode.Constructor, update = { set(materialized, ComposeUiNode.SetModifier) set(measurePolicy, ComposeUiNode.SetMeasurePolicy) set(density, ComposeUiNode.SetDensity) set(layoutDirection, ComposeUiNode.SetLayoutDirection) @Suppress("DEPRECATION") init { this.canMultiMeasure = true } }, content = content ) }

Slide 16

Slide 16 text

@ddinorahtovar Composition 
 Composer Compose Runtime Slot Table fun MultiMeasureLayout( modifier: Modifier = Modifier, content: @Composable () -> Unit, measurePolicy: MeasurePolicy ) { val materialized = currentComposer.materialize(modifier) val density = LocalDensity.current val layoutDirection = LocalLayoutDirection.current ReusableComposeNode>( factory = LayoutNode.Constructor, update = { set(materialized, ComposeUiNode.SetModifier) set(measurePolicy, ComposeUiNode.SetMeasurePolicy) set(density, ComposeUiNode.SetDensity) set(layoutDirection, ComposeUiNode.SetLayoutDirection) @Suppress("DEPRECATION") init { this.canMultiMeasure = true } }, content = content ) }

Slide 17

Slide 17 text

@ddinorahtovar Composition 
 Composer Compose Runtime Slot Table @Composable inline fun > ReusableComposeNode( noinline factory: () -> T, update: @DisallowComposableCalls Updater.() -> Unit, content: @Composable () -> Unit ) { if (currentComposer.applier !is E) invalidApplier() currentComposer.startReusableNode() if (currentComposer.inserting) { currentComposer.createNode(factory) } else { currentComposer.useNode() } currentComposer.disableReusing() Updater(currentComposer).update() currentComposer.enableReusing() content() }

Slide 18

Slide 18 text

Give it a try! @ddinorahtovar

Slide 19

Slide 19 text

Performance in a Compose world Dinorah Tovar Google Developer Expert Android @ddinorahtovar @ddinorahtovar