CLS hay Cumulative Layout Shift là chỉ số quan trọng trong bộ Core Web Vitals của Google, được thiết kế để đo lường độ ổn định trực quan của nội dung trên một trang. Nó tính toán tổng lượng dịch chuyển bố cục không mong muốn mà người dùng nhìn thấy trong suốt vòng đời của trang. Mục tiêu của CLS là đảm bảo trải nghiệm người dùng mượt mà và không bị gián đoạn.

Vậy Google tính điểm CLS như thế nào? Tại sao website của bạn lại bị CLS? Và tối ưu CLS cho website thế nào? Tất cả sẽ được tôi, Nguyễn Thanh Trường – Founder & CEO của SEO Center, giải đáp chi tiết qua bài viết dưới đây. 

Mục tiêu của bài viết này là giúp bạn nắm vững kiến thức về Cumulative Layout Shift, từ đó giúp bạn có thể tự tay tối ưu CLS cho website của mình đạt trạng thái tốt nhất.

Nội dung chính của bài viết: 

  • Cumulative Layout Shift (CLS) là chỉ số Core Web Vital đo lường độ ổn định trực quan của trang, đánh giá mức độ dịch chuyển không mong muốn của nội dung khi tải và tương tác, ảnh hưởng trực tiếp đến trải nghiệm người dùng và thứ hạng SEO của website.
  • Điểm CLS tốt phải dưới 0.1, và nguyên nhân chính gây CLS cao là do hình ảnh, video, quảng cáo hoặc nội dung động không có kích thước xác định hoặc được chèn bất ngờ, cùng với việc xử lý phông chữ web hoặc hoạt ảnh không đúng cách.
  • Để cải thiện CLS, bắt buộc phải khai báo rõ ràng chiều rộng và chiều cao cho tất cả hình ảnh, video, quảng cáo và nội dung nhúng bằng thuộc tính HTML hoặc CSS để dành sẵn không gian và ngăn nội dung bị xô đẩy.
  • Cần tránh chèn nội dung động vào các vị trí bất ngờ phía trên nội dung hiện có, tối ưu hóa xử lý phông chữ web bằng font-display: optional và sử dụng thuộc tính transform cho hoạt ảnh để không gây tính toán lại bố cục.
  • Thường xuyên sử dụng các công cụ như Google Search Console, PageSpeed Insights và Chrome DevTools để đo lường, chẩn đoán CLS và liên tục tối ưu hóa để đảm bảo trang web luôn ổn định và thân thiện với người dùng.

Nội dung bài học

Cumulative Layout Shift là gì?

Cumulative Layout Shift hay CLS là chỉ số đo lường mức độ ổn định của giao diện trang trong quá trình tải và tương tác của người dùng. CLS sẽ tính toán tổng lượng dịch chuyển bố cục không mong muốn, và cho Google biết trang của bạn có “đứng yên một chỗ” hay không khi người dùng tương tác hoặc khi các yếu tố khác đang tải. 

CLS là chỉ số đo lường mức độ ổn định của giao diện trang
CLS là chỉ số đo lường mức độ ổn định của giao diện trang

“Dịch chuyển bố cục” xảy ra khi một phần tử đang hiển thị trên trang (ví dụ: một đoạn văn bản, hình ảnh, nút bấm) thay đổi vị trí hoặc kích thước của nó, làm cho toàn bộ nội dung xung quanh cũng bị dịch chuyển theo. 

CLS chỉ quan tâm đến những dịch chuyển không mong muốn, tức là những dịch chuyển xảy ra mà không phải do người dùng chủ động tác động vào (ví dụ như nhấn nút để mở rộng nội dung). 

CLS cũng đo lường được có bao nhiêu nội dung nhìn thấy được đã dịch chuyển và khoảng cách mà những nội dung đó di chuyển xa bao nhiêu.

Ví dụ: Bạn đang đọc một bài báo trên trang tin tức về một sự kiện hot.

  • Tình huống 1 (Dịch chuyển bố cục không mong muốn): Bạn đang tập trung đọc đoạn văn cuối cùng của một câu chuyện, và chuẩn bị cuộn xuống để xem bình luận. Bỗng nhiên, một quảng cáo lớn (mà trang web không dành chỗ trước) xuất hiện ngay phía trên đoạn văn bạn đang đọc, đẩy toàn bộ nội dung bài viết và phần bình luận xuống dưới màn hình. Bạn bị mất dấu và phải mất công tìm lại chỗ mình đang đọc. Đây chính là một dịch chuyển bố cục không mong muốn và sẽ làm tăng điểm CLS của trang.
  • Tình huống 2 (Dịch chuyển bố cục không mong muốn khác): Bạn thấy một nút “Đăng ký nhận bản tin” rất hấp dẫn và đưa chuột đến định nhấp vào. Ngay khoảnh khắc ngón tay bạn chuẩn bị chạm vào chuột (hoặc chạm vào màn hình điện thoại), một hình ảnh động bất ngờ tải xong và “nhảy” vào giữa trang, khiến nút “Đăng ký” bị đẩy xuống và bạn vô tình nhấp vào một quảng cáo khác ở vị trí cũ của nút. Bạn cảm thấy bực bội vì nhấp nhầm và phải quay lại. Đây cũng là một ví dụ điển hình của CLS xấu.
  • Tình huống 3 (Dịch chuyển bố cục dự kiến): Bạn nhấp vào một nút “Xem thêm” để mở rộng nội dung một đoạn văn bản. Nội dung xuất hiện và đẩy phần còn lại của trang xuống. Vì bạn là người chủ động nhấp vào nút này, bạn mong đợi hành vi đó xảy ra. Đây được coi là một dịch chuyển bố cục dự kiến và sẽ không ảnh hưởng đến điểm CLS của trang, miễn là nó xảy ra trong vòng 500 mili giây sau hành động của bạn.

Tại sao CLS lại quan trọng?

Ảnh hưởng trực tiếp đến trải nghiệm người dùng (UX)

Như các ví dụ trên, khi nội dung liên tục nhảy nhót, người dùng sẽ cảm thấy cực kỳ khó chịu, mất tập trung khi đọc bài, hoặc thậm chí nhấp nhầm vào thứ không mong muốn (ví dụ: quảng cáo).

