javascripttypescriptvue.jsvuejs3

Keeping ref list of html elements of long v-for list causes performance problem


Task

I have a long list of elements in a v-for list. I want to call .focus() on the next element when pressing "arrow-down".

What I tried

<script setup>
import { ref } from 'vue'
const htmlElements = ref([])
const elements = Array.from({ length: 5_000 }, (_, i) => ({ text: 'Element'+ i }))
</script>

<template>
 <p v-for="el of elements" ref="htmlElements">{{ el.text }}</p>
</template>

Vue Playground

I have a long list of elements and I keep a list of the corresponding dom elements from the v-for loop to call focus on these elements (omitted for clarity).

Problem

ref="htmlElements" causes a massive performance problem. When accessing the dom elements of the list via the native childNodes property of the parent, I don't see a performance problem, but it does seem brittle (e.g., includes #text nodes I need to filter out).

Question

How can I get a performant and vue-compliant way to call focus on the child nodes?


Solution

  • OP achieved to have a good enough performance by using shallowRef, this is not the most optimal solution but good enough for a quick fix until a bigger revamp.