Skip to content

Commit

Permalink
fix: yield main thread before navigating (#12225)
Browse files Browse the repository at this point in the history
* fix: yield main thread before navigating

* Update packages/kit/src/runtime/client/client.js

* gah

* add test

* bigger magic number
  • Loading branch information
Rich-Harris authored May 17, 2024
1 parent b10bd44 commit 71015f0
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/pink-tigers-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

fix: yield main thread before navigating
12 changes: 11 additions & 1 deletion packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -2027,7 +2027,7 @@ function _start_router() {
}

/** @param {MouseEvent} event */
container.addEventListener('click', (event) => {
container.addEventListener('click', async (event) => {
// Adapted from https://github.com/visionmedia/page.js
// MIT license https://github.com/visionmedia/page.js#license
if (event.button || event.which !== 1) return;
Expand Down Expand Up @@ -2120,6 +2120,16 @@ function _start_router() {

event.preventDefault();

// allow the browser to repaint before navigating —
// this prevents INP scores being penalised
await new Promise((fulfil) => {
requestAnimationFrame(() => {
setTimeout(fulfil, 0);
});

setTimeout(fulfil, 100); // fallback for edge case where rAF doesn't fire because e.g. tab was backgrounded
});

navigate({
type: 'link',
url,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<a href="/routing/a">a</a>
<a href="/routing/ambiguous/ok.json" rel="external">ok</a>
<a href="/routing/next-paint">next-paint</a>
<a href="/routing/symlink-from">symlinked</a>
<a href="http://localhost:{$page.url.searchParams.get('port')}">elsewhere</a>
<a href="/static.json">static.json</a>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>next-paint</p>
29 changes: 29 additions & 0 deletions packages/kit/test/apps/basics/test/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1163,3 +1163,32 @@ test.describe('reroute', () => {
expect(await page.textContent('h1')).toContain('Full Navigation');
});
});

test.describe('INP', () => {
test('does not block next paint', async ({ page }) => {
// Thanks to https://publishing-project.rivendellweb.net/measuring-performance-tasks-with-playwright/#interaction-to-next-paint-inp
async function measureInteractionToPaint(selector) {
return page.evaluate(async (selector) => {
return new Promise((resolve) => {
const startTime = performance.now();
document.querySelector(selector).click();
requestAnimationFrame(() => {
const endTime = performance.now();
resolve(endTime - startTime);
});
});
}, selector);
}

await page.goto('/routing');

const client = await page.context().newCDPSession(page);
await client.send('Emulation.setCPUThrottlingRate', { rate: 100 });

const time = await measureInteractionToPaint('a[href="/routing/next-paint"]');

// we may need to tweak this number, and the `rate` above,
// depending on if this proves flaky
expect(time).toBeLessThan(400);
});
});

0 comments on commit 71015f0

Please sign in to comment.