Nếu một trang liên tục bị dịch chuyển bố cục, người dùng sẽ cảm thấy trang đó không đáng tin cậy và có xu hướng rời đi nhanh hơn.

Là một yếu tố xếp hạng quan trọng của Google

Google rất quan tâm đến trải nghiệm người dùng trên các website. Vì vậy, CLS là một trong những chỉ số Core Web Vitals được Google sử dụng để đánh giá chất lượng trải nghiệm trang.

Điểm CLS kém cho thấy một trang không ổn định và không đáng tin cậy. Điều này sẽ khiến Google đánh giá thấp website của bạn.

Do đó, tối ưu hóa điểm CLS là một phần thiết yếu của chiến lược SEO (tối ưu hóa công cụ tìm kiếm) thành công. Cải thiện CLS giúp trang web của bạn thân thiện hơn với người dùng, đồng thời cũng giúp cải thiện thứ hạng trên công cụ tìm kiếm, từ đó thu hút được nhiều lượt truy cập hơn.

Google tính điểm CLS như thế nào?

Thang điểm CLS

Google đưa ra một “thước đo” để các chủ sở hữu trang web biết được điểm CLS của mình đang ở mức nào. Thang điểm CLS này như một hệ thống đèn giao thông gồm:

  • Tốt (Good): Điểm CLS dưới 0.1. Đây là mục tiêu mà mọi trang web nên hướng tới. Nếu trang của bạn đạt điểm này, có nghĩa là người dùng hầu như không gặp phải các dịch chuyển khó chịu.
  • Cần cải thiện (Needs improvement): Điểm CLS nằm trong khoảng từ 0.1 đến 0.25. Điều này cho thấy trang của bạn có xảy ra dịch chuyển, và bạn cần xem xét để tối ưu hóa.
  • Kém (Poor): Điểm CLS trên 0.25. Một điểm số như vậy có thể làm hỏng thứ hạng của trang web trên công cụ tìm kiếm của Google và chắc chắn sẽ gây khó chịu lớn cho người dùng.
Thang điểm CLS
Thang điểm CLS

Ví dụ: Giả sử bạn có một trang bán hàng trực tuyến.

  • Nếu điểm CLS của trang sản phẩm là 0.05, thì trang của bạn đang ở mức Tốt. Khách hàng sẽ có trải nghiệm mượt mà khi xem sản phẩm và nhấn nút “Mua hàng”.
  • Nếu điểm là 0.15, trang của bạn Cần cải thiện. Có thể một số quảng cáo hoặc hình ảnh tải chậm đang làm dịch chuyển nội dung, khiến khách hàng hơi khó chịu.
  • Nếu điểm là 0.30, thì trang của bạn bị coi là Kém. Khách hàng có thể cực kỳ bực bội khi các nút bấm cứ nhảy loạn xạ, và họ sẽ thoát trang ngay lập tức.

Google khuyến nghị rằng ít nhất 75% lượt tải trang của bạn phải có điểm CLS từ 0.1 trở xuống mới được coi là tốt. Điều quan trọng cần nhớ là điểm CLS có thể khác nhau tùy theo từng trang cụ thể và thậm chí khác nhau giữa các thiết bị (ví dụ: dịch chuyển trên màn hình di động có tác động lớn hơn đến trải nghiệm người dùng di động).

Cách tính điểm CLS

Điểm CLS là một giá trị không có đơn vị. Nó được Google tính toán dựa trên hai yếu tố chính khi một phần tử trên trang dịch chuyển:

Công thức tính điểm dịch chuyển bố cục (Layout Shift Score): Điểm dịch chuyển bố cục = Tỷ lệ tác động (Impact Fraction) x Tỷ lệ khoảng cách (Distance Fraction)

Hãy cùng mình phân tích từng thành phần:

a. Tỷ lệ tác động

Tỷ lệ tác động đo lường mức độ chiếm không gian của một phần tử không ổn định trên viewport. Nó tính toán tổng diện tích mà một phần tử chiếm dụng trong cả khung hình hiện tại và khung hình trước đó (trước khi nó dịch chuyển), chia cho tổng diện tích của viewport.

Ví dụ: Tưởng tượng bạn đang xem một trang web trên điện thoại.

  • Màn hình điện thoại của bạn là viewport (vùng hiển thị).
  • Bạn đang đọc một đoạn văn bản. Đoạn văn này chiếm 50% diện tích màn hình của bạn.
  • Bỗng nhiên, một hình ảnh lớn xuất hiện phía trên đoạn văn, đẩy toàn bộ đoạn văn bạn đang đọc dịch xuống 25% chiều cao màn hình.
  • Vậy, tổng diện tích mà đoạn văn này đã “chiếm” trong quá trình dịch chuyển (bao gồm cả vị trí cũ và vị trí mới) sẽ là 50% (vị trí ban đầu) + 25% (khoảng cách dịch chuyển) = 75% diện tích màn hình.
  • Khi đó, Tỷ lệ tác động sẽ là 0.75.
  • Nói cách khác, nó cho biết bao nhiêu phần trăm nội dung hiển thị của bạn bị ảnh hưởng bởi sự dịch chuyển.

b. Tỷ lệ khoảng cách (Distance Fraction)

Tỷ lệ khoảng cách đo lường khoảng cách lớn nhất mà phần tử không ổn định đã di chuyển so với kích thước lớn nhất của viewport (chiều rộng hoặc chiều cao).

Tiếp tục với ví dụ trên:

  • Đoạn văn bản của bạn đã bị đẩy xuống một khoảng bằng 25% chiều cao màn hình.
  • Vậy, Tỷ lệ khoảng cách trong trường hợp này sẽ là 0.25.
  • Nói cách khác, nó cho biết phần tử đã di chuyển bao xa.

Tính điểm CLS cuối cùng: Kết hợp hai yếu tố trên, điểm CLS cho lần dịch chuyển này sẽ là: 0.75 (Tỷ lệ tác động) x 0.25 (Tỷ lệ khoảng cách) = 0.1875.

