One Hundred Million Checkboxes is a highly optimized, real-time collaborative web application that allows users to interact with an enormous grid of 100 million checkboxes. This project demonstrates advanced techniques in web development, focusing on performance optimization, efficient data management, and real-time synchronization across multiple clients.
The application is built using a client-server architecture:
- Frontend: HTML, CSS, and JavaScript
- Backend: Node.js with Express.js
- Real-time Communication: Socket.IO
- Rendering 100 million checkboxes efficiently
- Real-time synchronization across multiple clients
- Optimized scrolling and viewport rendering
- Chunked data transfer between client and server
- Responsive design for various screen sizes
- Integrated chat functionality
To handle 100 million checkboxes efficiently, the application employs a virtual DOM approach combined with a windowing technique:
- Grid Calculation: The total grid size is calculated based on the viewport dimensions and checkbox size.
- Viewport Rendering: Only the checkboxes visible in the current viewport (plus a small buffer) are actually rendered in the DOM.
- Scroll Optimization: As the user scrolls, the visible checkboxes are dynamically updated, removing out-of-view checkboxes and adding newly visible ones.
function updateVisibleRows() {
const scrollTop = checkboxContainer.scrollTop;
visibleStartRow = Math.floor(scrollTop / TOTAL_CHECKBOX_SIZE) - VIEWPORT_BUFFER;
visibleStartRow = Math.max(0, visibleStartRow);
const viewportHeight = checkboxContainer.clientHeight;
const visibleRows = Math.ceil(viewportHeight / TOTAL_CHECKBOX_SIZE) + 2 * VIEWPORT_BUFFER;
visibleEndRow = Math.min(visibleStartRow + visibleRows, totalRows - 1);
renderVisibleCheckboxes();
}
To prevent browser freezing when rendering large numbers of checkboxes, the rendering process is chunked and uses requestAnimationFrame
:
function renderChunk() {
const chunkEndIndex = Math.min(currentIndex + RENDER_CHUNK_SIZE, endIndex);
for (let i = currentIndex; i < chunkEndIndex; i++) {
if (!document.getElementById(`cb-${i}`)) {
fragment.appendChild(createCheckboxElement(i));
}
}
checkboxGrid.appendChild(fragment);
currentIndex = chunkEndIndex;
if (currentIndex < endIndex) {
requestAnimationFrame(renderChunk);
}
}
The server uses a Set
to efficiently store the indices of checked boxes:
const checkedBoxes = new Set(); // Store checked box indices
This allows for O(1) time complexity for adding, removing, and checking the state of any checkbox.
To minimize data transfer and improve performance, the application uses a chunking strategy:
- The client requests data for visible chunks only.
- The server sends chunk data containing only the indices of checked boxes within that chunk.
socket.on('request checkbox chunk', (chunkIndex) => {
const start = chunkIndex * CHUNK_SIZE;
const end = Math.min((chunkIndex + 1) * CHUNK_SIZE, TOTAL_CHECKBOXES);
const chunkCheckedBoxes = Array.from(checkedBoxes).filter(index => index >= start && index < end);
socket.emit('checkbox chunk', { chunkIndex, checkedBoxes: chunkCheckedBoxes });
});
Socket.IO is used for real-time communication between the client and server:
- When a user checks or unchecks a box, an update is sent to the server.
- The server broadcasts this update to all connected clients.
- Clients update their local state and UI accordingly.
socket.on('checkbox update', ({ index, checked, totalChecked }) => {
if (checked) {
checkedBoxes.add(index);
} else {
checkedBoxes.delete(index);
}
updateCheckedCount(totalChecked);
const checkbox = document.getElementById(`cb-${index}`);
if (checkbox) {
checkbox.checked = checked;
}
});
- Efficient DOM Manipulation: Using
document.createDocumentFragment()
for batch DOM updates. - Debounced Scroll Handling: Using
requestAnimationFrame
to optimize scroll performance. - Lazy Loading: Only loading and rendering checkboxes as they become visible.
- Minimized Data Transfer: Sending only necessary data (checked box indices) between client and server.
The application includes a real-time chat feature, allowing users to communicate while interacting with the checkboxes. This demonstrates the versatility of the Socket.IO implementation.
The layout adapts to different screen sizes, ensuring a consistent experience across devices.
- Clone the repository
- Install dependencies:
npm install
- Start the server:
node server.js
- Access the application at
http://localhost:3000
One Hundred Million Checkboxes showcases advanced web development techniques, pushing the boundaries of what's possible in browser-based applications. By employing smart rendering strategies, efficient data structures, and optimized real-time communication, it achieves smooth performance even with an enormous number of interactive elements.
- Implement server-side persistence for checkbox states
- Add user authentication and personalized experiences
- Optimize for even larger numbers of checkboxes (e.g., 1 billion)
- Implement more advanced collaborative features
Created by Mohd Yahya Mahmodi