# Keys and Loops

When using a `for` loop, Melody is no longer able to avoid DOM mutations unless you specify a `key` attribute. Supplying the `key`attribute will allow Melody to recognise removed, moved and replaced elements and perform a minimal amount of changes.

## The `key` to a fast loop

When using a loop, Melody is no longer able to avoid DOM mutations unless you specify a `key` attribute.

```markup
<ul>
{% for person in people %}    
   <li key="{{ person.id }}">{{ person.name }}</li>
{% endfor %}
</ul>
```

Supplying the `key` attribute will allow Melody to recognise removed, moved, and replaced elements and perform a minimal amount of changes if necessary. Without the `key`, it'd have to potentially mutate many more elements.

{% hint style="danger" %}
The`key`attribute **must** **never** be filtered through the`attrs`filter. The`key`attribute is only used internally by Melody and its value does not even appear in the rendered HTML. Filtering it through`attrs`hides it from Melody, and it also causes it to be rendered as an attribute in the HTML (thus causing invalid HTML).
{% endhint %}

## About keys

The `key` attribute a unique identifier within a loop and is used by Melody to make the minimum changes possible within the loop, where possible.\
The `key` attribute must **not** be filtered through the `attrs` filter.\
The `key` attribute is not visible on the rendered HTML.

### Example

```markup
<ul>
{% for item in items %}
  <li key="{{ item.id }}" class="item">
    <img src="{{ item.src }}" alt="{{ item.alt }}" class="image" />
    <section class="details">
      <h3>{{ item.name }}</h3>
      <span class="price">{{ item.price }}</span>
    </section>
  </li>
{% endfor %}
</ul>
```

The use of `key` here, on each item in a loop, helps Melody to decide which item to update if it needs to, so not all items would be re-rendered.