Điểm CLS cuối cùng của một trang là tổng của chuỗi các “điểm dịch chuyển bố cục” lớn nhất xảy ra trong toàn bộ thời gian người dùng truy cập trang. Google đã thay đổi cách tính CLS để giới hạn “cửa sổ phiên” tối đa 1 giây khoảng trống giữa các dịch chuyển và tối đa 5 giây tổng thời lượng cửa sổ để làm cho chỉ số này công bằng hơn.

Khi nào CLS được tính và không được tính?

Không phải mọi sự dịch chuyển trên trang đều bị tính vào điểm CLS. Google phân biệt rõ ràng giữa các loại dịch chuyển để đảm bảo chỉ những trải nghiệm xấu mới bị phạt điểm.

Dịch chuyển bố cục không mong muốn

Đây là những dịch chuyển xảy ra mà không phải do người dùng chủ động tác động.

Ví dụ: bạn đang đọc bài, tự dưng một quảng cáo tải xong và đẩy nội dung bài viết xuống. Hoặc bạn chuẩn bị nhấp vào một nút, nhưng một hình ảnh tải lên và nút đó bị đẩy đi chỗ khác, khiến bạn nhấp nhầm vào quảng cáo.

Chỉ những dịch chuyển không mong muốn này mới ảnh hưởng đến điểm CLS của trang web bạn.

Dịch chuyển bố cục dự kiến

Đây là những dịch chuyển xảy ra do tương tác của người dùng, và người dùng mong đợi điều đó.

Ví dụ: Bạn nhấp vào nút “Xem thêm” để mở rộng nội dung, hoặc bạn nhấn nút để chuyển tab. Vì bạn là người chủ động thực hiện hành động, bạn sẽ không bất ngờ khi nội dung thay đổi.

Những dịch chuyển này không được tính vào điểm CLS, miễn là chúng xảy ra trong vòng 500 mili giây sau khi người dùng tương tác.

Tuy nhiên, cần lưu ý rằng các tương tác liên tục như cuộn trang hoặc di chuyển chuột không được coi là “đầu vào gần đây” và không kích hoạt khoảng thời gian 500ms này. Tức là, nếu bạn cuộn nhanh và nội dung tải lười (lazy-loaded) xuất hiện mà không có chỗ giữ chỗ, vẫn có thể gây ra CLS.

Điều này đã được Google xác nhận trong video dưới đây:

2 giai đoạn dịch chuyển

1. Dịch chuyển khi tải (Load Layout Shift): Xảy ra trong 5 giây đầu tiên sau khi trang bắt đầu tải. Đây là giai đoạn mà các tài nguyên ban đầu đang được tải và sắp xếp.

2. Dịch chuyển sau tải (Post-load Layout Shift): Xảy ra sau 5 giây đầu tiên. Các dịch chuyển này có thể do nội dung tải lười, quảng cáo hoặc các phần tử động khác xuất hiện sau quá trình tải ban đầu.

2 giai đoạn dịch chuyển này đã được nhắc đến trong podcast “071: Why do I have layout shift?” của Chrome for Developers

Lưu ý quan trọng về Viewport đối với CLS

CLS chỉ tính toán các dịch chuyển của các phần tử hiển thị trong viewport (tức là những gì người dùng đang nhìn thấy trên màn hình).

Nội dung nằm ngoài màn hình (off-screen), tức là bạn phải cuộn xuống mới thấy, nếu dịch chuyển thì không ảnh hưởng trực tiếp đến điểm CLS của bạn. Tuy nhiên, việc tối ưu hóa tất cả các phần tử trên trang vẫn quan trọng để có hiệu suất tổng thể tốt hơn.

Những nguyên nhân nào gây ra CLS?

1. Hình ảnh, video, iFrames hoặc quảng cáo không có kích thước 

Khi bạn chèn một hình ảnh, video, khung nhúng (iframe) hoặc quảng cáo vào trang mà không khai báo rõ ràng chiều rộng và chiều cao của chúng trong mã HTML hoặc CSS, trình duyệt sẽ không biết cần phải dành ra bao nhiêu không gian cho phần tử đó.

Điều gì xảy ra? Trang sẽ tải nội dung văn bản trước, rồi sau đó, khi hình ảnh hoặc quảng cáo tải xong, trình duyệt mới “đột nhiên” biết được kích thước thực của chúng. Lúc này, để chèn phần tử đó vào, nó sẽ phải đẩy toàn bộ nội dung xung quanh xuống phía dưới. Điều này giống như bạn đang đọc sách thì có người đột ngột đặt một vật nặng lên trang sách, khiến các trang bị xô lệch. 

Vấn đề này đặc biệt nghiêm trọng với các phần tử được tải lười (lazy-loaded), tức là chỉ tải khi người dùng cuộn đến gần chúng, vì chúng thường không được cấp không gian giữ chỗ trước.

Quảng cáo từ các mạng bên thứ ba cũng thường khó kiểm soát kích thước chính xác, và chúng có thể tải linh hoạt với nhiều kích cỡ khác nhau, khiến việc dự đoán không gian trở nên khó khăn hơn, và cũng gây ra CLS.

Các trường hợp gây ra CLS
Các trường hợp gây ra CLS

2. Nội dung được chèn động

Đây là các nội dung được thêm vào trang sau khi trang đã tải ban đầu, thường là không có sự tương tác trực tiếp của người dùng.

Khi các phần tử như biểu ngữ quảng cáo bất ngờ, cửa sổ bật lên (pop-up) yêu cầu đăng ký nhận tin, biểu mẫu liên hệ, bài đăng từ mạng xã hội (như Twitter/X), hoặc nội dung trong các danh sách cuộn vô hạn xuất hiện mà không có một khoảng trống giữ chỗ (placeholder) được dành trước, chúng sẽ “chiếm” không gian và đẩy nội dung hiện có trên trang xuống.

Người dùng đang tập trung vào một phần nội dung, và đột nhiên một phần tử mới xuất hiện, làm xáo trộn bố cục. Ví dụ, bạn đang định nhấp vào một nút, nhưng một pop-up quảng cáo hiện lên và đẩy nút đó đi chỗ khác, khiến bạn nhấp nhầm.

