Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/salty-hounds-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

perf: don't use tracing overeager during dev
1 change: 1 addition & 0 deletions packages/svelte/src/compiler/phases/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface Analysis {
/** @deprecated use `runes` from `state.js` instead */
runes: boolean;
immutable: boolean;
/** True if `$inspect.trace` is used */
tracing: boolean;
comments: AST.JSComment[];

Expand Down
6 changes: 4 additions & 2 deletions packages/svelte/src/internal/client/dev/tracing.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ function log_entry(signal, entry) {

if (dirty && signal.updated) {
for (const updated of signal.updated.values()) {
// eslint-disable-next-line no-console
console.log(updated.error);
if (updated.error) {
// eslint-disable-next-line no-console
console.log(updated.error);
}
}
}

Expand Down
20 changes: 18 additions & 2 deletions packages/svelte/src/internal/client/reactivity/batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,8 @@ function flush_effects() {
var was_updating_effect = is_updating_effect;
is_flushing = true;

var source_stacks = DEV ? new Set() : null;

try {
var flush_count = 0;
set_is_updating_effect(true);
Expand All @@ -633,8 +635,10 @@ function flush_effects() {
}

for (const update of updates.values()) {
// eslint-disable-next-line no-console
console.error(update.error);
if (update.error) {
// eslint-disable-next-line no-console
console.error(update.error);
}
}
}

Expand All @@ -643,12 +647,24 @@ function flush_effects() {

batch.process(queued_root_effects);
old_values.clear();

if (DEV) {
for (const source of batch.current.keys()) {
/** @type {Set<Source>} */ (source_stacks).add(source);
}
}
}
} finally {
is_flushing = false;
set_is_updating_effect(was_updating_effect);

last_scheduled_effect = null;

if (DEV) {
for (const source of /** @type {Set<Source>} */ (source_stacks)) {
source.updated = null;
}
}
}
}

Expand Down
26 changes: 17 additions & 9 deletions packages/svelte/src/internal/client/reactivity/sources.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,18 +188,26 @@ export function internal_set(source, value) {

if (DEV) {
if (tracing_mode_flag || active_effect !== null) {
const error = get_stack('updated at');
source.updated ??= new Map();

if (error !== null) {
source.updated ??= new Map();
let entry = source.updated.get(error.stack);
// For performance reasons, when not using $inspect.trace, we only start collecting stack traces
// after the same source has been updated more than 5 times in the same flush cycle.
const count = (source.updated.get('')?.count ?? 0) + 1;
source.updated.set('', { error: /** @type {any} */ (null), count });

if (!entry) {
entry = { error, count: 0 };
source.updated.set(error.stack, entry);
}
if (tracing_mode_flag || count > 5) {
const error = get_stack('updated at');

if (error !== null) {
let entry = source.updated.get(error.stack);

entry.count++;
if (!entry) {
entry = { error, count: 0 };
source.updated.set(error.stack, entry);
}

entry.count++;
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions packages/svelte/src/internal/flags/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/** True if experimental.async=true */
export let async_mode_flag = false;
/** True if we're not certain that we only have Svelte 5 code in the compilation */
export let legacy_mode_flag = false;
/** True if $inspect.trace is used */
export let tracing_mode_flag = false;

export function enable_async_mode_flag() {
Expand Down
Loading