Là một Frontend Engineer, bạn không cần phải giải các bài toán quy hoạch động phức tạp như Backend hay AI, nhưng việc nắm vững một số thuật toán và cấu trúc dữ liệu cụ thể sẽ giúp bạn xử lý UI mượt mà, tối ưu performance và giải quyết các bài toán logic phức tạp.
1. Tư duy về độ phức tạp (Big O)
Trong React, việc render lặp đi lặp lại rất thường xuyên. Một hàm xử lý dữ liệu chậm (O(n²)) chạy trong render body có thể "đóng băng" trình duyệt.
- Nên dùng:
SethoặcMapđể tra cứu (Lookup) với độ phức tạp O(1). - Tránh: Dùng
findhoặcfilterbên trong vòng lặpmapgây ra độ phức tạp O(n²).
Ví dụ thực tế: Normalized Data Store
Thay vì lưu mảng object, hãy lưu dạng Dictionary (Object/Map) để truy xuất nhanh.
// ❌ Kém: O(n) để tìm kiếm
const users = [{id: 1, name: 'A'}, {id: 2, name: 'B'}];
const user = users.find(u => u.id === 2);
// ✅ Tốt: O(1) để tìm kiếm
const usersMap = {
1: {id: 1, name: 'A'},
2: {id: 2, name: 'B'}
};
const user = usersMap[2];2. Tree Traversal (Duyệt Cây) & Recursion (Đệ Quy)
DOM là một cây, component tree cũng là một cây. Dữ liệu dạng cây rất phổ biến (Menu đa cấp, Comments, File Management).
Ứng dụng: Render Menu Đa Cấp
Sử dụng đệ quy để render component.
interface MenuItem {
title: string;
children?: MenuItem[];
}
const Menu = ({ items }: { items: MenuItem[] }) => (
<ul>
{items.map(item => (
<li key={item.title}>
{item.title}
{item.children && <Menu items={item.children} />}
</li>
))}
</ul>
);3. Debounce & Throttle (Kiểm soát tần suất)
Đây là hai kỹ thuật "phải biết" để xử lý sự kiện DOM dồn dập (scroll, resize, keypress).
Debounce (Chờ dứt điểm)
Dùng khi: Search box. Chỉ gọi API khi người dùng ngừng gõ sau 500ms.
function debounce<T extends (...args: any[]) => void>(func: T, wait: number) {
let timeout: NodeJS.Timeout;
return (...args: Parameters<T>) => {
clearTimeout(timeout);
timeout = setTimeout(() => func(...args), wait);
};
}Throttle (Bóp van)
Dùng khi: Scroll event, Resize. Chỉ thực thi hàm tối đa 1 lần mỗi 100ms, bất kể người dùng scroll nhanh thế nào.
4. Windowing / Virtualization (Danh sách ảo)
Khi hiển thị danh sách 10,000 item, trình duyệt sẽ bị crash nếu render tất cả DOM. Thuật toán: Chỉ render các item đang nằm trong khung nhìn (Viewport) + một khoảng đệm (buffer).
Key Concepts:
- Tính toán
startIndexvàendIndexdựa trênscrollTop. - Dùng
padding-topvàpadding-bottomgiả để thanh cuộn vẫn đúng kích thước thật.
5. Optimistic Updates (Cập nhật lạc quan)
Một kỹ thuật UX quan trọng. Cập nhật UI ngay lập tức trước khi server phản hồi. Nếu lỗi thì revert lại.
Cấu trúc dữ liệu:
- Thường dùng Stack (Ngăn xếp) để lưu trạng thái trước đó (history) để có thể "Undo" dễ dàng.
6. Diffing Algorithms (Thuật toán tìm sự khác biệt)
Hiểu cách React so sánh Virtual DOM giúp bạn viết key đúng cách.
- List Rendering: Luôn dùng
keyổn định (ID), không dùngindexnếu list có thể thay đổi thứ tự. Vì thuật toán diff của React so sánh theo thứ tự nếu không có key, việc sai khác sẽ dẫn đến Render lại toàn bộ list thừa thãi.
Thực hành tốt: Hãy rèn luyện thói quen nhìn code dưới góc độ "Dữ liệu này chạy qua bao nhiêu vòng lặp?" để tối ưu ngay từ khi viết logic.