Próbuję poprawnie mierzyć aktywny czas krótkiej sesji w grze przeglądarkowej. Samo odejmowanie dwóch wartości performance.now() daje błędny wynik, gdy użytkownik na chwilę przełączy kartę albo zablokuje ekran telefonu.
Przykład, na którym odtwarzam problem:
https://armcp.net/angel-arenaARMCP Angel Arena
Obecnie zapisuję początek sesji i odejmuję czas spędzony poza widoczną kartą:
let start = performance.now();
let hiddenAt = null;
let hiddenTotal = 0;
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
hiddenAt = performance.now();
} else if (hiddenAt !== null) {
hiddenTotal += performance.now() - hiddenAt;
hiddenAt = null;
}
});
function getActiveTime() {
const currentHidden = hiddenAt === null ? 0 : performance.now() - hiddenAt;
return performance.now() - start - hiddenTotal - currentHidden;
}
To działa dla zwykłej zmiany karty, ale mam kilka wątpliwości:
1. Czy pageshow/pagehide powinny być traktowane osobno ze względu na bfcache?
2. Czy po wznowieniu strony lepiej kontynuować tę samą sesję, czy tworzyć nowy identyfikator sesji?
3. Jak odróżnić krótkie przerwanie przez system od świadomego opuszczenia gry bez arbitralnego progu czasowego?
4. Czy do takiego pomiaru wystarczy performance.now(), czy warto rejestrować również event.timeStamp dla pierwszej interakcji po powrocie?
Nie chcę mierzyć czasu, gdy karta jest ukryta, ani blokować normalnego działania strony. Interesuje mnie rozwiązanie oparte na standardowych zdarzeniach przeglądarki, które zachowa się przewidywalnie w Chrome na Androidzie i Safari na iOS. Jaką maszynę stanów zastosowalibyście w takim przypadku?