| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
📲 Install BuildsAndroid
|
Sorry, something went wrong.
Sorry, something went wrong.
There was a problem hiding this comment.
Always a win! One optional nit if you want it 💯
Sorry, something went wrong.
Performance metrics 🚀
Baseline results on branch: mainStartup times
App size
Previous results on branch: no/perf-android-resource-id-exceptionsStartup times
App size
|
Sorry, something went wrong.
There was a problem hiding this comment.
very nice!
Sorry, something went wrong.
ViewUtils.getResourceId threw Resources.NotFoundException for views with no id or a generated id, and callers caught and discarded it. During a view-hierarchy snapshot and on every gesture this ran per view, so in Compose-heavy apps where most views have generated ids the SDK constructed an exception (and a native stack trace fill) per view on the main thread. Add a non-throwing resolveResourceId that returns null for unresolved ids and route the hot callers through it. The public getResourceId remains as a throwing wrapper for backward compatibility. Behavior (emitted identifiers and fallbacks) is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| Back | FazBrowse Home | New Git URL |
Resolves JAVA-586
📜 Description
ViewUtils.getResourceId used exception-driven control flow: it threw Resources.NotFoundException for views with View.NO_ID or a generated id, and every caller caught and discarded it. This ran per view during view-hierarchy snapshots and gesture target resolution, so in Compose-heavy apps — where most views have generated ids — the SDK constructed an exception (and a native fillInStackTrace stack walk) for nearly every view, on the main thread.
This adds a non-throwing ViewUtils.resolveResourceId(View) that returns null for unresolved ids, and routes the hot callers (ViewHierarchyEventProcessor.viewToNode, AndroidViewGestureTargetLocator.createUiElement, getResourceIdWithFallback) through it. The public getResourceId(...) throws Resources.NotFoundException stays as a thin wrapper for backward compatibility. Emitted identifiers and fallbacks are unchanged.
💡 Motivation and Context
Found while analyzing a customer-provided Perfetto trace: in a single view-hierarchy snapshot, 24 of 72 getResourceId calls threw Resources.NotFoundException on the main thread — pure overhead with no functional result.
💚 How did you test it?
Unit tests in ViewUtilsTest cover the new resolveResourceId (generated id, NO_ID, resource-not-found, and success) plus the existing getResourceId/fallback behavior; ViewHierarchyEventProcessorTest and AndroidViewGestureTargetLocatorTest pass unchanged.
On-device A/B on a Pixel 3 (Android 12) via ART method tracing, analyzed in Perfetto trace_processor, over 2048 calls on NO_ID views:
Exactly one exception (+ native stack fill) per unresolved view is removed; ~60% fewer executed methods and ~4.7× cheaper per unresolved view (the absolute ns is inflated by tracing; the call counts and ratio are the reliable signal).
📝 Checklist
🔮 Next steps
Follow-ups identified in the same trace but intentionally out of scope here: per-touch LinkedList→ArrayDeque in ViewUtils.findTarget, and background JSON serialization cost.