# jank

Published articles for jank.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Why Your LazyColumn Is Still Janky

DevFeed: [Why Your LazyColumn Is Still Janky](<https://devfeed.tech/articles/why-your-lazycolumn-is-still-janky-57485.md>)

Original publisher: [Read original article](<https://proandroiddev.com/why-your-lazycolumn-is-still-janky-47270b88670b?source=rss----c72404660798---4>)

Author: Subhankar Bag

Published: 2026-09-21T18:07:08Z

Content type: article

Language: en

Sources: [ProAndroidDev](<https://devfeed.tech/sources/proandroiddev-medium.md>)

Topics: [jank](<https://devfeed.tech/topics/jank.md>), [Image](<https://devfeed.tech/topics/image.md>), [Tool](<https://devfeed.tech/topics/tool.md>)

Tags: [4g](<https://devfeed.tech/tags/4g.md>), [android](<https://devfeed.tech/tags/android.md>), [build](<https://devfeed.tech/tags/build.md>), [cache](<https://devfeed.tech/tags/cache.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [compose](<https://devfeed.tech/tags/compose.md>), [compose-performance](<https://devfeed.tech/tags/compose-performance.md>), [composition](<https://devfeed.tech/tags/composition.md>), [containers](<https://devfeed.tech/tags/containers.md>), [content](<https://devfeed.tech/tags/content.md>), [debug](<https://devfeed.tech/tags/debug.md>), [device](<https://devfeed.tech/tags/device.md>), [image](<https://devfeed.tech/tags/image.md>), [images](<https://devfeed.tech/tags/images.md>), [jank](<https://devfeed.tech/tags/jank.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [key](<https://devfeed.tech/tags/key.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [list](<https://devfeed.tech/tags/list.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [measuring](<https://devfeed.tech/tags/measuring.md>), [mobile-development](<https://devfeed.tech/tags/mobile-development.md>), [nested](<https://devfeed.tech/tags/nested.md>), [nested-scroll](<https://devfeed.tech/tags/nested-scroll.md>), [performance](<https://devfeed.tech/tags/performance.md>)

### AI overview

Scrolling jank often comes from work scheduled into the frame when a new item appears, rather than from scrolling itself. The article identifies unstable or missing item keys, nested scroll containers that remove lazy measurement, expensive first-time row composition, oversized image decoding, insufficient prefetch, and misleading debug-build measurements. It recommends stable unique keys and content types; a single LazyColumn with bounded layout; moving formatting and other work out of row composition, hoisting constants, and limiting costly draw effects; requesting display-sized images with fixed dimensions and checking cache hits; and tuning LazyLayoutCacheWindow against memory use. Diagnose with a release-mode system trace and composition tracing, then benchmark on the worst supported device using consistent data and network conditions, a baseline profile, and P90/P99 frame timings. Prefetch trades memory and off-screen work for smoother scrolling, and prefetched rows may compose before becoming visible, so composition is not a reliable impression signal.

### Source excerpt

Part 4 of the Modern Compose Performance series. Previously: Stop Writing Compose Like It's 2024, Your Compose App Isn't Slow -- Your State Is, and The Compose Recomposition Mistakes I Keep Seeing in Production. If you're joining here, this article assumes your state reads are clean and no one is constructing a SimpleDateFormat in a row. Your state is clean. Your recomposition counts are flat. The compiler report says every row is restartable skippable. And the feed still stutters. Not always -- that's the maddening part. It's smooth on your Pixel, smooth in the office on Wi-Fi, and then someone drops a screen recording in Slack from a mid-range device on 4G where the list visibly hitches every time three new items arrive. You scroll it yourself on the test device and feel it: not a freeze, just a hesitation. A frame that should have taken 8ms took 40. Here's what took me longer than I'd like to admit to internalize: the jank you feel while scrolling is usually not caused by scrolling. By the time your finger is moving, Compose has almost nothing left to decide. The real cost was committed earlier -- when you declared the list, when you shaped the item, when you decided where an image gets decoded. Scrolling is just the moment the bill arrives. This article is about that bill. Six list-specific problems, why each one only shows up during scroll, and the before/after fix. TL;DR: six reasons your list hitches: No key, or an unstable one -- Compose can't tell your items apart, so it rebuilds them Nested scroll containers and unbounded height -- One misplaced Modifier.verticalScroll composes your whole list at once Expensive item content -- The row is skippable, but the first composition still costs 20ms Images decoded on the main thread -- The one that doesn't show up in recomposition counts at all Prefetch tuned for the wrong list -- Default cache windows assume light items Measuring in a debug build -- Half the jank you're chasing doesn't exist in release Then: how to tell wh

## Building Shellporter: From Idea to Production in a Week

DevFeed: [Building Shellporter: From Idea to Production in a Week](<https://devfeed.tech/articles/building-shellporter-from-idea-to-production-in-a-week-25589.md>)

Original publisher: [Read original article](<https://www.marcogomiero.com/posts/2026/building-shellporter/>)

Author: Marco Gomiero

Published: 2026-02-14T00:00:00Z

Content type: article

Language: en

Sources: [Posts on Marco Gomiero](<https://devfeed.tech/sources/posts-on-marco-gomiero.md>)

Topics: [ide](<https://devfeed.tech/topics/ide.md>), [Tool](<https://devfeed.tech/topics/tool.md>), [Visual Studio Code](<https://devfeed.tech/topics/visual-studio-code.md>)

Tags: [accessibility](<https://devfeed.tech/tags/accessibility.md>), [ai-agents](<https://devfeed.tech/tags/ai-agents.md>), [antigravity](<https://devfeed.tech/tags/antigravity.md>), [cache](<https://devfeed.tech/tags/cache.md>), [ide](<https://devfeed.tech/tags/ide.md>), [jank](<https://devfeed.tech/tags/jank.md>), [macos](<https://devfeed.tech/tags/macos.md>), [project](<https://devfeed.tech/tags/project.md>), [terminal](<https://devfeed.tech/tags/terminal.md>)

### AI overview

Shellporter is a macOS menu bar utility that opens a standalone terminal in the project directory associated with the frontmost IDE window, via a global hotkey or menu bar button. It reads window titles and document attributes through the macOS Accessibility API, then tries IDE-specific resolution strategies; the order varies by IDE and may use title parsing, accessibility attributes, or IDE metadata files. A cache provides a fallback when live resolution fails during transitions, and a manual folder picker is the last resort. The excerpt lists support for JetBrains IDEs, Android Studio, VS Code, Cursor, Antigravity, and Xcode, with Kitty, Ghostty, Terminal.app, iTerm2, or a custom terminal command. The supplied text cuts off during the build discussion.

### Source excerpt

I work with multiple projects at the same time. My typical macOS setup is one Desktop/Workspace per project, with my IDE and a terminal window. I prefer using a standalone terminal over the one built into the IDE because TUIs, especially those from AI agents, tend to perform better there: no scrolling jank, no weird jumps, and a generally smoother experience. And also I prefer to have a full big window dedicated to the terminal with more stuff to read rather than a small window in the IDE.

## Exploring PausableComposition internals in Jetpack Compose

DevFeed: [Exploring PausableComposition internals in Jetpack Compose](<https://devfeed.tech/articles/exploring-pausablecomposition-internals-in-jetpack-compose-25718.md>)

Original publisher: [Read original article](<https://blog.shreyaspatil.dev/exploring-pausablecomposition-internals-in-jetpack-compose/>)

Author: Shreyas Patil

Published: 2025-07-14T05:34:31Z

Content type: tutorial

Language: en

Sources: [Shreyas Patil's Blog](<https://devfeed.tech/sources/shreyas-patil-s-blog.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [code](<https://devfeed.tech/tags/code.md>), [compose](<https://devfeed.tech/tags/compose.md>), [declarative](<https://devfeed.tech/tags/declarative.md>), [internals](<https://devfeed.tech/tags/internals.md>), [jank](<https://devfeed.tech/tags/jank.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [performance](<https://devfeed.tech/tags/performance.md>), [performance-optimization](<https://devfeed.tech/tags/performance-optimization.md>), [ui](<https://devfeed.tech/tags/ui.md>), [uiux](<https://devfeed.tech/tags/uiux.md>)

### AI overview

This article explores the internals of PausableComposition, an internal API introduced in Compose 1.9.X. It explains how composition can be divided into smaller pieces and prepared asynchronously to reduce main-thread work and help prevent dropped frames during scrolling.

### Source excerpt

Explore the internals of PausableComposition in Jetpack Compose. Learn how Compose manages state and effects when a composition is paused or resumed.

## How Android Memory Leaks Cause Jank, Freezes, and ANRs

DevFeed: [How Android Memory Leaks Cause Jank, Freezes, and ANRs](<https://devfeed.tech/articles/freezes-anrs-check-memory-leaks-25624.md>)

Original publisher: [Read original article](<https://blog.p-y.wtf/freezes-anrs-check-memory-leaks>)

Author: Pierre-Yves Ricau

Published: 2023-07-20T22:09:53Z

Content type: tutorial

Language: en

Sources: [Py's blog](<https://devfeed.tech/sources/py-s-blog.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Memory Leaks](<https://devfeed.tech/topics/memory-leaks.md>), [Latency](<https://devfeed.tech/topics/latency.md>), [navigation](<https://devfeed.tech/topics/navigation.md>), [Java](<https://devfeed.tech/topics/java.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [jank](<https://devfeed.tech/tags/jank.md>), [latency](<https://devfeed.tech/tags/latency.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [memory-leak](<https://devfeed.tech/tags/memory-leak.md>), [memory-leaks](<https://devfeed.tech/tags/memory-leaks.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [outofmemory](<https://devfeed.tech/tags/outofmemory.md>), [performance](<https://devfeed.tech/tags/performance.md>)

### AI overview

This article explains how Android memory leaks can cause jank, freezes, and ANRs rather than immediate crashes. It describes tracking memory usage per navigation, correlating memory growth with navigation latency, and how garbage collection blocking the main thread affects UI responsiveness near the app memory limit.

### Source excerpt

In this article, I show how Android memory leaks lead to jank, freezes and ANRs more often than they lead to OutOfMemoryError crashes. Navigation Latency At Square, we've been tracking a User-Centric performance metric: Interaction Latency. We track ...

## First Impressions of Android's new ConstraintLayout

DevFeed: [First Impressions of Android's new ConstraintLayout](<https://devfeed.tech/articles/first-impressions-of-android-s-new-constraintlayout-41662.md>)

Original publisher: [Read original article](<http://mikewolfson.com/blog/2021/9/8/first-impressions-of-androids-new-constraintlayout>)

Author: Mike Wolfson

Published: 2021-09-08T15:57:48Z

Content type: opinion

Language: en

Sources: [My Big Appetite - Mike Wolfson](<https://devfeed.tech/sources/my-big-appetite-mike-wolfson.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [constraintlayout](<https://devfeed.tech/topics/constraintlayout.md>), [layout](<https://devfeed.tech/topics/layout.md>), [Android Studio](<https://devfeed.tech/topics/android-studio.md>), [User Interfaces](<https://devfeed.tech/topics/user-interfaces.md>), [XML](<https://devfeed.tech/topics/xml.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-layout](<https://devfeed.tech/tags/android-layout.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [constraintlayout](<https://devfeed.tech/tags/constraintlayout.md>), [gde](<https://devfeed.tech/tags/gde.md>), [jank](<https://devfeed.tech/tags/jank.md>), [layout](<https://devfeed.tech/tags/layout.md>), [render](<https://devfeed.tech/tags/render.md>), [responsive](<https://devfeed.tech/tags/responsive.md>), [ui](<https://devfeed.tech/tags/ui.md>), [xml](<https://devfeed.tech/tags/xml.md>)

### AI overview

An early review of Android's ConstraintLayout, introduced at Google I/O 2016. It describes the XML-based layout container, its constraint-driven responsive design, Android Studio's visual editor, and its goal of producing flatter view hierarchies for faster rendering and less visual jank.

### Source excerpt

This article was originally published to Medium on May 31, 2016 - 4 min read After Google IO, the Android GDE team got together to gather our thoughts about the most significant announcements from the conference. This is a summary of our thoughts about the new ConstraintLayout. Some of the Andoid GDEs at post-IO gathering At IO 2016, one of the more exciting announcements (especially for UI focused developers) was a new layout container and tool named ConstraintLayout (CL). It's early days for this tool. It is currently only available from the Canary channel of Android Studio. We expect it to mature quickly (they have already pushed their first update within the first week of release). We expect that eventually this layout type will be the default used for all top-level interfaces. ConstraintLayout View Type High-level Constraint Layout basic concepts On a basic level, the new CL is just another simple XML layout type. It is not much different then other layouts you are probably already using (like RelativeLayout or LinearLayout). In fact, the CL can be used just like any other layout -- it can be nested into other layouts, and even be used back to API 9. It is possible to view and edit the XML, but when we asked Googlers about this, they all answered: "You can, but why would you want to?". This is primarily designed as a visually oriented tool. The new layout is based on Constraints. These describe relationships between your views (or the screen), in a responsive nature. These attributes are very similar to the ones used with RelativeLayout (such as: android:layout_alignParentBottom="true"). If CL was just another layout container, there wouldn't be too much to be excited about. But, CL is much more then just another layout type. It is an all new layout container designed to help developers create complex layouts that are optimized to render quickly. This is because it generates flat view hierarchies (read this article to review why this is important). This will rea

## The Anatomy of a Frame

DevFeed: [The Anatomy of a Frame](<https://devfeed.tech/articles/the-anatomy-of-a-frame-39440.md>)

Original publisher: [Read original article](<https://aerotwist.com/blog/the-anatomy-of-a-frame>)

Author: Paul Lewis

Published: 2016-02-15T00:00:00Z

Content type: tutorial

Language: en

Sources: [Paul Lewis](<https://devfeed.tech/sources/paul-lewis.md>)

Topics: [Google Chrome](<https://devfeed.tech/topics/google-chrome.md>), [browser](<https://devfeed.tech/topics/browser.md>), [Process](<https://devfeed.tech/topics/process.md>), [GPU](<https://devfeed.tech/topics/gpu.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>), [layout](<https://devfeed.tech/topics/layout.md>), [Web Development](<https://devfeed.tech/topics/web-development.md>)

Tags: [browser](<https://devfeed.tech/tags/browser.md>), [chrome](<https://devfeed.tech/tags/chrome.md>), [code](<https://devfeed.tech/tags/code.md>), [gpu](<https://devfeed.tech/tags/gpu.md>), [jank](<https://devfeed.tech/tags/jank.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [layout](<https://devfeed.tech/tags/layout.md>), [pixels](<https://devfeed.tech/tags/pixels.md>), [process](<https://devfeed.tech/tags/process.md>)

### AI overview

This reference explains how Chrome and Blink move content from browser processes and renderer threads to the screen. It describes the GPU process, compositor thread, main thread, tile workers, input handling, JavaScript, style, layout, paint, and frame delivery, while noting that the architecture may differ across browser vendors.

### Source excerpt

I'm often asked by other developers about parts of the pixel workflow, and what fires when and why, so I figured it might be worth putting up a little reference for what's involved in shipping pixels to screen.

## The Hack is Back!

DevFeed: [The Hack is Back!](<https://devfeed.tech/articles/the-hack-is-back-39441.md>)

Original publisher: [Read original article](<https://aerotwist.com/blog/the-hack-is-back>)

Author: Paul Lewis

Published: 2016-01-25T00:00:00Z

Content type: tutorial

Language: en

Sources: [Paul Lewis](<https://devfeed.tech/sources/paul-lewis.md>)

Topics: [Image](<https://devfeed.tech/topics/image.md>), [performance-optimization](<https://devfeed.tech/topics/performance-optimization.md>), [async](<https://devfeed.tech/topics/async.md>), [User interface design](<https://devfeed.tech/topics/ui-design.md>), [Google Chrome](<https://devfeed.tech/topics/google-chrome.md>)

Tags: [accessibility](<https://devfeed.tech/tags/accessibility.md>), [accessible](<https://devfeed.tech/tags/accessible.md>), [alt-text](<https://devfeed.tech/tags/alt-text.md>), [aria](<https://devfeed.tech/tags/aria.md>), [background-image](<https://devfeed.tech/tags/background-image.md>), [based](<https://devfeed.tech/tags/based.md>), [blob](<https://devfeed.tech/tags/blob.md>), [block](<https://devfeed.tech/tags/block.md>), [blocking](<https://devfeed.tech/tags/blocking.md>), [browser](<https://devfeed.tech/tags/browser.md>), [bug](<https://devfeed.tech/tags/bug.md>), [canary](<https://devfeed.tech/tags/canary.md>), [canvas](<https://devfeed.tech/tags/canvas.md>), [chrome](<https://devfeed.tech/tags/chrome.md>), [chrome-canary](<https://devfeed.tech/tags/chrome-canary.md>), [code](<https://devfeed.tech/tags/code.md>), [decoding](<https://devfeed.tech/tags/decoding.md>), [hack](<https://devfeed.tech/tags/hack.md>), [image](<https://devfeed.tech/tags/image.md>), [images](<https://devfeed.tech/tags/images.md>), [jank](<https://devfeed.tech/tags/jank.md>), [perf](<https://devfeed.tech/tags/perf.md>)

### AI overview

`createImageBitmap` offers a browser-managed way to decode images in a worker, so decoding need not block other paint work on the main thread. The excerpt shows fetching an image as a blob, creating an `ImageBitmap` in a worker, and transferring it back with `postMessage`; `requestIdleCallback` can defer drawing until the main thread has time. Compared with the older JavaScript-decoder workaround, this avoids making developers manage decoding, memory use, image quality, and extra code. The feature is described as experimental in Chrome Canary behind the "Enable experimental canvas features" flag and available in Firefox 42 onward. Replacing `<img>` with `<canvas>` requires accessible markup; the excerpt recommends a labeled `role="img"` wrapper with an `aria-hidden="true"` canvas so hiding it also removes it from the accessibility tree.

### Source excerpt

Image decoding can be a source of checkboarding and jank. What if there was a way to work around it without resorting to a cluster of horror hacks? Step right up and meet my new friend createImageBitmap!