Lesson 5
Optimized List Rendering with Keyed `#each`
Introduction to Optimized List Rendering

Welcome back! In the previous lesson, you explored how to use the #if, else-if and else blocks in Svelte to manage control flow. These constructs allowed you to conditionally render content and iterate over lists, enhancing the interactivity and responsiveness of your applications. Today, we will build on that foundation by focusing on optimizing list rendering using keyed #each blocks. This lesson will help you understand how to efficiently update the DOM when items are added or removed from a list, ensuring your applications run smoothly and efficiently.

Non-Keyed `#each` Blocks

Non-keyed #each blocks in Svelte allow you to iterate over arrays and render lists dynamically. However, they come with limitations, particularly when it comes to updating the DOM. When you modify the value of an #each block, Svelte adds and removes DOM nodes at the end of the block and updates any values that have changed. This can lead to DOM node misalignment, where elements do not update as expected.

Consider the following example:

svelte
1<script lang="ts"> 2 import Thing from '$lib/Thing.svelte'; 3 4 let things = [ 5 { id: 1, name: 'apple' }, 6 { id: 2, name: 'banana' }, 7 { id: 3, name: 'carrot' }, 8 { id: 4, name: 'doughnut' }, 9 { id: 5, name: 'egg' } 10 ]; 11 12 function removeFirstThing() { 13 things.shift(); 14 } 15</script> 16 17<button onclick={removeFirstThing}>Remove first thing</button> 18 19{#each things as thing} 20 <Thing name={thing.name} /> 21{/each}

Thing.svelte

svelte
1<script lang="ts"> 2 const emojis = { 3 apple: '🍎', 4 banana: '🍌', 5 carrot: '🥕', 6 doughnut: '🍩', 7 egg: '🥚' 8 }; 9 10 export let name: string; 11 const emoji = emojis[name]; 12</script> 13 14<p>{emoji} = {name}</p>

In this example, when you click the "Remove first thing" button, the first item is removed from the things array. However, the DOM updates by removing the last component and updating the name value in the remaining DOM nodes, but not the emoji. This behavior can lead to inconsistencies in your UI.

Keyed `#each` Blocks: The Solution

Keyed #each blocks provide a solution to the limitations of non-keyed lists. By using unique keys for each item, Svelte can more efficiently update the DOM, ensuring that elements remain in sync with the underlying data. This approach minimizes unnecessary DOM operations and improves the performance of your application.

To implement a keyed #each block, you specify a unique key for each iteration. This key helps Svelte identify which items have changed, allowing it to update only the necessary DOM nodes.

Implementing Keyed `#each` Blocks in Svelte

Let's convert the previous non-keyed list to a keyed list. By using unique keys, we can ensure that the DOM updates correctly when items are added or removed.

svelte
1<script lang="ts"> 2 import Thing from '$lib/Thing.svelte'; 3 4 let keyedThings = [ 5 { id: 1, name: 'apple' }, 6 { id: 2, name: 'banana' }, 7 { id: 3, name: 'carrot' }, 8 { id: 4, name: 'doughnut' }, 9 { id: 5, name: 'egg' } 10 ]; 11 12 function removeFirstKeyedThing() { 13 keyedThings.shift(); 14 } 15</script> 16 17<button onclick={removeFirstKeyedThing}>Remove first keyed thing</button> 18 19{#each keyedThings as thing (thing.id)} 20 <Thing name={thing.name} /> 21{/each}

In the example above, when you click the "Remove first keyed thing" button, the first item is removed from the keyedThings array. Svelte updates the DOM by removing the corresponding component, leaving the rest of the list intact. This optimized behavior is achieved by using the unique id keys, which help Svelte track changes accurately.

Summary and Preparation for Practice

In this lesson, you learned how to optimize list rendering in Svelte using keyed #each blocks. By assigning unique keys to each item, you can ensure that the DOM updates efficiently, minimizing unnecessary operations and improving performance. This approach is particularly useful when working with dynamic lists that frequently change.

As you move forward, I encourage you to experiment with the example code and apply these concepts to your own projects. The upcoming practice exercises will reinforce your understanding and help you gain confidence in using keyed #each blocks in Svelte. Keep up the great work, and happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.