MST

星途 面试题库

面试题:Svelte虚拟化列表性能优化之动态高度处理

在Svelte的虚拟化列表场景下,若列表项高度不一致且是动态变化的,例如根据内容多少自适应高度,你将如何调整虚拟化列表的算法来确保渲染效率和准确性?请详细说明你的思路和可能涉及的关键代码片段。
14.9万 热度难度
前端开发Svelte

知识考点

AI 面试

面试题答案

一键面试

思路

  1. 测量高度:为了实现虚拟化,需要提前知道每个列表项的高度。由于高度是动态变化的,不能在初始化时就确定,因此可以在每个列表项渲染完成后测量其高度。在Svelte中,可以利用 bind:this 来获取DOM元素,进而测量高度。
  2. 高度缓存:测量后的高度需要缓存起来,以便虚拟化算法使用。可以使用一个数组来存储每个列表项的高度,数组的索引与列表项的索引相对应。
  3. 虚拟化算法调整:传统的虚拟化算法假设列表项高度固定,在此场景下需要修改为根据缓存的高度来计算可见列表项的范围。计算可见区域内的起始索引和结束索引时,需要累计每个列表项的高度。

关键代码片段

  1. 测量并缓存高度
<script>
    let itemHeights = [];
    function measureHeight(node) {
        if (node) {
            itemHeights.push(node.offsetHeight);
        }
    }
</script>

{#each data as item, index}
    <div bind:this={measureHeight}>
        {item.content}
    </div>
{/each}
  1. 调整虚拟化算法
<script>
    let visibleStart = 0;
    let visibleEnd = 0;
    let scrollTop = 0;

    function updateVisibleRange() {
        let totalHeight = 0;
        for (let i = 0; i < itemHeights.length; i++) {
            totalHeight += itemHeights[i];
            if (totalHeight >= scrollTop) {
                visibleStart = i;
                break;
            }
        }

        totalHeight = 0;
        for (let i = visibleStart; i < itemHeights.length; i++) {
            totalHeight += itemHeights[i];
            if (totalHeight >= scrollTop + viewportHeight) {
                visibleEnd = i;
                break;
            }
        }
    }
</script>

这里 viewportHeight 是视口高度,可以通过 window.innerHeight 获取,scrollTop 是滚动条位置,可以通过监听 scroll 事件获取。最后在渲染时,只渲染 visibleStartvisibleEnd 之间的列表项。

{#each data.slice(visibleStart, visibleEnd + 1) as item, index}
    <div>
        {item.content}
    </div>
{/each}