Let's say I have a component:
<script lang="ts">
const players: Player[] = getPlayersFromSomewhere()
</script>
{#each players || [] as player}
<Player {player} />
{/each}
<script lang="ts">
export let player: Player;
async function doSomethingWithPlayer() {
// many lines of code here...
}
async function doSomethingElse() {
// many lines of code here...
}
async function doSomethingElseAgain() {
// many lines of code here...
}
// ... many functions here
</script>
player is used here with many buttons like:
<button on:click={doSomethingWithPlayer}>...</button>
<button on:click={doSomethingElse}>...</button>
<button on:click={doSomethingElseAgain}>...</button>
Is Svelte recreating the functions in Player.svelte
for each player or just one time using it for each player?
Shall I create the functions in Page.svelte
and pass them to Player.svelte
? Or is Svelte able to "hoist" them?
Svelte will automatically hoist functions that don't depend on local component state. From the docs:
Don't worry about the fact that we're redeclaring the foo function for every component instance — Svelte will hoist any functions that don't depend on local state out of the component definition.
You can see this behavior in the Svelte REPL. Consider the following component.
<script>
let name = 'world';
function changeName() {
name = name + 1;
}
function log() {
console.log("I'm independent")
}
</script>
<h1>Hello {name}!</h1>
<button on:click={changeName}>
Change
</button>
<button on:click={log}>
Log
</button>
changeName
depends on component state, but log
does not, so it is hoisted out of the component. You see the following in the compiled JS: there is only one log
function, but changeName
is created per instance.
function log() {
console.log("I'm independent");
}
function instance($$self, $$props, $$invalidate) {
let name = 'world';
function changeName() {
$$invalidate(0, name = name + 1);
}
return [name, changeName];
}
class App extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, {});
}
}