diff --git a/.changeset/nasty-falcons-ring.md b/.changeset/nasty-falcons-ring.md
new file mode 100644
index 000000000000..2d032d6fcf6f
--- /dev/null
+++ b/.changeset/nasty-falcons-ring.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+Prevent needless prop updates causing rerenders
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index 16a2889d61ad..613a67ec27ed 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -424,8 +424,11 @@ export function create_client({ target, session, base, trailing_slash }) {
};
for (let i = 0; i < filtered.length; i += 1) {
- const loaded = filtered[i].loaded;
- result.props[`props_${i}`] = loaded ? await loaded.props : null;
+ // Only set props if the node actually updated. This prevents needless rerenders.
+ if (!current.branch.some((node) => node === filtered[i])) {
+ const loaded = filtered[i].loaded;
+ result.props[`props_${i}`] = loaded ? await loaded.props : null;
+ }
}
const page_changed =
diff --git a/packages/kit/test/apps/basics/src/routes/load/layout-props/__layout.svelte b/packages/kit/test/apps/basics/src/routes/load/layout-props/__layout.svelte
new file mode 100644
index 000000000000..555061eead4b
--- /dev/null
+++ b/packages/kit/test/apps/basics/src/routes/load/layout-props/__layout.svelte
@@ -0,0 +1,26 @@
+
+
+
+
+
{count}
+
+
diff --git a/packages/kit/test/apps/basics/src/routes/load/layout-props/a.svelte b/packages/kit/test/apps/basics/src/routes/load/layout-props/a.svelte
new file mode 100644
index 000000000000..77fcba3ded86
--- /dev/null
+++ b/packages/kit/test/apps/basics/src/routes/load/layout-props/a.svelte
@@ -0,0 +1,2 @@
+On a
+to b
diff --git a/packages/kit/test/apps/basics/src/routes/load/layout-props/b.svelte b/packages/kit/test/apps/basics/src/routes/load/layout-props/b.svelte
new file mode 100644
index 000000000000..cb5b54229446
--- /dev/null
+++ b/packages/kit/test/apps/basics/src/routes/load/layout-props/b.svelte
@@ -0,0 +1,2 @@
+On b
+to a
diff --git a/packages/kit/test/apps/basics/test/client.test.js b/packages/kit/test/apps/basics/test/client.test.js
index 4046d0c7dacf..d100c66e2307 100644
--- a/packages/kit/test/apps/basics/test/client.test.js
+++ b/packages/kit/test/apps/basics/test/client.test.js
@@ -370,6 +370,15 @@ test.describe('Load', () => {
expect(await page.textContent('h1')).toBe("I didn't break!");
});
+ test("layout props don't cause rerender when unchanged", async ({ page, clicknav }) => {
+ await page.goto('/load/layout-props/a');
+ expect(await page.textContent('h1')).toBe('1');
+ await clicknav('[href="/load/layout-props/b"]');
+ expect(await page.textContent('h1')).toBe('1');
+ await page.click('button');
+ expect(await page.textContent('h1')).toBe('2');
+ });
+
if (process.env.DEV) {
test('using window.fetch causes a warning', async ({ page }) => {
const port = 5173;