From 852850c24f60c0e07667d67e12174573485731b9 Mon Sep 17 00:00:00 2001 From: Michal Mocny Date: Tue, 18 Jun 2024 15:33:21 -0400 Subject: [PATCH] Updates --- .../index.html | 32 ++++++-- sandbox/unload-event-timing/snippet.js | 76 +++++++++++++++++++ 2 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 sandbox/unload-event-timing/snippet.js diff --git a/sandbox/soft-nav-test-dom-edit-append-tree/index.html b/sandbox/soft-nav-test-dom-edit-append-tree/index.html index 1d2b6e1..07a63c7 100644 --- a/sandbox/soft-nav-test-dom-edit-append-tree/index.html +++ b/sandbox/soft-nav-test-dom-edit-append-tree/index.html @@ -6,6 +6,9 @@ +
+ +
Content
@@ -14,7 +17,15 @@ diff --git a/sandbox/unload-event-timing/snippet.js b/sandbox/unload-event-timing/snippet.js new file mode 100644 index 0000000..35b6bdb --- /dev/null +++ b/sandbox/unload-event-timing/snippet.js @@ -0,0 +1,76 @@ +/* + * Add this snippet to any page. + */ + +// Because unload freezes console.log, rely on a net-log tunnel +async function log(...messages) { + // Also log the messages to the console + console.log(...messages); + + try { + const response = await fetch('http://localhost:8080/log', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ messages }) + }); + } catch (error) { + console.error('log fetch() error:', error); + } +} + +function block(ms) { + const target = performance.now() + ms; + while (performance.now() < target); +} +function openNewTab() { + let newWindow = window.open('https://en.wikipedia.org', '_blank'); +} +function syncNavigate() { + window.location.href = 'https://en.wikipedia.org'; +} +function measureNextPaint() { + // The first rAF represents rendering start (BMF). + // BMF in Chrome will be prioritized after input, and so may get scheduled before visibilitychange event + // But, the visibilitychange event might get "flushed" before rAF. Let's see... + requestAnimationFrame(() => { + log('rAF1'); + // The second rAF represents a time which might correspond to the next vsync, which + // might be aligned with presentation time. It's not innacurate. + requestAnimationFrame(() => { + log('rAF2'); + }); + }); + // Alternatively, leverage element timing... +} +document.documentElement.addEventListener('pointerup', () => { + log('pointerup start'); + block(1000); + log('pointerup end'); + + // Run these after pointerup is done blocking, so you have time to add more input + measureNextPaint(); + for (let i = 0; i < 10; i++) { + setTimeout(() => { + log('timeout first?'); + block(50); + }, 0); + scheduler.postTask(() => { + log('user-blocking first?'); + block(50); + }, { priority: 'user-blocking' }); + } + + // openNewTab(); + syncNavigate(); +}); +document.documentElement.addEventListener('click', () => { + log('click start'); + block(1000); + log('click end'); +}); +window.addEventListener('visibilitychange', event => { + log('visibilitychange', performance.now() - event.timeStamp, 'ago') + block(1000); +});