forked from OpenNeo/impress
Fix bug where changing tabs would *always* pause the outfit animations
We have a feature to check the movie's FPS, and pause it if it gets too low, as a guard against especially low-performance movies. But this was triggering in an *expected* case, where browsers intentionally throttle interval events when a page is in the background (e.g. you switch to another tab). Now, our rendering is aware of page visibility: when the page is hidden, don't bother rendering, and keep resetting the FPS counter state, so that we can pick up with a fresh FPS counter when the page comes back.
This commit is contained in:
parent
cedceeaf3c
commit
60e9130891
1 changed files with 24 additions and 13 deletions
|
@ -196,26 +196,37 @@ function OutfitMovieLayer({
|
||||||
let lastFpsLoggedAtInMs = performance.now();
|
let lastFpsLoggedAtInMs = performance.now();
|
||||||
let numFramesSinceLastLogged = 0;
|
let numFramesSinceLastLogged = 0;
|
||||||
const intervalId = setInterval(() => {
|
const intervalId = setInterval(() => {
|
||||||
updateStage();
|
|
||||||
|
|
||||||
numFramesSinceLastLogged++;
|
|
||||||
|
|
||||||
const now = performance.now();
|
const now = performance.now();
|
||||||
const timeSinceLastFpsLoggedAtInMs = now - lastFpsLoggedAtInMs;
|
const timeSinceLastFpsLoggedAtInMs = now - lastFpsLoggedAtInMs;
|
||||||
const timeSinceLastFpsLoggedAtInSec = timeSinceLastFpsLoggedAtInMs / 1000;
|
const timeSinceLastFpsLoggedAtInSec = timeSinceLastFpsLoggedAtInMs / 1000;
|
||||||
|
|
||||||
if (timeSinceLastFpsLoggedAtInSec > 2) {
|
|
||||||
const fps = numFramesSinceLastLogged / timeSinceLastFpsLoggedAtInSec;
|
const fps = numFramesSinceLastLogged / timeSinceLastFpsLoggedAtInSec;
|
||||||
const roundedFps = Math.round(fps * 100) / 100;
|
const roundedFps = Math.round(fps * 100) / 100;
|
||||||
|
|
||||||
|
// If the page is visible, render the next frame, and track that we did.
|
||||||
|
// And if it's been 2 seconds since the last time we logged the FPS,
|
||||||
|
// compute and log the FPS during those two seconds. (Checking the page
|
||||||
|
// visibility is both an optimization to avoid rendering the movie, but
|
||||||
|
// also makes "low FPS" tracking more accurate: browsers already throttle
|
||||||
|
// intervals when the page is hidden, so a low FPS is *expected*, and
|
||||||
|
// wouldn't indicate a performance problem like a low FPS normally would.)
|
||||||
|
if (!document.hidden) {
|
||||||
|
updateStage();
|
||||||
|
numFramesSinceLastLogged++;
|
||||||
|
|
||||||
|
if (timeSinceLastFpsLoggedAtInSec > 2) {
|
||||||
console.debug(
|
console.debug(
|
||||||
`[OutfitMovieLayer] FPS: ${roundedFps} (Target: ${targetFps}) (${libraryUrl})`,
|
`[OutfitMovieLayer] FPS: ${roundedFps} (Target: ${targetFps}) (${libraryUrl})`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (onLowFps && fps < 2) {
|
if (onLowFps && fps < 2) {
|
||||||
onLowFps(fps);
|
onLowFps(fps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastFpsLoggedAtInMs = now;
|
||||||
|
numFramesSinceLastLogged = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Otherwise, if the page is hidden, keep resetting the FPS tracker
|
||||||
|
// state, to be able to pick up counting fresh once we come back.
|
||||||
lastFpsLoggedAtInMs = now;
|
lastFpsLoggedAtInMs = now;
|
||||||
numFramesSinceLastLogged = 0;
|
numFramesSinceLastLogged = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue