From ccfd5f4006254d38d64fdff1925102943cf276cd Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Sat, 4 Jul 2026 17:42:31 -0500 Subject: [PATCH] Run no-op rAF workaround on Chrome Android closes https://github.com/TurboWarp/scratch-vm/issues/343 --- src/engine/tw-frame-loop.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/engine/tw-frame-loop.js b/src/engine/tw-frame-loop.js index bf2554b4..30632ec0 100644 --- a/src/engine/tw-frame-loop.js +++ b/src/engine/tw-frame-loop.js @@ -24,18 +24,28 @@ const animationFrameWrapper = callback => { /** * We've found that having an empty requestAnimationFrame loop running in the background improves frame - * pacing in many situations. See https://github.com/TurboWarp/scratch-vm/issues/257. + * pacing in many situations. * * Having an extra loop running increases CPU usage and battery usage even if it's not doing anything. * So, we only do this when the intended framerate is high enough that the user clearly wants smooth * motion, and only if the user is on a platform where we have evidence that this helps: - * - Chrome, Edge, and other Chromium on Windows + * + * Chrome on Windows: We think this is related to timer precision, where using rAF might be making Chrome + * give us a more precise timer. + * See https://github.com/TurboWarp/scratch-vm/issues/257. + * + * Chrome on Android. Chrome throttles frame production when it does not believe there is an animation + * happening. setInterval does not count as an animation, but rAF does. + * See https://github.com/TurboWarp/scratch-vm/issues/343. * * @param {number} framerate Intended framerate * @returns {boolean} true if no-op animation frame loop should be used */ const shouldUseNoopAnimationFrame = framerate => - framerate >= 30 && navigator.userAgent.includes('Chrome') && navigator.userAgent.includes('Windows'); + framerate >= 30 && navigator.userAgent.includes('Chrome') && ( + navigator.userAgent.includes('Windows') || + navigator.userAgent.includes('Android') + ); class FrameLoop { constructor (runtime) {