3. Phông chữ web

Phông chữ web cũng có thể là một nguyên nhân gây CLS mà ít người nghĩ tới. Khi một trang web sử dụng phông chữ tùy chỉnh (web font) mà chưa tải xong, trình duyệt sẽ có hai cách xử lý phổ biến:

  1. Flash of Invisible Text (FOIT – Vệt văn bản vô hình): Trình duyệt hiển thị một khoảng trống hoặc văn bản vô hình cho đến khi phông chữ tùy chỉnh tải xong. Sau đó, nó sẽ thay thế khoảng trống đó bằng văn bản có phông chữ đã tải.
  2. Flash of Unstyled Text (FOUT – Vệt văn bản không kiểu): Trình duyệt tạm thời hiển thị văn bản bằng một phông chữ hệ thống đã có sẵn. Sau khi phông chữ tùy chỉnh tải xong, nó sẽ “đột ngột” đổi phông chữ, thay thế phông chữ dự phòng bằng phông chữ web.

Cả hai trường hợp FOIT và FOUT đều có thể gây dịch chuyển bố cục do các phông chữ khác nhau thường chiếm không gian khác nhau về chiều dài dòng, chiều cao dòng và kích thước tổng thể. Khi phông chữ thay đổi, các dòng chữ có thể bị dãn ra, co lại, hoặc nhảy sang dòng mới, làm thay đổi toàn bộ bố cục của đoạn văn bản và các phần tử xung quanh.

Ví dụ: Bạn mở một trang blog có tiêu đề lớn. Ban đầu, tiêu đề hiện lên bằng một phông chữ mặc định của hệ thống (ví dụ: Arial). Bạn bắt đầu đọc phần giới thiệu. Bỗng dưng, phông chữ tùy chỉnh của trang tải xong, và tiêu đề “nhảy” sang một phông chữ khác (ví dụ: Inter). Do phông chữ mới chiếm nhiều không gian hơn, toàn bộ đoạn văn bản giới thiệu bên dưới bị đẩy xuống, làm bạn phải điều chỉnh lại vị trí đọc.

4. Hoạt ảnh không được triển khai đúng cách

Một số thuộc tính CSS, khi được thay đổi hoặc tạo hoạt ảnh, sẽ buộc trình duyệt phải tính toán lại toàn bộ bố cục trang (layout recalculation). Ví dụ như việc thay đổi box-shadow, box-sizing, hoặc các thuộc tính vị trí như top và left.

Khi một phần tử thay đổi kích thước hoặc vị trí bằng các thuộc tính này, ngay cả khi nó nằm trên một lớp riêng, nó vẫn có thể kích hoạt việc bố cục lại toàn bộ trang, làm dịch chuyển các phần tử khác.

Để tránh CLS do hoạt ảnh, bạn nên sử dụng thuộc tính transform của CSS (ví dụ: transform: scale() để thay đổi kích thước, transform: translate() để di chuyển). Các hoạt ảnh sử dụng transform sẽ không ảnh hưởng đến bố cục của các phần tử khác và do đó không được tính vào CLS.

5. Định nghĩa lưới hoặc lưới lấy kích thước từ phần tử con

CLS có thể xảy ra khi định nghĩa CSS cho bố cục lưới (grid layout) được tải muộn. Hoặc khi một bố cục lưới chỉ có thể xác định được kích thước cuối cùng của nó sau khi tất cả các phần tử con (nội dung bên trong lưới) đã được tải xong.

Nếu CSS của lưới tải sau hoặc các nội dung trong lưới tải lười biếng mà không có chỗ giữ chỗ, khi chúng xuất hiện, chúng sẽ “ép” lưới phải điều chỉnh kích thước, tạo ra một hiệu ứng “gợn sóng” (rippling effect) làm dịch chuyển nhiều phần tử khác trên trang.

Ví dụ: Bạn truy cập một website bán hàng online hiển thị các sản phẩm dưới dạng lưới (grid) gồm 3 cột. Lúc đầu, chỉ có tên sản phẩm và giá hiển thị. Sau đó, các hình ảnh sản phẩm chất lượng cao mới từ từ tải về. 

Nếu không có không gian được dành trước, khi hình ảnh tải xong, chúng sẽ lấp đầy ô lưới, khiến toàn bộ các sản phẩm khác trong lưới và nội dung bên dưới bị xô lệch để điều chỉnh lại bố cục.

Chào bạn,

Sau khi đã hiểu được CLS là gì và các nguyên nhân gây ra nó, bước tiếp theo và cũng vô cùng quan trọng là làm thế nào để đo lường CLS trên trang web của chúng ta. Việc đo lường chính xác sẽ giúp chúng ta biết được vấn đề nằm ở đâu và mức độ nghiêm trọng của nó, từ đó đưa ra giải pháp khắc phục phù hợp. Hãy cùng tìm hiểu phần “IV. Cách đo lường CLS” một cách cụ thể, chi tiết và dễ hiểu nhé.

Cải thiện điểm CLS như thế nào?

Cách 1. Xác định kích thước cho hình ảnh và video

Vấn đề: Khi bạn đưa hình ảnh hoặc video lên trang mà không chỉ định rõ ràng chiều rộng (width) và chiều cao (height) của chúng, trình duyệt sẽ không biết cần dành bao nhiêu không gian cho các phần tử này. 

Ban đầu, nó có thể chỉ là một “nút giữ chỗ” (placeholder node) với kích thước 0x0. Chỉ khi hình ảnh hoặc video được tải xuống hoàn chỉnh, trình duyệt mới biết kích thước thực của chúng và lúc đó mới phân bổ không gian, đẩy toàn bộ nội dung phía dưới dịch chuyển xuống để tạo chỗ. Điều này đặc biệt tệ với các phần tử được “tải lười” (lazy-loaded), tức là chúng chỉ được tải khi người dùng cuộn đến gần vị trí của chúng.

Xác định kích thước cho hình ảnh và video
Xác định kích thước cho hình ảnh và video

