Reflow, Repaint, Layout Shift là gì? Tối ưu để tránh CLS cao trong Core Web Vitals

0 0 0

Người đăng: Vũ Nguyễn

Theo Viblo Asia

Vì sao bạn cần hiểu Reflow, Repaint và Layout Shift?

Khi xây dựng giao diện web, đặc biệt là các ứng dụng SPA hay các trang thương mại điện tử, bạn thường tối ưu hình ảnh, bundle nhỏ gọn, code chia nhỏ... Nhưng có một thứ tinh tế mà đôi khi chúng ta bỏ qua: trải nghiệm người dùng khi trang đang render.

Các hiện tượng như:

  • Giao diện bị “nhảy” khi ảnh vừa tải xong
  • Văn bản tự động bị đẩy xuống vì banner xuất hiện chậm
  • Người dùng định click thì nút trượt sang chỗ khác

Tất cả đều liên quan đến Reflow, Repaint, và Layout Shift. Và những điều này ảnh hưởng trực tiếp đến CLS – Cumulative Layout Shift, một chỉ số quan trọng trong Core Web Vitals của Google.


Reflow là gì?

Reflow (hay còn gọi là Layout) là quá trình trình duyệt tính toán lại kích thước và vị trí của các phần tử trên trang.

Reflow xảy ra khi:

  • Thêm, xóa hoặc thay đổi phần tử DOM
  • Thay đổi các thuộc tính CSS như width, font-size, position, display...
  • Thay đổi nội dung text
  • Kích thước cửa sổ trình duyệt thay đổi (resize)

Ví dụ:

element.style.width = "200px";

Thao tác này yêu cầu trình duyệt tính toán lại bố cục các phần tử liên quan – đó chính là Reflow.

Reflow rất tốn kém tài nguyên. Một thay đổi nhỏ có thể ảnh hưởng đến nhiều phần tử, đặc biệt trong layout phức tạp.


Repaint là gì?

Repaint là quá trình vẽ lại phần tử trên màn hình mà không cần tính toán lại layout.

Repaint xảy ra khi:

  • Thay đổi màu sắc (background-color, color)
  • Thay đổi visibility
  • Đổ bóng, viền, opacity…

Ví dụ:

element.style.backgroundColor = "blue";

Không cần tính lại bố cục, chỉ cần tô lại màu => Repaint.

So với Reflow, Repaint nhẹ hơn. Tuy nhiên nếu diễn ra liên tục (ví dụ animation không tối ưu), vẫn gây drop FPS và lag.


Layout Shift là gì?

Layout Shift xảy ra khi một phần tử bất ngờ thay đổi vị trí trên màn hình mà người dùng không tương tác gì cả. Khi điều này xảy ra quá nhiều hoặc quá trễ, trải nghiệm người dùng sẽ bị ảnh hưởng mạnh mẽ.

Đây chính là thứ mà CLS – Cumulative Layout Shift đo lường.

Một số nguyên nhân phổ biến:

  • Ảnh chưa có kích thước trước khi tải => ảnh “đẩy” phần tử khác xuống
  • Font hiển thị muộn => văn bản bị dịch chuyển (FOIT/FOUT)
  • Quảng cáo, popup render trễ => đẩy nội dung đi
  • Sử dụng JavaScript thêm nội dung bất ngờ vào DOM

Cách đo CLS (Cumulative Layout Shift)

CLS đo bằng công thức:

CLS = Tổng Layout Shift Score = Impact Fraction * Distance Fraction

Nói đơn giản:

  • Impact Fraction: bao nhiêu phần trăm vùng màn hình bị thay đổi
  • Distance Fraction: khoảng cách phần tử đã bị dịch chuyển bao nhiêu

Google khuyến nghị: CLS < 0.1 để đạt tiêu chuẩn tốt cho Core Web Vitals.


Cách giảm Reflow và Repaint không cần thiết

  1. Tránh thao tác DOM liên tục
// KHÔNG nên
for (let i = 0; i < 100; i++) { document.body.style.margin = `${i}px`;
} // NÊN
document.body.style.margin = "100px";
  1. Dùng class thay vì thay đổi style trực tiếp
