π Problem Statement
The frontend/ leaderboard page fetches all users from leetcode-ranking-data and renders them in a single HTML table. Based on the project's growth trajectory (PVG COET has thousands of CS students), this will scale to 200-500 rows as more students register.
A single DOM with 500 <tr> elements (each with 6-8 cells including solved counts, badges, and ranking positions) causes:
- Initial render lag: 500 rows Γ 8 cells = 4,000 DOM nodes rendered at once
- Scroll jank: The browser must layout and paint all 4,000 nodes even when only 15 are visible
- Poor mobile experience: On a phone, a 500-row table is nearly unusable
Proposed Fix
Add client-side virtual scrolling + pagination in the frontend/ JavaScript:
// frontend/js/leaderboard.js
const PAGE_SIZE = 25;
let currentPage = 1;
let allUsers = [];
let filteredUsers = [];
function renderPage(users, page) {
const start = (page - 1) * PAGE_SIZE;
const end = start + PAGE_SIZE;
const pageUsers = users.slice(start, end);
const tbody = document.querySelector('#leaderboard tbody');
tbody.innerHTML = '';
pageUsers.forEach((user, i) => {
const rank = start + i + 1;
tbody.insertAdjacentHTML('beforeend', buildRow(user, rank));
});
updatePaginationControls(users.length, page);
}
function updatePaginationControls(totalUsers, currentPage) {
const totalPages = Math.ceil(totalUsers / PAGE_SIZE);
const pagination = document.getElementById('pagination');
pagination.innerHTML = `
<button onclick="goToPage(${currentPage - 1})" ${currentPage === 1 ? 'disabled' : ''}>β Prev</button>
<span>Page ${currentPage} of ${totalPages} (${totalUsers} students)</span>
<button onclick="goToPage(${currentPage + 1})" ${currentPage === totalPages ? 'disabled' : ''}>Next β</button>
`;
}
function goToPage(page) {
currentPage = Math.max(1, Math.min(page, Math.ceil(filteredUsers.length / PAGE_SIZE)));
renderPage(filteredUsers, currentPage);
window.scrollTo({ top: 0, behavior: 'smooth' });
}
Also add a search/filter bar above the table to filter by student name or username in real-time (since the full dataset is already loaded client-side, filtering is instant):
document.getElementById('search').addEventListener('input', (e) => {
const query = e.target.value.toLowerCase().trim();
filteredUsers = query
? allUsers.filter(u => u.name.toLowerCase().includes(query) || u.username.toLowerCase().includes(query))
: allUsers;
currentPage = 1;
renderPage(filteredUsers, currentPage);
});
Files to Modify
| File |
Change |
frontend/ (leaderboard JS) |
Add renderPage(), goToPage(), pagination controls, search filter |
frontend/ (leaderboard HTML) |
Add <input id="search"> and <div id="pagination"> |
frontend/ (leaderboard CSS) |
Style pagination controls and search bar |
Suggested labels: enhancement, frontend, performance, level: beginner
I would like to work on this. Could you please assign it to me?
π Problem Statement
The
frontend/leaderboard page fetches all users fromleetcode-ranking-dataand renders them in a single HTML table. Based on the project's growth trajectory (PVG COET has thousands of CS students), this will scale to 200-500 rows as more students register.A single DOM with 500
<tr>elements (each with 6-8 cells including solved counts, badges, and ranking positions) causes:Proposed Fix
Add client-side virtual scrolling + pagination in the
frontend/JavaScript:Also add a search/filter bar above the table to filter by student name or username in real-time (since the full dataset is already loaded client-side, filtering is instant):
Files to Modify
frontend/(leaderboard JS)renderPage(),goToPage(), pagination controls, search filterfrontend/(leaderboard HTML)<input id="search">and<div id="pagination">frontend/(leaderboard CSS)Suggested labels:
enhancement,frontend,performance,level: beginnerI would like to work on this. Could you please assign it to me?