Giải pháp:

  • Luôn thêm thuộc tính width và height vào thẻ <img> và <video> trong mã HTML của bạn. Ví dụ: <img src=”anh-minh-hoa.jpg” width=”640″ height=”360″ alt=”Ảnh minh họa”>.
  • Các trình duyệt hiện đại rất thông minh. Khi bạn cung cấp width và height, chúng có thể tự động tính toán tỷ lệ khung hình (aspect ratio) của hình ảnh (tỷ lệ giữa chiều rộng và chiều cao) ngay lập tức. Nhờ đó, trình duyệt có thể dành đúng không gian cho hình ảnh ngay từ đầu, trước cả khi nó được tải xuống hoàn toàn.
  • Đối với hình ảnh “responsive” (thích ứng với nhiều kích thước màn hình) sử dụng thuộc tính srcset, hãy đảm bảo rằng tất cả các phiên bản hình ảnh được chỉ định trong srcset đều có cùng một tỷ lệ khung hình. Điều này giúp trình duyệt duy trì không gian đã dành trước một cách nhất quán.
  • Bạn cũng có thể sử dụng thuộc tính CSS aspect-ratio để dành không gian. Ví dụ: img { aspect-ratio: attr(width) / attr(height); }. Hoặc bạn có thể đặt một tỷ lệ cố định như aspect-ratio: 16 / 9;.
  • Khi sử dụng CSS để làm cho hình ảnh thích ứng với chiều rộng của khung chứa (ví dụ: width: 100%; height: auto;), trình duyệt vẫn sẽ tính toán chiều cao dựa trên tỷ lệ khung hình đã được xác định từ thuộc tính width và height trên thẻ <img>.

Cách 2. Đặt chiều rộng và chiều cao cho quảng cáo, nội dung nhúng và iFrames

Vấn đề: Tương tự như hình ảnh, các banner quảng cáo, nội dung nhúng từ bên thứ ba (như video YouTube, bản đồ Google Maps, bài đăng mạng xã hội) và các thẻ <iframe> (khung nội tuyến) thường được tải không đồng bộ. Nếu bạn không dành sẵn không gian cho chúng, khi chúng tải xong, chúng sẽ đẩy nội dung hiện có ra khỏi vị trí. 

Đặc biệt, quảng cáo là một trong những nguyên nhân lớn nhất gây ra CLS trên web. Các mạng quảng cáo thường có nhiều kích thước quảng cáo linh hoạt, và việc dự đoán kích thước chính xác có thể khó khăn.

Giải pháp:

  • Dành chỗ trước cho các phần tử này trong bố cục ban đầu của trang.
  • Sử dụng thuộc tính CSS min-height và min-width trên thẻ div chứa quảng cáo hoặc iframe. Điều này cho phép bạn đặt một kích thước tối thiểu, đảm bảo có đủ chỗ ngay cả khi nội dung tải muộn hơn. Ví dụ: <div id="vung-quang-cao" style="min-width: 300px; min-height: 250px;"></div>.
  • Kết hợp với CSS media queries để điều chỉnh các giá trị min-height/min-width cho phù hợp với các kích thước màn hình khác nhau (ví dụ: màn hình điện thoại, máy tính bảng, máy tính để bàn).
  • Nếu bạn không biết chính xác kích thước của quảng cáo hoặc nội dung nhúng (ví dụ: một số quảng cáo linh hoạt), hãy đặt một chỗ giữ chỗ tối thiểu. Dù có thể tạo ra một chút khoảng trống thừa, nhưng “một chút vẫn tốt hơn không có gì” để giảm thiểu đáng kể mức độ dịch chuyển. Bạn có thể tham khảo dữ liệu lịch sử về các kích thước quảng cáo phổ biến nhất để đặt chỗ giữ chỗ phù hợp.
  • Tránh dành chỗ bằng JavaScript vì việc này cũng có thể gây ra dịch chuyển khi script tải. Luôn ưu tiên dùng CSS để đặt trước không gian.
  • Nếu không có quảng cáo nào được trả về cho một vị trí đã dành trước, đừng xóa khoảng trống đó mà hãy hiển thị một chỗ giữ chỗ trống. Việc thu gọn không gian có thể gây ra dịch chuyển tương tự như việc chèn nội dung.
  • Đối với các nội dung nhúng có kích thước linh hoạt, hãy cố gắng chỉ sử dụng chúng ở những vị trí nằm dưới màn hình đầu tiên (below the fold) và tải chúng càng sớm càng tốt để người dùng không cuộn đến trước khi chúng thay đổi kích thước.

Cách 3. Xử lý đúng cách phông chữ web

Vấn đề: Khi trang của bạn sử dụng phông chữ web (web fonts), tức là các phông chữ được tải từ máy chủ thay vì có sẵn trên hệ thống của người dùng, có thể xảy ra hai hiện tượng gây dịch chuyển là FOIT và FOUT như tôi đã nói ở phần “Nguyên nhân gây ra CLS”

Giải pháp:

  • Sử dụng thuộc tính CSS font-display trong khai báo @font-face để kiểm soát cách phông chữ hiển thị.
    • font-display: optional là một giá trị được khuyến nghị để tránh dịch chuyển bố cục. Nó cho phép phông chữ web có một khoảng thời gian nhỏ để tải. Nếu phông chữ không tải kịp trong thời gian đó (thường là 3 giây), trình duyệt sẽ dùng phông chữ dự phòng và sẽ không thay đổi nữa, ngăn ngừa dịch chuyển. Phông chữ web sẽ chỉ được dùng cho các lần tải trang sau (nếu đã được lưu vào bộ nhớ đệm).
    • Tránh dùng font-display: swap nếu phông chữ của bạn tải chậm. Mặc dù nó hiển thị văn bản ngay lập tức bằng phông chữ dự phòng, nhưng sau đó nó sẽ luôn hoán đổi sang phông chữ web ngay khi tải xong, bất kể mất bao lâu, điều này có thể gây ra dịch chuyển lớn nếu phông chữ web khác biệt nhiều so với phông dự phòng.
  • Tải trước (preload) các phông chữ quan trọng bằng cách thêm <link rel="preload"> vào phần <head> của trang. Điều này báo hiệu cho trình duyệt tải phông chữ sớm nhất có thể, tăng khả năng nó sẽ sẵn sàng trước khi hiển thị nội dung, từ đó giảm thiểu dịch chuyển.
  • Chọn một phông chữ dự phòng (system font) có hình dáng và kích thước tương tự với phông chữ web của bạn. Việc này sẽ giảm thiểu sự khác biệt về bố cục khi trình duyệt chuyển đổi giữa hai phông chữ.
  • Bạn cũng có thể sử dụng các thuộc tính CSS mới như size-adjust để giảm sự khác biệt về kích thước giữa phông chữ dự phòng và phông chữ web.
  • Đối với các biểu tượng (icons), hãy ưu tiên sử dụng SVG thay vì icon fonts để tránh các vấn đề liên quan đến phông chữ và dịch chuyển.