element.classList.add("expanded"); // Gọn hơn, dễ maintain
  1. Đọc và ghi DOM riêng biệt
const height = element.offsetHeight; // Đọc layout
element.style.height = height + 10 + "px"; // Ghi layout // Gộp nhiều thay đổi vào cùng một frame
requestAnimationFrame(() => { // Thay đổi nhiều thứ tại đây
});

Cách tối ưu để tránh CLS cao

1. Luôn đặt chiều cao cố định cho ảnh

<img src="/logo.png" width="200" height="100" alt="Logo" />

Hoặc dùng CSS:

img { aspect-ratio: 2 / 1;
}

Next.js dùng next/image sẽ tự động xử lý việc này.


2. Tránh font nhảy – preload font sớm

<link rel="preload" href="/fonts/custom.woff2" as="font" type="font/woff2" crossorigin="anonymous" />

Hoặc dùng font-display: swap để tránh chặn render quá lâu.


3. Đặt chỗ sẵn cho component động (banner, quảng cáo...)

Nếu biết chiều cao của một thành phần sẽ xuất hiện muộn, hãy dành sẵn khoảng trống trong layout:

.banner-placeholder { min-height: 120px;
}

4. Tránh chèn DOM bất ngờ từ JS

Hạn chế setTimeout để render component động sau vài giây. Nếu cần animation, dùng opacity, transform để transition mượt mà mà không gây layout shift.


Tổng kết

Reflow, Repaint và Layout Shift là ba yếu tố quan trọng ảnh hưởng trực tiếp đến trải nghiệm người dùng – và đặc biệt là chỉ số CLS trong Core Web Vitals.

Việc hiểu cách trình duyệt hoạt động giúp bạn:

  • Tối ưu hiệu suất mà không cần chỉ nhìn vào Lighthouse
  • Tránh “trượt điểm” SEO vì lỗi UX
  • Làm chủ frontend một cách chuyên nghiệp hơn

Bình luận

Bài viết tương tự

- vừa được xem lúc

Một số lưu ý cải thiện performance khi làm việc với Rails

Khi làm việc với ruby on rails chắc hẳn chúng ta sẽ làm việc với active record rất nhiều. Tuy nhiên có nhiều điều có thể ta vẫn chưa thực sự hiểu, ví dụ như ActiveRecord execute SQL query như thế nào? Và cũng còn khá nhiều lập trình viên khác cũng không để ý tới điều này.

0 0 116

- vừa được xem lúc

3 cách tối ưu hóa hiệu suất Rails views

. Chào các bạn, chào các bạn. Trong bài viết này, chúng ta sẽ cùng nhau tìm hiểu một số kỹ thuật tối ưu hóa hiệu suất đơn giản và hiệu quả mà bạn có thể sử dụng ngay từ khi bắt đầu viết code.

0 0 70

- vừa được xem lúc

Kĩ thuật Memoize cải thiện performance

Kĩ thuật Memoize cải thiện performance. Memoize là một kĩ thuật cache lại giá trị trả về của các hàm dựa trên tham số truyền vào nó.

0 0 43

- vừa được xem lúc

MySQL Performance Tuning With Index

Lâu rồi không viết bài trên viblo nên để cái tiêu đề hơi công nghiệp =)) Xin chào các bạn, đợt rồi mình mới được làm vài task cải thiện thiện tốc độ truy vấn mysql nên hôm nay xin phép chia sẻ lại chú

0 0 89

- vừa được xem lúc

Làm thế nào để tối ưu những câu query trong Laravel ?

Đặt vấn đề. Nếu thấy ứng dụng của bạn đang chạy chậm , thì có một số nguyên nhân dẫn đến tình trạng này ví dụ như :.

0 0 2.1k

- vừa được xem lúc

Kiểm tra chịu tải của server với K6.io (Phần 1)

Lời mở đầu. Để có được một sản phẩm phần mềm tốt việc test performance là việc hết sức quan trọng để xác định độ ổn định của hệ thống, Để test được hắn một mình bạn không thể gửi request bằng cơm để t

0 0 206