Understanding Virtual Scrolling in Frontend Development: Principles, Use Cases, and Implementation
This article explains the concept of virtual scrolling, why it is needed for performance in web pages, outlines two main implementation strategies, and provides detailed Vue‑based code examples—including Element‑Plus Infinite Scroll and a custom VirtualList class—to help developers apply the technique effectively.
Preface
Virtual scrolling is a common technique in the frontend field that appears in interviews, business requirements, performance optimization, and data presentation, and it underpins many UI components.
Application Scenarios of Virtual Scrolling
We use virtual scrolling to avoid page lag caused by rendering too many elements at once. Rendering a select with thousands of options can take nearly two seconds, blocking user interaction.
Typical scenarios include tables, lists, selects, and trees where only a subset of items is visible.
1. Dynamic Loading Based on Scroll Position
Element‑Plus Infinite Scroll is a directive plugin that loads more data when the scroll reaches the bottom.
<ul v-infinite-scroll="load" class="infinite-list" style="overflow: auto">
<li v-for="i in count" :key="i" class="infinite-list-item">{{ i }}</li>
</ul>The plugin stores its instance on the DOM element, uses MutationObserver for a fallback strategy, and throttles scroll handling.
2. Rendering Only the Visible Area
Only items within the viewport are rendered; off‑screen items are omitted, following a divide‑and‑conquer approach.
When the user scrolls, the visible content is updated by listening to the scroll event and adjusting padding.
<script setup lang="ts">
import { ref } from 'vue'
const paddingTop = ref(0)
const scroll = (e) => {
if (e.target.scrollTop % 200 < 20) {
paddingTop.value = e.target.scrollTop
}
}
</script>
<template>
<div class="warp" @scroll="scroll">
<div class="scroll-box" :style="`padding-top:${paddingTop}px`">
<div class="test-item">Test item</div>
...
</div>
</div>
</template>Virtual Scrolling Principle
The core idea is to listen to the scroll event, determine if the scroll has reached the bottom, and then dynamically load new data.
Implementation Details
The custom Virtual class encapsulates the logic, handling fixed and dynamic item heights, range calculation, padding computation, and scroll direction.
class Virtual {
constructor(param, callUpdate) { this.init(param, callUpdate) }
// ... methods: init, getRange, handleScroll, getIndexOffset, etc.
}Key methods include handleScroll (determines direction and triggers range updates), getIndexOffset (calculates offset for a given index using binary search for dynamic heights), and updateRange (updates the rendered range and padding).
Conclusion
Both approaches improve performance: dynamic loading reduces the amount of data processed, while rendering only visible items minimizes DOM updates. Choose the strategy that best fits your project’s needs.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.