Cách 4. Tránh chèn nội dung động phía trên nội dung hiện có

Vấn đề: Khi nội dung mới (như banner khuyến mãi, pop-up đăng ký, hoặc các bài đăng mạng xã hội được nhúng) được chèn động vào phía trên hoặc giữa nội dung mà người dùng đang xem, nó sẽ đẩy toàn bộ nội dung còn lại xuống dưới. Điều này phá vỡ luồng đọc hoặc duyệt của người dùng. 

Nội dung xuất hiện gần đầu màn hình hiển thị (viewport) thường gây ra dịch chuyển bố cục lớn hơn.

Giải pháp:

  • Không chèn nội dung động vào các vị trí bất ngờ phía trên nội dung hiện có.
  • Thay vào đó, hãy tải nội dung động ở phần sau của trang hoặc nằm ngoài màn hình hiển thị (off-screen), ví dụ như ở cuối trang hoặc ở một phần mà người dùng chưa cuộn tới.
  • Mời người dùng tương tác để kích hoạt việc tải nội dung mới. Ví dụ, thay vì tự động bật pop-up, hãy dùng nút “Tải thêm” (Load more), “Làm mới” (Refresh), hoặc khi người dùng cuộn đến một điểm nhất định, hiển thị thông báo “Cuộn lên đầu để xem nội dung mới”. Khi dịch chuyển xảy ra do tương tác của người dùng, chúng được coi là “dịch chuyển dự kiến” (expected layout shift) và không bị tính vào điểm CLS nếu xảy ra trong vòng 500 mili giây sau tương tác đó.
  • Nếu nội dung động thay thế một phần tử khác (ví dụ: một quảng cáo mới thay thế quảng cáo cũ), hãy sử dụng một vùng chứa có kích thước cố định hoặc một carousel (băng chuyền) để nội dung mới vừa khít vào đó mà không làm thay đổi bố cục xung quanh.
  • Nếu nội dung có thể mất hơn 500ms để tải (ví dụ: do yêu cầu mạng), hãy dành trước không gian dự kiến cho nó trong khoảng thời gian 500ms đó để tránh dịch chuyển không mong muốn.

Cách 5. Sử dụng thuộc tính transform cho hoạt ảnh

Vấn đề: Nhiều hoạt ảnh CSS không được triển khai đúng cách có thể gây ra dịch chuyển bố cục. Một số thuộc tính CSS như box-shadow, box-sizing, top, left khi được thay đổi trong hoạt ảnh sẽ buộc trình duyệt phải tính toán lại bố cục của trang (re-layout), dẫn đến dịch chuyển của các phần tử xung quanh.

Giải pháp:

  • Để tạo hoạt ảnh cho các phần tử trên trang mà không gây dịch chuyển bố cục, hãy sử dụng thuộc tính CSS transform.
  • Thay vì thay đổi thuộc tính height và width để điều chỉnh kích thước của một phần tử, hãy dùng transform: scale().
  • Để di chuyển các phần tử, thay vì thay đổi thuộc tính top, right, bottom, hoặc left, hãy dùng transform: translate().
  • Các hoạt ảnh sử dụng thuộc tính transform thường được thực hiện trên một “lớp riêng” (own layer) của phần tử, có nghĩa là chúng không ảnh hưởng đến bố cục của các phần tử khác trên trang và do đó không bị tính vào điểm CLS. Điều này giúp duy trì sự ổn định thị giác.

Cách 6. Đảm bảo trang đủ điều kiện cho bfcache (Bộ nhớ đệm tiến/lùi)

Vấn đề: Khi người dùng điều hướng trên trang web của bạn, ví dụ như nhấp vào một liên kết, sau đó sử dụng nút “Quay lại” (Back) hoặc “Tiến” (Forward) của trình duyệt, nếu trang không được tối ưu hóa, nó sẽ tải lại hoàn toàn. Điều này có nghĩa là tất cả các vấn đề gây dịch chuyển bố cục (như quảng cáo, hình ảnh tải muộn) mà người dùng đã trải qua trong lần tải trang đầu tiên sẽ lặp lại.

Giải pháp:

  • Đảm bảo các trang web của bạn đủ điều kiện sử dụng bộ nhớ đệm tiến/lùi (bfcache – back/forward cache).
  • bfcache là một tính năng của trình duyệt giúp lưu giữ các trang web trong bộ nhớ trong một khoảng thời gian ngắn sau khi người dùng rời khỏi trang. Khi người dùng quay lại các trang này (dùng nút “Back”/”Forward”), trang sẽ được khôi phục tức thì chính xác như khi họ rời đi, mà không cần tải lại và không có bất kỳ dịch chuyển bố cục nào.
  • Mặc dù bfcache không giải quyết được dịch chuyển bố cục trong lần tải trang ban đầu, nhưng nó giảm thiểu tác động của vấn đề này cho các lần điều hướng quay lại hoặc tiến sau đó, mang lại trải nghiệm mượt mà hơn cho người dùng.
  • Mặc định, tất cả các trình duyệt đều sử dụng bfcache, nhưng một số trang web có thể không đủ điều kiện do cách chúng được xây dựng (ví dụ: sử dụng sự kiện unload, hoặc có các kết nối mở không đóng). Bạn cần kiểm tra và khắc phục các vấn đề này để đảm bảo trang web của mình tận dụng được bfcache.

Các công cụ đo lường CLS

