Estou pensando sobre os internos do Svelte para projetar adequadamente meu aplicativo para ter eficiência máxima (posso lidar com (dezenas?) de milhares de elementos para atualizar, então eficiência importa), notavelmente com como a reatividade é implementada. Então, usando este pequeno exemplo (no link você pode inspecionar o código JS na aba direita), implementei este código básico:
<script>
let foo = $state(42);
let bar = $state(52);
</script>
<div onclick={() => foo = foo + 2}>
Hello {foo}
</div>
<span onclick={() => bar = bar + 1}>
Hello {bar}
</span>
e obtenho o seguinte JavaScript compilado:
import 'svelte/internal/disclose-version';
import * as $ from 'svelte/internal/client';
var on_click = (_, foo) => $.set(foo, $.get(foo) + 2);
var on_click_1 = (__1, bar) => $.set(bar, $.get(bar) + 1);
var root = $.template(`<div> </div> <span> </span>`, 1);
export default function App($$anchor) {
let foo = $.state(42);
let bar = $.state(52);
var fragment = root();
var div = $.first_child(fragment);
div.__click = [on_click, foo];
var text = $.child(div);
$.reset(div);
var span = $.sibling(div, 2);
span.__click = [on_click_1, bar];
var text_1 = $.child(span);
$.reset(span);
$.template_effect(() => {
$.set_text(text, `Hello ${$.get(foo) ?? ''}`);
$.set_text(text_1, `Hello ${$.get(bar) ?? ''}`);
});
$.append($$anchor, fragment);
}
$.delegate(['click']);
O que parece importante é o código:
$.template_effect(() => {
$.set_text(text, `Hello ${$.get(foo) ?? ''}`);
$.set_text(text_1, `Hello ${$.get(bar) ?? ''}`);
});
Se meu entendimento de sinais estiver correto (eu segui esta ótima postagem para entender como os sinais são implementados), isso executará a função de retorno de chamada toda vez que um sinal mudar internamente... mas o problema é que se bar
mudar, o código $.set_text(text, `Hello ${$.get(foo) ?? ''}`);
também mudará, ou seja, mudar um sinal aciona operações O(n) onde n é o número de sinais... Com 2 elementos isso não é muito, mas se eu tiver dezenas de milhares de elementos, temo ter um tempo de atualização não desprezível.
Então eu tenho duas perguntas:
- Por que o Svelte não implementa um retorno de chamada por sinal para ter uma complexidade O(1) independente do número de sinais?
- Além disso, a mesma ideia é seguida por observable? Meu objetivo final é entender a complexidade das atualizações no
liveQuery
observable do Dexie.js.
Adicionar muitos efeitos individuais traz consigo sua própria sobrecarga significativa, então as atualizações são em lote. O Svelte também não em lote tudo no componente, por exemplo, se você adicionar um
#each
, então cada item obtém seu próprio efeito de modelo.O código fornecido também não causará nenhuma atualização redundante do DOM. O
set_text
código verificará se o valor realmente mudou e só interagirá com o conteúdo se realmente for necessário.Não posso comentar
Dexie.js
nada relacionado a observáveis. Por favor, faça perguntas separadas.