Android Lint for Jetpack Compose

Android Lint for Jetpack Compose: Fixing UI Performance Warnings the Smart Way

Android Lint for Jetpack Compose: Fixing UI Performance Warnings the Smart Way

When you're building beautiful UI with Jetpack Compose, it's easy to get caught up in previews and animations—but behind the scenes, you might be introducing subtle performance issues without even knowing it.

That’s where Android Lint comes in. It’s your quiet watchdog—pointing out bad patterns, inefficient code, and potential bugs before they go live. But Compose introduced new patterns, and with that, new kinds of Lint warnings.

In this post, let’s explore how to use Android Lint effectively with Jetpack Compose, decode the most common warnings, and actually fix them the right way.

🤔 What is Android Lint (And Why Should You Care)?

Android Lint is a static analysis tool built into Android Studio. It inspects your code without running it and flags things like:
  • Bad practices (e.g., hardcoded text)
  • Layout issues (e.g., missing constraints)
  • Resource misuse (e.g., unused IDs)
  • Now: Compose-specific problems
And guess what? Many Compose performance problems show up as Lint warnings before they ever slow your app down in production.

So ignoring Lint = ignoring helpful advice.

⚠️ Compose-Specific Lint Warnings You Should Not Ignore

1. "Modifier order matters"

Modifier chain should be ordered for better performance and clarity

✅ Example Fix:

// 🚫 Inefficient
Modifier
    .padding(16.dp)
    .fillMaxWidth()
    .background(Color.Red)

// ✅ Better
Modifier
    .fillMaxWidth()
    .background(Color.Red)
    .padding(16.dp)
📌 Why? Putting fillMaxWidth() early avoids unnecessary layout recalculations caused by padding. Padding should typically come last.

2. "Unstable collections passed to Composables"
Do not pass unstable types (like List) without using remember

Bad

@Composable
fun UserList() {
    val users = listOf("A", "B", "C")
    LazyColumn {
        items(users) {
            Text(it)
        }
    }
}


Good

@Composable
fun UserList() {
    val users = remember { listOf("A", "B", "C") }
    LazyColumn {
        items(users) {
            Text(it)
        }
    }
}
📌 Why? Recreating collections on every recomposition triggers unnecessary UI rebuilds.

3. "Remember call inside composition is missing"

State object should be remembered to retain across recompositions

🚫 This will break:

val scrollState = ScrollState(0)

✅ This is correct:

val scrollState = rememberScrollState()
If you forget to remember state, every recomposition will recreate it, causing weird bugs like "jumping scroll".

4. "Composables not marked as @Composable"

Lint will scream if you forget this—because the compiler can’t run it otherwise.
// Missing @Composable annotation = crash
fun ShowText() {
    Text("Hello")
}
Always mark UI functions with @Composable or they'll silently fail to show up.


👨‍🔧 How to Fix These Warnings the Smart Way

✅ Step 1: Run Inspect Code


In Android Studio:
  • Go to Analyze > Inspect Code
  • Choose your module or whole project
  • Select Jetpack Compose > Compose Lint Checks

This gives you a full list of actionable suggestions.

✅ Step 2: Fix with Auto-Correction (When Safe)

Some warnings have quick fixes. Android Studio will underline them in yellow. Just press Alt + Enter and apply the recommended fix.

💡 But beware: Always read the description. Don’t apply fixes blindly. Some suggestions depend on your design intent.

✅ Step 3: Turn On Lint in CI/CD

Add this in your build.gradle to enforce Lint in every build:
android {
    lintOptions {
        abortOnError true
        warningsAsErrors true
        checkReleaseBuilds true
    }
}
This ensures no bad patterns sneak into production.


✅ Step 4: Create Your Own Custom Lint Rules (Optional)

You can even define your own rules for team-wide guidelines like:
  • Enforce all text to come from string.xml
  • Disallow Modifier.clickable without semantics
It takes effort but boosts long-term code health.


🚨 Common Compose Lint Mistakes That Lead to Bugs

  • Creating state inside loops
  • Forgetting to use remember for ScrollState, CoroutineScope, etc.
  • Modifying lists without using mutableStateListOf()
  • Passing mutable parameters directly into Composables

All of these trigger Lint warnings. Don’t ignore them.


🧠 Real Developer Advice: Don’t Fight Lint, Learn From It

Think of Lint as your pair programmer. It’s not there to annoy you — it’s there to help you catch bugs before your users do.

Every Lint warning you ignore might come back as a bug report on your Play Store page.

So fix it now — or debug it later under pressure.


✅ Summary: Compose Lint Survival Kit

ProblemHow to Fix
Wrong modifier orderUse fillMaxWidth() before padding
Unstable collections passed inWrap them with remember { }
State objects not rememberedUse remember, rememberSaveable
Missing @Composable annotationMark your UI function with @Composable
Performance warnings in Lazy listsUse key param and avoid reallocation


💬 Final Thoughts

Android Lint is no longer just about XML and layouts — it’s now smarter, Compose-aware, and developer-friendly. Instead of fearing warnings, embrace them. Fixing small issues today will save you hours of frustration tomorrow.

Let me know in the views:

What’s the weirdest Compose bug you fixed thanks to a Lint warning?
Until next time, keep your code clean and your previews pretty.
Sandeep@CodingBihar.com
Previous Post Next Post

Contact Form