Google Chrome DevTools

Cách dùng: Bạn có thể mở Chrome DevTools bằng cách nhấn Ctrl + Shift + I (trên Windows) hoặc Cmd + Option + I (trên Mac), hoặc nhấp chuột phải vào trang và chọn “Kiểm tra” (Inspect).

Kiểm tra CLS bằng Google Chrome DevTools
Kiểm tra CLS bằng Google Chrome DevTools

Trong tab “Performance” (Hiệu suất), bạn có thể ghi lại quá trình tải trang. Sau khi ghi, bạn sẽ thấy kênh “Layout Shifts” (Thay đổi bố cục) hiển thị các thanh màu tím và các hình kim cương. Các thanh màu tím là nơi xảy ra các “cụm” dịch chuyển bố cục.

Khi bạn nhấp vào một hình kim cương, bạn sẽ thấy ảnh động của dịch chuyển đó trên trang và các thông tin chi tiết trong bảng “Summary” (Tóm tắt), bao gồm cả điểm dịch chuyển và các phần tử bị ảnh hưởng.

Tab “Experience” (Trải nghiệm) cũng sẽ làm nổi bật các vùng dịch chuyển trên trang bằng màu đỏ, giúp bạn dễ dàng hình dung.

Lighthouse

Lighthouse là một công cụ tự động của Google để kiểm tra chất lượng trang web, bao gồm hiệu suất, khả năng tiếp cận, SEO, v.v.. Nó thường cung cấp dữ liệu phòng thí nghiệm.

Bạn có thể chạy Lighthouse trực tiếp trong Chrome DevTools (tab “Lighthouse”) hoặc sử dụng công cụ Lighthouse online.

Điểm nổi bật của Lighthouse là sẽ hiển thị cho bạn những phần tử nào đang gây ra vấn đề CLS bằng cách cung cấp các ảnh chụp màn hình. Nó cũng đưa ra lời khuyên cụ thể để giảm CLS và cải thiện các chỉ số Core Web Vitals khác.

Lưu ý: Lighthouse thường chỉ ra các phần tử bị ảnh hưởng (chứ không phải nguyên nhân gốc rễ). Ví dụ, nếu một quảng cáo được chèn vào thanh bên, Lighthouse sẽ hiển thị tất cả các phần tử bên dưới quảng cáo đó bị dịch chuyển, nhưng không trực tiếp chỉ ra rằng chính quảng cáo đó là nguyên nhân. Bạn có thể cần tự mình điều tra thêm (ví dụ, bằng cách mở bảng network để xem các tài nguyên tải như thế nào).

PageSpeed Insights

PageSpeed Insights là một công cụ online phổ biến của Google, cho phép bạn phân tích hiệu suất của một URL cụ thể.

Điểm nổi bật: PageSpeed Insights hiển thị cả dữ liệu thực tế (Field Data) từ CrUX và dữ liệu phòng thí nghiệm (Lab Data) từ Lighthouse. Điều này giúp bạn có cái nhìn tổng quan về hiệu suất của trang trên cả thiết bị di động và máy tính.

Phần “Diagnostics” (Chẩn đoán) sẽ cung cấp chi tiết về các phần tử gây dịch chuyển, cùng với các khuyến nghị cụ thể.

Kiểm tra CLS bằng PageSpeed Insights
Kiểm tra CLS bằng PageSpeed Insights

Google Search Console

Google Search Console là một công cụ miễn phí của Google giúp chủ sở hữu trang web theo dõi hiệu suất của trang web trong kết quả tìm kiếm.

Điểm nổi bật của Google Search Console là cung cấp dữ liệu thực tế (Field Data) từ CrUX cho toàn bộ trang web của bạn. Nó phân loại các trang thành “Good” (Tốt), “Needs improvement” (Cần cải thiện), và “Poor” (Kém) dựa trên điểm CLS và các Core Web Vitals khác.

Lưu ý: Dữ liệu trong Search Console có độ trễ cập nhật (có thể mất vài tuần). Điều này có nghĩa là nếu bạn vừa sửa lỗi CLS, bạn sẽ phải chờ để thấy kết quả trong báo cáo này.

Kiểm tra CLS bằng Google Search Console
Kiểm tra CLS bằng Google Search Console

Chrome Web Vitals extension

Chrome Web Vitals extension là một tiện ích mở rộng nhỏ gọn cho trình duyệt Chrome.

Điểm nổi bật của Chrome Web Vitals extension là hiển thị điểm CLS (và các Core Web Vitals khác) trực tiếp trên trang web khi bạn duyệt và tương tác. Điều này cực kỳ hữu ích để gỡ lỗi tại chỗ và xem các dịch chuyển xảy ra ngay lập tức khi bạn cuộn hoặc nhấp.

Semrush’s Site Audit tool

Semrush’s Site Audit tool là một công cụ thuộc bộ Semrush, chuyên về kiểm tra SEO kỹ thuật.

Điểm nổi bật: Cho phép bạn kiểm tra điểm CLS cho nhiều trang cùng lúc (không chỉ một URL như PageSpeed Insights). Nó cung cấp các báo cáo chi tiết về hiệu suất và các khuyến nghị để khắc phục.

JavaScript (Performance Observer & Layout Instability API)

Performance Observer & Layout Instability API là cách dành cho các nhà phát triển nâng cao muốn thu thập dữ liệu CLS trực tiếp từ người dùng thực (Field Data) trên trang web của mình. Nó sử dụng các API trình duyệt mới như Layout Instability API.

Điểm nổi bật: Cho phép bạn tùy chỉnh việc thu thập dữ liệu và tích hợp vào hệ thống phân tích của riêng bạn. Thư viện web-vitals.js được khuyến nghị để đơn giản hóa quá trình này.

Cách dùng: Bạn có thể đăng ký một PerformanceObserver để lắng nghe các sự kiện layout-shift. Mỗi khi có dịch chuyển, trình duyệt sẽ báo cáo thông tin về nó, bao gồm giá trị dịch chuyển và liệu nó có phải là kết quả của một tương tác gần đây của người dùng hay không.

