evidence-dev / evidence

Business intelligence as code: build fast, interactive data visualizations in pure SQL and markdown
https://evidence.dev
MIT License
4.47k stars 215 forks source link

Improve SSR reliability #2573

Open csjh opened 2 months ago

csjh commented 2 months ago

Problem is that, for the most part, the way we use and build components is incompatible with Svelte SSR. More specifically one part - reactive statements (ie $:).

For an ideal SSR experience, we should make it an antipattern to have any reactivity (that might happen during SSR; prop reactivity is an exception) happen through reactive statements, and instead use derived stores and event handlers.

Example from _DataTable:

$: finalColumnOrder = getFinalColumnOrder(
    $props.columns.map((d) => d.id),
    $props.priorityColumns
);
$: orderedColumns = [...$props.columns].sort(
    (a, b) => finalColumnOrder.indexOf(a.id) - finalColumnOrder.indexOf(b.id)
);

should become

const finalColumnOrder = derived(props, ($props) => getFinalColumnOrder(
    $props.columns.map((d) => d.id),
    $props.priorityColumns
));
const orderedColumns = derived([props, finalColumnOrder], ([$props, $finalColumnOrder]) => [...$props.columns].sort(
    (a, b) => $finalColumnOrder.indexOf(a.id) - $finalColumnOrder.indexOf(b.id)
));

or something to that effect

This is especially relevant in components that make use of <slot /> for composing their behaviour (DataTable is also the best example here, should also be the starting point for changes)

General translation guide:

can be expanded upon w/ exception cases when we start work on this

csjh commented 1 month ago

Not necessarily directly related, but we should also do a once-over of basic prop reactivity to pick up on things like ySet in #2574