repro (not for merge): idle Choreographer loop #58367 — empty playground pumps 60 doFrames/s - #58369
repro (not for merge): idle Choreographer loop #58367 — empty playground pumps 60 doFrames/s#58369capt-muji wants to merge 2 commits into
Conversation
…ync rate Four Android frame callbacks re-post themselves unconditionally on every doFrame, keeping the Choreographer armed at ~60fps while an app is foreground-idle with zero pending work (zero timers, zero animations, zero mount items, zero frames rendered): - JavaTimerManager.TimerFrameCallback (JavaTimerManager.kt) - FabricEventDispatcher.ScheduleDispatchFrameCallback - NativeAnimatedModule.animatedFrameCallback - FabricUIManager.DispatchUIFrameCallback Each now re-arms only when it has work, and re-arms lazily from its registration/posting path (createTimer / didDispatchMountItems / schedule). Measured on a stock RN 0.86.3 template app, idle foreground: ~600 doFrames/10s at 0.2-2ms each and 3.5-22.5% process CPU across API 28-36 devices; after this change: 0 doFrames, ~0% CPU, app fully functional.
… pumps 60 doFrames/s
|
Hi @capt-muji! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
Please don't publish if you do not want review. |
Summary
Reproducer for #58367 — not intended for merge (reproducer only, per the issue bot's request).
The playground renders nothing but an empty
View: on a physical Android device (verified API 28, 29 and 36), while this screen is foreground and idle, the framework keeps the main-thread Choreographer armed at ~60 doFrames/second with zero frames rendered and zero pending work — no timers, no animations, no mount items.Control: a plain native
Activityrendering an emptyViewreceives 0 doFrames at idle — the loop is entirely framework-driven. Full device matrix and root-cause analysis (four frame callbacks that re-arm unconditionally) are in #58367; the fix is in #58368.Test plan
adb shell atrace -t 10 -b 32768 view input -z -o /data/local/tmp/idle.atrace.gz && adb pull /data/local/tmp/idle.atrace.gz .grep -c "Choreographer#doFrame" idle.text→ ≈600 sections in 10 idle seconds, each containing only an empty "animation" stage — no layout, no drawadb shell dumpsys gfxinfo <rn_tester_pkg> reset && sleep 10 && adb shell dumpsys gfxinfo <rn_tester_pkg> | grep "Total frames rendered"→ 0Changelog:
[General] [Changed] - Add reproducer for #58367: RNTesterPlayground renders an empty View while the framework's idle Choreographer loop keeps firing ~60 doFrames/s (reproducer only, not intended for merge; fix in #58368)