From e067928d73f7b9f21338034eb4011bcf495e6f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Popek?= <78650133+Varixo@users.noreply.github.com> Date: Fri, 17 Jul 2026 17:23:13 +0200 Subject: [PATCH] fix computed signal serialization default --- .changeset/calm-computed-secrets.md | 5 +++ .../core/reactive-primitives/signal-api.ts | 2 +- .../src/core/shared/serdes/serdes.unit.ts | 38 ++++++++++++------- packages/qwik/src/core/shared/types.ts | 4 +- 4 files changed, 32 insertions(+), 17 deletions(-) create mode 100644 .changeset/calm-computed-secrets.md diff --git a/.changeset/calm-computed-secrets.md b/.changeset/calm-computed-secrets.md new file mode 100644 index 00000000000..56b9271eb82 --- /dev/null +++ b/.changeset/calm-computed-secrets.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: avoid serializing computed values by default. diff --git a/packages/qwik/src/core/reactive-primitives/signal-api.ts b/packages/qwik/src/core/reactive-primitives/signal-api.ts index f1ecc8a45d7..249c74f266b 100644 --- a/packages/qwik/src/core/reactive-primitives/signal-api.ts +++ b/packages/qwik/src/core/reactive-primitives/signal-api.ts @@ -29,7 +29,7 @@ export const createComputedSignal = ( return new ComputedSignalImpl( options?.container || null, qrl as ComputeQRL, - getComputedSignalFlags(options?.serializationStrategy || 'always'), + getComputedSignalFlags(options?.serializationStrategy || 'never'), options ); }; diff --git a/packages/qwik/src/core/shared/serdes/serdes.unit.ts b/packages/qwik/src/core/shared/serdes/serdes.unit.ts index e9bac17e54f..7482e589574 100644 --- a/packages/qwik/src/core/shared/serdes/serdes.unit.ts +++ b/packages/qwik/src/core/shared/serdes/serdes.unit.ts @@ -607,35 +607,40 @@ describe('shared-serialization', () => { const clean = createComputed$(() => foo.value + 2, { serializationStrategy: 'always' }); const never = createComputed$(() => foo.value + 3, { serializationStrategy: 'never' }); const always = createComputed$(() => foo.value + 4, { serializationStrategy: 'always' }); + const defaultStrategy = createComputed$(() => foo.value + 5); const noSer = createComputed$(() => noSerialize({ foo })); // note that this won't subscribe because we're not setting up the context // do not read `dirty` to keep it dirty expect(clean.value).toBe(2); expect(never.value).toBe(3); expect(always.value).toBe(4); - const objs = await serialize(dirty, clean, never, always, noSer); + expect(defaultStrategy.value).toBe(5); + const objs = await serialize(dirty, clean, never, always, defaultStrategy, noSer); expect(_dumpState(objs)).toMatchInlineSnapshot(` " 0 ComputedSignal [ - QRL "6#1#-2" + QRL "7#1#-2" ] 1 ComputedSignal [ - QRL "6#2#-3" + QRL "7#2#-3" Constant undefined {number} 2 ] 2 ComputedSignal [ - QRL "6#3#-4" + QRL "7#3#-4" ] 3 ComputedSignal [ - QRL "6#4#-5" + QRL "7#4#-5" Constant undefined {number} 4 ] 4 ComputedSignal [ - QRL "6#5#-6" + QRL "7#5#-6" ] - 5 Signal [ + 5 ComputedSignal [ + QRL "7#6#-7" + ] + 6 Signal [ {number} 0 EffectSubscriptionNoData [ RootRef 1 @@ -649,14 +654,19 @@ describe('shared-serialization', () => { RootRef 3 Constant '.' ] + EffectSubscriptionNoData [ + RootRef 4 + Constant '.' + ] ] - 6 {string} "mock-chunk" - 7 {string} "describe_describe_it_dirty_createComputed_ahnh0V4rf6g" - 8 {string} "describe_describe_it_clean_createComputed_0ZTfN4iJ0tg" - 9 {string} "describe_describe_it_never_createComputed_1HbLed7JXyo" - 10 {string} "describe_describe_it_always_createComputed_4nMmgHlUOog" - 11 {string} "describe_describe_it_noSer_createComputed_pXwl00hYYQQ" - (454 chars)" + 7 {string} "mock-chunk" + 8 {string} "describe_describe_it_dirty_createComputed_ahnh0V4rf6g" + 9 {string} "describe_describe_it_clean_createComputed_0ZTfN4iJ0tg" + 10 {string} "describe_describe_it_never_createComputed_1HbLed7JXyo" + 11 {string} "describe_describe_it_always_createComputed_4nMmgHlUOog" + 12 {string} "describe_describe_it_defaultStrategy_createComputed_i9O7shypysA" + 13 {string} "describe_describe_it_noSer_createComputed_pXwl00hYYQQ" + (552 chars)" `); }); it(title(TypeIds.SerializerSignal), async () => { diff --git a/packages/qwik/src/core/shared/types.ts b/packages/qwik/src/core/shared/types.ts index ab2ec6baffe..5b1962fa1d5 100644 --- a/packages/qwik/src/core/shared/types.ts +++ b/packages/qwik/src/core/shared/types.ts @@ -142,8 +142,8 @@ export interface QContainerElement extends Element { * value during SSR. * * - `never`: The value is never serialized. When the component is resumed, the value will be - * recalculated when it is first read. - * - `always`: The value is always serialized. This is the default. + * recalculated when it is first read. This is the default for computed signals. + * - `always`: The value is always serialized. This is the default for async signals. * * **IMPORTANT**: When you use `never`, your serialized HTML is smaller, but the recalculation will * trigger subscriptions, meaning that other signals using this signal will recalculate, even if