Lưu ý: CLS được đo lường trong toàn bộ vòng đời của trang, và bạn nên báo cáo CLS bất cứ khi nào trang chuyển sang chế độ nền (ví dụ: người dùng chuyển tab), sử dụng sự kiện visibilitychange. Tuy nhiên, cần lưu ý rằng API này không báo cáo các dịch chuyển xảy ra bên trong iFrame, mặc dù CrUX (dữ liệu thực tế) có tính đến chúng, điều này có thể gây ra sự khác biệt giữa dữ liệu lab và field.

Một số thông tin liên quan đến CLS

1. Cập nhật cách tính CLS của Google

Trước đây, cách Google tính điểm CLS có thể khá “khó nhằn” cho một số loại web, đặc biệt là những trang mà người dùng ở lại lâu hoặc những ứng dụng web chạy trên một trang (Single-Page Applications – SPAs). Để làm cho chỉ số này công bằng hơn, Google đã có những điều chỉnh quan trọng.

Thay đổi ngưỡng và phản ánh trên Search Console

Vào tháng 4 năm 2021, Google đã cập nhật ngưỡng tính CLS, giúp nhiều trang web dễ dàng đạt được điểm “Good” (Tốt) hơn. Những thay đổi này sau đó đã được cập nhật và hiển thị trong báo cáo Core Web Vitals của Google Search Console vào tháng 6 năm 2021. 

Điều này có nghĩa là, nếu trước đây trang của bạn có thể bị đánh giá là “Kém”, sau cập nhật bạn có thể thấy nó chuyển sang “Cần cải thiện” hoặc thậm chí là “Tốt” mà không cần phải thay đổi gì nhiều trên code.

Dưới đây là bài đăng của Glenn Gabe đăng trên Twitter cho thấy sự thay đổi sau khi Google cập nhật:

Giới hạn session window

CLS đo lường tổng điểm dịch chuyển bố cục lớn nhất trong suốt thời gian người dùng truy cập. Tuy nhiên, để tính toán công bằng hơn, Google đã giới hạn cái gọi là session window.

Một session window được định nghĩa là một chuỗi các dịch chuyển bố cục xảy ra liên tiếp nhanh chóng, với khoảng thời gian không quá 1 giây giữa các lần dịch chuyển và tổng thời lượng của chuỗi không quá 5 giây. 

Mục đích là để các dịch chuyển liên tục, kéo dài (ví dụ: trên một ứng dụng chạy liên tục) không bị “phạt” quá nặng.

2. CLS trong Lighthouse 10

Lighthouse là một công cụ kiểm tra tự động của Google, giúp các nhà phát triển đánh giá hiệu suất, khả năng truy cập, và các yếu tố khác của trang web.

  • Loại bỏ chỉ số Time To Interactive (TTI): Lighthouse 10 đã loại bỏ chỉ số Time To Interactive (TTI), là một chỉ số đo lường thời gian trang web trở nên tương tác hoàn toàn. TTI không phải là một trong các chỉ số Core Web Vitals mà Google sử dụng để xếp hạng trên công cụ tìm kiếm.
  • Tăng trọng số của CLS: Khi TTI bị loại bỏ, phần trọng số 10% của nó trong tổng điểm hiệu suất của Lighthouse đã được chuyển sang cho CLS. Điều này nâng tổng trọng số của CLS trong điểm hiệu suất tổng thể của Lighthouse lên 25%.

3. CLS trong iFrames

iFrame hay Inline Frame là một phần tử HTML cho phép bạn nhúng một tài liệu HTML khác vào trong tài liệu HTML hiện tại của mình. Ví dụ, bạn có thể nhúng một video YouTube, một bản đồ Google Maps, hoặc một quảng cáo từ một nhà cung cấp bên thứ ba vào trang web của mình bằng iFrame.

Sự khác biệt trong báo cáo CLS với iFrame: API (giao diện lập trình ứng dụng) mà các nhà phát triển sử dụng để đo lường CLS bằng JavaScript trên trang của mình không thể báo cáo các dịch chuyển xảy ra bên trong iFrame. Tuy nhiên, chỉ số CLS thực tế mà Google thu thập từ người dùng (thông qua dữ liệu CrUX – Chrome User Experience Report) lại có tính đến những dịch chuyển này.

Ví dụ: Bạn có một website dùng để giới thiệu sản phẩm. Bạn nhúng một video đánh giá sản phẩm từ YouTube (sử dụng iFrame) ở giữa bài viết. Video này có một quảng cáo tự động phát, và quảng cáo này gây ra một dịch chuyển nhỏ bên trong khung video đó.

Khi bạn dùng các công cụ kiểm tra trong môi trường phát triển (lab data) hoặc sử dụng API CLS bằng JavaScript, bạn có thể không thấy dịch chuyển này được tính vào điểm CLS của mình.

Tuy nhiên, khi người dùng thực tế truy cập trang của bạn, Google CrUX sẽ ghi nhận dịch chuyển bên trong video iFrame đó và tính vào điểm CLS cuối cùng của trang.

Điều này có nghĩa là, bạn có thể thấy điểm CLS trên công cụ phát triển của mình là “tốt” (ví dụ 0.05), nhưng trên Google Search Console lại hiển thị là “cần cải thiện” hoặc “kém” (ví dụ 0.15). 

Kết luận

Tóm lại, việc tối ưu hóa Cumulative Layout Shift là một bước gần như bắt buộc để cung cấp trải nghiệm người dùng tốt nhất và cải thiện hiệu suất SEO trên Google. Bằng cách hiểu rõ nguyên nhân và áp dụng các giải pháp phù hợp, bạn có thể tạo ra những trang web hoạt động ổn định và dễ chịu hơn cho người dùng.

Bài viết trên được mình nghiên cứu, phân tích và tổng hợp từ nhiều nguồn nội dung uy tín như Google Search Central, WebDev, Ahrefs, Semrush, Search Engine Land,…. Cùng với kinh nghiệm hơn 7 năm làm SEO của mình. Nếu bạn còn điều gì thắc mắc thì hãy để lại thông tin bên dưới để cùng nhau trao đổi nhé.

Nguồn bài viết tham khảo: 

Hãy đánh giá nội dung