Repaint và Reflow - thợ sơn và kỹ sư xây dựng
Trong phát triển web hiện đại, việc tạo ra trải nghiệm người dùng mượt mà không chỉ phụ thuộc vào tốc độ tải trang mà còn nằm ở cách trình duyệt render (hiển thị) nội dung. Hai trong số các yếu tố kỹ thuật ảnh hưởng trực tiếp đến điều này là Repaint và Reflow.
Repaint - thợ sơn cần mẫn
Repaint xảy ra khi bạn thay đổi các thuộc tính ảnh hưởng đến giao diện trực quan nhưng không thay đổi bố cục. Ví dụ như màu nền, màu chữ, hay độ trong suốt... Ví dụ:
document.getElementById("btn").style.backgroundColor = "#ff0000";
Đoạn code này yêu cầu trình duyệt vẽ lại phần tử #btn, nhưng không cần tính toán lại toàn bộ layout.
Reflow - kỹ sư chỉn chu
Reflow là quá trình tính toán lại layout của toàn bộ hoặc một phần DOM, khi có thay đổi liên quan đến kích thước, vị trí, hoặc cấu trúc phần tử. Ví dụ:
document.getElementById("box").style.width = "100%";
Trình duyệt sẽ phải đo lại kích thước, xác định vị trí phần tử, sau đó mới tiến hành vẽ lại nếu cần. Reflow có thể ảnh hưởng lan rộng – từ phần tử cha đến các phần tử con và lân cận.
Mối quan hệ giữa Repaint và Reflow
- Reflow luôn kéo theo Repaint, nhưng Repaint không kéo theo Reflow.
- Chi phí hiệu suất của Reflow cao hơn đáng kể, đặc biệt trên thiết bị di động hoặc các trang có nhiều phần tử.
Khi nào trình duyệt kích hoạt Repaint/Reflow?
Trình duyệt sẽ kích hoạt các quá trình này khi:
- Thay đổi thuộc tính style (ví dụ: width, height, margin, color,…).
- Thêm/xoá phần tử trong DOM.
- Gọi các thuộc tính như offsetWidth, clientHeight, getBoundingClientRect() (chúng buộc trình duyệt tính toán layout hiện tại).
Tối ưu Repaint/Reflow
1. Tránh thao tác DOM liên tục
Ví dụ:
for (let i = 0; i < 1000; i++) {
document.getElementById("item").style.marginTop = i + "px";
}
Thay đổi style element nhiều lần dẫn đến reflow liên tục, ảnh hưởng đến UX và performance
2. Gộp thay đổi DOM lại với nhau
Sử dụng DocumentFragment khi chèn nhiều phần tử:
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const li = document.createElement("li");
li.textContent = `Item ${i}`;
fragment.appendChild(li);
}
document.getElementById("list").appendChild(fragment);
3. Sử dụng thuộc tính tối ưu hơn
Dùng transform hoặc opacity thay vì top, left, width để tránh reflow:
/* Tốt hơn cho hiệu suất trang web */
.animated-box {
transform: translateX(100px);
transition: transform 0.3s ease-in-out;
}
Công cụ kiểm tra Reflow và Repaint
*** Chrome DevTools** → Tab Performance
- Bật “Paint Flashing” để thấy vùng nào đang bị vẽ lại.
- Dùng Lighthouse để phân tích hiệu suất tổng thể.
Kết luận
Repaint và Reflow không chỉ là thuật ngữ kỹ thuật – chúng là yếu tố quyết định đến độ mượt, tốc độ và khả năng phản hồi của trang web. Việc tối ưu hai quá trình này sẽ giúp bạn nâng cao trải nghiệm người dùng, giảm thời gian tương tác và cải thiện hiệu suất tổng thể của ứng dụng.
All Rights Reserved