techniq / techniq/layerchart

tab freezes when an awaited value feeding a chart changes (async svelte + kit remote functions)

Open
#895 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1.3k
Forks
41
Avg merge
2d 19h
Merged PRs (30d)
16

Description

the bug

if i change the argument of an awaited SvelteKit remote-function query() inside a <svelte:boundary>, that renders a LayerChart chart inside - the tab hangs in what i can only assume to be a main-thread infinite js loop: cpu usage is at 100%, and the page stays frozen indefinitely. initial render (ssr and hydration) is (usually) fine; the freeze happens only when the awaited value re-resolves while the chart subtree is alive.

Filing here because LayerChart's derived graph is what the loop walks, but this might also be a svelte/sveltekit issue

repro

git clone https://github.com/teidesu/layerchart-async-repro && cd layerchart-async-repro
pnpm install
pnpm dev

if the tab didn't freeze right away - click the button once.

config: compilerOptions.experimental.async: true + kit.experimental.remoteFunctions: true.

versions

  • layerchart 2.1.0
  • svelte 5.56.8 (also reproduces on 5.56.4)
  • @sveltejs/kit 2.63
  • vite 8, Chrome 150, macOS
findings by claude fable 5

What I measured

Patched update_derived in svelte's client runtime with a counter: page load is ~13k derived updates, then a single click drives it past 2,000,000 — still climbing when I made the counter throw to free the tab. So it's an unbounded
derived re-evaluation storm, not a slow render.

Pausing the wedged renderer (debugger attached before the click) shows a ~780-frame stack cycling through:

get → update_derived → execute_derived → update_reaction → (layerchart derived) → get → ...

interleaved with nested $state-proxy ownKeys recursion through exclude_from_object (rest-props destructuring) in LayerChart's component chain (restProps = user_derived(() => exclude_from_object(props, [...])) etc. in the Chart component). The graph never settles — deriveds producing fresh object identities keep re-capturing into the async batch/fork during the boundary re-render.

Notes / controls

  • Replacing the remote query with a plain local async function of identical shape (same await in the boundary, same 100ms delay) does not reproduce. The remote-function query object is load-bearing.
  • Fresh mounts are always fine; only a re-resolve over a live chart subtree freezes. {#key data} around the chart does not help (the remount itself storms). motion: 'none' doesn't help either.
  • $effect.pending() is not required (this repro has none), but pages reading it freeze the same way.
  • Looks like a survivor of the async-mode round from last year: sveltejs/svelte#17883 (same symptom, closed), sveltejs/svelte#16548, #626, #630 — all marked fixed, but this variant reproduces on latest svelte.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Clone the linked layerchart-async-repro repository, run pnpm install and pnpm dev, then click the button to reproduce the freeze. Start by tracing the remote-function query re-resolution through the live chart subtree and the reported update_derived cycle; done means the chart can update after the click without an unbounded derived-update storm or a frozen tab.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
data-visualization, frontend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.