前端大資料量優化:分頁與無限滾動實作指南
在前端專案中,如果資料量非常龐大,一次載入所有資料會導致頁面渲染緩慢、卡頓甚至瀏覽器崩潰。針對這個問題,最常用的兩種做法是 分頁 (Pagination) 與 無限滾動 (Infinite Scroll)。下面詳細說明這兩種方法,並提供 React 範例。
1️⃣ 分頁 (Pagination)
概念:
分頁就是把資料切成多個小頁,每次只載入一頁資料。使用者可以透過「上一頁 / 下一頁」或頁碼切換資料。
優點:
-
減少一次渲染的資料量。
-
使用者可以快速定位特定頁面的資料。
-
後端可以支援分批查詢,減少資料傳輸量。
React 範例:
import { useState, useEffect } from "react";
function PaginationExample() {
const [data, setData] = useState([]);
const [page, setPage] = useState(1);
const [totalPages, setTotalPages] = useState(1);
useEffect(() => {
async function fetchData() {
const res = await fetch(`/api/items?page=${page}&limit=10`);
const result = await res.json();
setData(result.items);
setTotalPages(result.totalPages);
}
fetchData();
}, [page]);
return (
<div>
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
<div>
<button
onClick={() => setPage(prev => Math.max(prev - 1, 1))}
disabled={page === 1}
>
上一頁
</button>
<span>第 {page} 頁 / 共 {totalPages} 頁</span>
<button
onClick={() => setPage(prev => Math.min(prev + 1, totalPages))}
disabled={page === totalPages}
>
下一頁
</button>
</div>
</div>
);
}
export default PaginationExample;
說明:
-
page狀態控制目前頁碼。 -
每次
page改變時,使用useEffect重新抓取該頁資料。 -
後端 API 支援
page與limit參數,返回該頁資料及總頁數。 -
減少一次載入過多資料,提高效能。
2️⃣ 無限滾動 (Infinite Scroll)
概念:
無限滾動是使用者滾動到頁面底部時,自動載入下一批資料,常見於社群媒體或文章列表。
優點:
-
不需要分頁按鈕,使用者體驗流暢。
-
適合資料量非常大、且不一定需要定位特定頁面。
React 範例:
import { useState, useEffect } from "react";
function InfiniteScrollExample() {
const [data, setData] = useState([]);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);
useEffect(() => {
async function fetchData() {
setLoading(true);
const res = await fetch(`/api/items?page=${page}&limit=10`);
const result = await res.json();
setData(prev => [...prev, ...result.items]);
setLoading(false);
}
fetchData();
}, [page]);
useEffect(() => {
function handleScroll() {
if (
window.innerHeight + window.scrollY >= document.body.offsetHeight - 100 &&
!loading
) {
setPage(prev => prev + 1);
}
}
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, [loading]);
return (
<div>
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
{loading && <p>載入中...</p>}
</div>
);
}
export default InfiniteScrollExample;
說明:
-
每次滾動到頁面底部時,
handleScroll觸發,增加page狀態。 -
useEffect監控page,抓取下一批資料並追加到原本列表。 -
loading防止滾動事件在資料尚未回來前重複觸發。
✅ 小結
| 方法 | 適用情境 | 優點 | 注意事項 |
|---|---|---|---|
| 分頁 | 使用者需要明確控制頁面,或查找特定資料 | 減少 DOM 數量,清楚頁碼 | UI 需要頁碼/上一頁下一頁按鈕 |
| 無限滾動 | 資料量大、使用者瀏覽模式是向下滑 | 使用者體驗流暢 | 需注意滾動事件效能、加載提示 |
建議根據專案需求選擇:若需要快速定位資料,使用 分頁;若資料量龐大且呈現類似社群列表,使用 無限滾動。