Skip to content

Reuse DOM nodes / state across components? #1411

@nolanlawson

Description

@nolanlawson

This may not have an easy solution, but I wanted to document this tricky performance problem I ran into.

If you follow the sapper-template, you end up with multiple pages each containing a Layout and a Nav. When you navigate from one page to another, this Nav remains ~99% the same, and yet Svelte will tear down the entire DOM tree and recreate the DOM structure from scratch.

This has a few undesirable performance impacts:

  1. A delay caused by destroying and re-creating largely identical DOM nodes
  2. Style and layout must be recalculated, even though the DOM structures are largely the same
  3. For "perceived performance," it would be nice to run animations on the Nav during this transition, but it's impossible to animate the old DOM nodes since they get destroyed. So you instead have to wait for the new DOM nodes to be inserted and then animate those, which leads to a slight delay between the click and the start of the animation. (See the animations in pinafore.social when clicking on the nav buttons for an example.)

I'm not sure there's an easy solution to this, but maybe something like the following would be possible?

<!-- Nav.html -->
<script>
  const nodePool = []
  export default {
    recycleNode (node) {
      nodePool.push(node)
    },
    updateNode (node) (
      // any work to update the component with the existing node
    },
    getRecycledNode () {
      return nodePool.pop() // null/undefined indicates Svelte should create a new one
    }
  }
</script>

See this infinite list implementation for where I got some of these ideas about recycling. It's also possible it would be better to recycle the components themselves (including state) rather than just the DOM nodes, but this is just a sketch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions