Việc thay đổi bố cục không mong muốn có thể làm gián đoạn trải nghiệm người dùng theo nhiều cách, từ việc khiến họ mất vị trí khi đọc nếu văn bản di chuyển đột ngột, đến việc khiến họ nhấp vào đường liên kết hoặc nút không chính xác. Trong một số trường hợp, điều này có thể gây ra thiệt hại nghiêm trọng.
Việc nội dung trang di chuyển không mong muốn thường xảy ra khi tài nguyên tải không đồng bộ hoặc các phần tử DOM được thêm động vào trang trước nội dung hiện có. Nguyên nhân gây ra sự thay đổi bố cục có thể là hình ảnh hoặc video có kích thước không xác định, phông chữ hiển thị lớn hơn hoặc nhỏ hơn phông chữ dự phòng ban đầu, hoặc quảng cáo hoặc tiện ích của bên thứ ba tự động đổi kích thước.
Sự khác biệt giữa cách một trang web hoạt động trong quá trình phát triển và cách người dùng trải nghiệm trang web đó khiến vấn đề này trở nên tồi tệ hơn. Ví dụ:
- Nội dung được cá nhân hoá hoặc nội dung của bên thứ ba thường hoạt động khác nhau trong quá trình phát triển và trong quá trình sản xuất.
- Hình ảnh kiểm thử thường đã có trong bộ nhớ đệm trình duyệt của nhà phát triển, nhưng mất nhiều thời gian hơn để tải cho người dùng cuối.
- Các lệnh gọi API chạy cục bộ thường rất nhanh đến nỗi độ trễ không đáng kể trong quá trình phát triển có thể trở thành đáng kể trong quá trình sản xuất.
Chỉ số Sự thay đổi bố cục tích luỹ (CLS) giúp bạn giải quyết vấn đề này bằng cách đo lường tần suất xảy ra sự cố này đối với người dùng thực.
CLS là gì?
CLS là chỉ số đo lường chuỗi điểm số về mức thay đổi bố cục lớn nhất cho mọi lần thay đổi bố cục không mong muốn xảy ra trong toàn bộ vòng đời của một trang.
Thay đổi bố cục xảy ra bất cứ khi nào một phần tử hiển thị thay đổi vị trí từ khung hiển thị này sang khung hiển thị tiếp theo. (Thông tin chi tiết về cách tính điểm thay đổi bố cục riêng lẻ sẽ được đề cập ở phần sau của hướng dẫn này.)
Một loạt các thay đổi bố cục, được gọi là khoảng thời gian phiên, là khi một hoặc nhiều thay đổi bố cục riêng lẻ xảy ra liên tiếp nhanh chóng với khoảng thời gian dưới 1 giây giữa mỗi lần thay đổi và tối đa 5 giây cho tổng thời lượng cửa sổ.
Chuỗi điểm số lớn nhất là khoảng thời gian phiên có điểm tích luỹ tối đa của tất cả các lượt thay đổi bố cục trong khoảng thời gian đó.
Điểm CLS tốt là bao nhiêu?
Để đem lại trải nghiệm tốt cho người dùng, các trang web nên cố gắng đạt điểm CLS từ 0,1 trở xuống. Để đảm bảo bạn đang đạt được mục tiêu này cho hầu hết người dùng, ngưỡng phù hợp để đo lường là phân vị thứ 75 của số lượt tải trang, được phân đoạn trên thiết bị di động và máy tính.
Để tìm hiểu thêm về nghiên cứu và phương pháp đằng sau đề xuất này, hãy xem bài viết Xác định ngưỡng của các chỉ số Core Web Vitals.
Thông tin chi tiết về thay đổi bố cục
Sự thay đổi bố cục được xác định bởi Layout Instability API (API về sự không ổn định của bố cục). API này báo cáo các mục layout-shift
bất cứ khi nào một phần tử hiển thị trong khung nhìn thay đổi vị trí bắt đầu (ví dụ: vị trí trên cùng và bên trái trong chế độ ghi mặc định) giữa hai khung. Những phần tử như vậy được coi là phần tử không ổn định.
Xin lưu ý rằng việc thay đổi bố cục chỉ xảy ra khi các phần tử hiện có thay đổi vị trí bắt đầu. Nếu một phần tử mới được thêm vào DOM hoặc một phần tử hiện có thay đổi kích thước, thì phần tử đó không được tính là thay đổi bố cục, miễn là thay đổi đó không khiến các phần tử hiển thị khác thay đổi vị trí bắt đầu.
Điểm số về mức thay đổi bố cục
Để tính toán điểm số thay đổi bố cục, trình duyệt sẽ xem xét kích thước khung nhìn và chuyển động của các phần tử không ổn định trong khung nhìn giữa hai khung hình được kết xuất. Điểm dịch chuyển bố cục là tích của hai chỉ số đo lường chuyển động đó: phần tử tác động và phần tử khoảng cách (cả hai đều được xác định bên dưới).
layout shift score = impact fraction * distance fraction
Tỷ lệ tác động
Mức tác động đo lường mức độ ảnh hưởng của các phần tử không ổn định đến khu vực khung nhìn giữa hai khung hình.
Mức tác động của một khung hình nhất định là sự kết hợp của các khu vực hiển thị của tất cả các phần tử không ổn định cho khung hình đó và khung hình trước đó, dưới dạng một phân số của tổng diện tích khung nhìn.
Trong hình ảnh trước, có một phần tử chiếm một nửa khung nhìn trong một khung. Sau đó, trong khung tiếp theo, phần tử này sẽ dịch chuyển xuống 25% chiều cao khung nhìn. Hình chữ nhật màu đỏ, có chấm cho biết sự kết hợp của vùng hiển thị của phần tử trong cả hai khung, trong trường hợp này là 75% tổng số khung nhìn, vì vậy, phần tử tác động là 0.75
.
Phân số khoảng cách
Phần còn lại của phương trình điểm số thay đổi bố cục đo lường khoảng cách mà các phần tử không ổn định đã di chuyển so với khung nhìn. Phần tử khoảng cách là khoảng cách theo chiều ngang hoặc chiều dọc lớn nhất mà bất kỳ phần tử không ổn định nào đã di chuyển trong khung chia cho kích thước lớn nhất của khung nhìn (chiều rộng hoặc chiều cao, tuỳ theo kích thước nào lớn hơn).
Trong ví dụ trước, kích thước khung nhìn lớn nhất là chiều cao và phần tử không ổn định đã di chuyển 25% chiều cao khung nhìn, khiến phần tỷ lệ khoảng cách là 0, 25.
Vì vậy, trong ví dụ này, phần tử tác động là 0.75
và phần tử khoảng cách là 0.25
, do đó điểm dịch chuyển bố cục là 0.75 * 0.25 = 0.1875
.
Ví dụ
Ví dụ tiếp theo minh hoạ cách việc thêm nội dung vào một phần tử hiện có ảnh hưởng đến điểm số thay đổi bố cục:
Trong ví dụ này, hộp màu xám thay đổi kích thước nhưng vị trí bắt đầu của hộp không thay đổi nên đây không phải là phần tử không ổn định.
Nút "Nhấp vào tôi!" trước đây không có trong DOM, vì vậy, vị trí bắt đầu của nút này cũng không thay đổi.
Tuy nhiên, vị trí bắt đầu của hộp màu xanh lục sẽ thay đổi, nhưng vì hộp này đã được di chuyển một phần ra khỏi khung nhìn, nên khu vực không hiển thị sẽ không được tính đến khi tính toán phần trăm tác động. Tập hợp các vùng hiển thị của hộp màu xanh lục trong cả hai khung (được minh hoạ bằng hình chữ nhật màu đỏ, có chấm) giống với diện tích của hộp màu xanh lục trong khung đầu tiên – 50% của khung nhìn. Mức tác động là 0.5
.
Phần tử khoảng cách được minh hoạ bằng mũi tên màu tím. Hộp màu xanh lục đã di chuyển xuống khoảng 14% khung nhìn, vì vậy phần khoảng cách là 0.14
.
Điểm số về mức thay đổi bố cục là 0.5 x 0.14 = 0.07
.
Ví dụ sau đây cho thấy cách nhiều phần tử không ổn định ảnh hưởng đến điểm số về mức thay đổi bố cục của trang:
Trong khung đầu tiên của hình ảnh trước, có 4 kết quả của một yêu cầu API về động vật, được sắp xếp theo thứ tự bảng chữ cái. Trong khung thứ hai, nhiều kết quả hơn được thêm vào danh sách đã sắp xếp.
Mục đầu tiên trong danh sách ("Mèo") không thay đổi vị trí bắt đầu giữa các khung hình, vì vậy, mục này ổn định. Tương tự, các mục mới được thêm vào danh sách trước đây không có trong DOM, vì vậy, vị trí bắt đầu của các mục đó cũng không thay đổi. Tuy nhiên, các mục có nhãn "Chó", "Ngựa" và "Ngựa vằn" đều thay đổi vị trí bắt đầu, khiến chúng trở thành các phần tử không ổn định.
Xin nhắc lại, các hình chữ nhật màu đỏ, có dấu chấm đại diện cho sự hợp nhất của các vùng trước và sau của 3 phần tử không ổn định này, trong trường hợp này là khoảng 60% diện tích của khung nhìn (phần tử tác động của 0.60
).
Các mũi tên thể hiện khoảng cách mà các phần tử không ổn định đã di chuyển từ vị trí bắt đầu. Phần tử "Zebra" (Ngựa vằn), được biểu thị bằng mũi tên màu xanh dương, đã di chuyển nhiều nhất, khoảng 30% chiều cao khung nhìn. Điều đó làm cho phần tử khoảng cách trong ví dụ này là 0.3
.
Điểm số về mức thay đổi bố cục là 0.60 x 0.3 = 0.18
.
Thay đổi bố cục dự kiến so với thay đổi bố cục không mong muốn
Không phải sự thay đổi bố cục nào cũng là xấu. Trên thực tế, nhiều ứng dụng web động thường xuyên thay đổi vị trí bắt đầu của các phần tử trên trang. Sự thay đổi bố cục chỉ là xấu nếu người dùng không mong đợi điều đó.
Thay đổi bố cục do người dùng thực hiện
Các thay đổi về bố cục xảy ra để phản hồi hoạt động tương tác của người dùng (chẳng hạn như nhấp hoặc nhấn vào đường liên kết, nhấn vào nút hoặc nhập vào hộp tìm kiếm) thường không gây vấn đề, miễn là sự thay đổi xảy ra đủ gần với hoạt động tương tác để người dùng hiểu rõ mối quan hệ.
Ví dụ: nếu một lượt tương tác của người dùng kích hoạt một yêu cầu mạng có thể mất chút thời gian để hoàn tất, tốt nhất bạn nên tạo một khoảng trống ngay lập tức và hiển thị chỉ báo tải để tránh sự thay đổi bố cục không mong muốn khi yêu cầu hoàn tất. Nếu người dùng không nhận ra rằng có nội dung đang tải hoặc không biết thời điểm tài nguyên sẵn sàng, họ có thể thử nhấp vào một nội dung khác trong khi chờ đợi – một nội dung có thể di chuyển ra khỏi màn hình.
Các thay đổi về bố cục xảy ra trong vòng 500 mili giây kể từ khi người dùng nhập sẽ được đặt cờ hadRecentInput
để có thể loại trừ khỏi các phép tính.
Ảnh động và hiệu ứng chuyển tiếp
Ảnh động và hiệu ứng chuyển đổi (nếu được thực hiện tốt) là một cách tuyệt vời để cập nhật nội dung trên trang mà không làm người dùng bất ngờ. Nội dung thay đổi đột ngột và không mong muốn trên trang hầu như luôn tạo ra trải nghiệm người dùng kém. Tuy nhiên, nội dung di chuyển dần dần và tự nhiên từ vị trí này sang vị trí khác thường có thể giúp người dùng hiểu rõ hơn về những gì đang diễn ra và hướng dẫn họ trong quá trình thay đổi trạng thái.
Hãy nhớ tuân thủ chế độ cài đặt trình duyệt prefers-reduced-motion
, vì một số khách truy cập trang web có thể gặp phải các vấn đề về sự chú ý hoặc tác động xấu do ảnh động gây ra.
Thuộc tính CSS transform
cho phép bạn tạo ảnh động cho các phần tử mà không kích hoạt sự thay đổi bố cục:
- Thay vì thay đổi thuộc tính
height
vàwidth
, hãy sử dụngtransform: scale()
. - Để di chuyển các phần tử, hãy tránh thay đổi thuộc tính
top
,right
,bottom
hoặcleft
và sử dụngtransform: translate()
.
Cách đo lường CLS
Bạn có thể đo lường CLS trong phòng thí nghiệm hoặc trực tiếp tại hiện trường. Bạn cũng có thể đo lường CLS bằng các công cụ sau:
Công cụ tại hiện trường
- Báo cáo trải nghiệm người dùng trên Chrome
- PageSpeed Insights
- Search Console (báo cáo Các chỉ số quan trọng chính của trang web)
- Thư viện JavaScript
web-vitals
Công cụ của Labs
Đo lường mức thay đổi bố cục trong JavaScript
Để đo lường mức thay đổi bố cục trong JavaScript, bạn có thể sử dụng Layout Instability API (API không ổn định của bố cục).
Ví dụ sau đây cho biết cách tạo PerformanceObserver
để ghi lại các mục nhập layout-shift
vào bảng điều khiển:
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('Layout shift:', entry);
}
}).observe({type: 'layout-shift', buffered: true});
Đo lường CLS trong JavaScript
Để đo lường CLS trong JavaScript, bạn cần nhóm các mục nhập layout-shift
không mong muốn này thành các phiên và tính giá trị phiên tối đa. Bạn có thể tham khảo mã nguồn thư viện JavaScript web vitals
. Mã này chứa nội dung triển khai tham chiếu về cách tính CLS.
Trong hầu hết các trường hợp, giá trị CLS hiện tại tại thời điểm trang đang được tải xuống là giá trị CLS cuối cùng cho trang đó, nhưng có một số trường hợp ngoại lệ quan trọng như được ghi chú trong phần tiếp theo. Thư viện JavaScript web vitals
tính đến các yếu tố này nhiều nhất có thể, trong phạm vi giới hạn của API Web.
Sự khác biệt giữa chỉ số và API
- Nếu một trang được tải ở chế độ nền hoặc nếu trang đó ở chế độ nền trước khi trình duyệt vẽ bất kỳ nội dung nào, thì trang đó sẽ không báo cáo giá trị CLS nào.
- Nếu một trang được khôi phục từ bộ nhớ đệm cho thao tác tiến/lùi, thì giá trị CLS của trang đó sẽ được đặt lại về 0 vì người dùng sẽ thấy đây là một lượt truy cập trang riêng biệt.
- API không báo cáo các mục nhập
layout-shift
cho các lượt thay đổi xảy ra trong iframe, nhưng chỉ số này lại báo cáo vì các lượt thay đổi đó là một phần của trải nghiệm người dùng trên trang. Điều này có thể cho thấy sự khác biệt giữa CrUX và RUM. Để đo lường chính xác CLS, bạn nên cân nhắc những yếu tố này. Khung con có thể sử dụng API để báo cáo các mục nhậplayout-shift
của chúng cho khung mẹ để tổng hợp.
Ngoài những trường hợp ngoại lệ này, CLS còn có một số điểm phức tạp khác do chỉ số này đo lường toàn bộ thời gian hoạt động của một trang:
- Người dùng có thể mở một thẻ trong một khoảng thời gian rất dài – vài ngày, vài tuần, vài tháng. Trên thực tế, người dùng có thể không bao giờ đóng thẻ.
- Trên hệ điều hành di động, trình duyệt thường không chạy lệnh gọi lại khi tải trang cho các thẻ ở chế độ nền, khiến việc báo cáo giá trị "cuối cùng" trở nên khó khăn.
Để xử lý những trường hợp như vậy, bạn nên báo cáo CLS bất cứ khi nào trang ở chế độ nền, ngoài mọi thời điểm trang không tải (sự kiện visibilitychange
bao gồm cả hai trường hợp này). Sau đó, các hệ thống phân tích nhận dữ liệu này sẽ cần tính toán giá trị CLS cuối cùng ở phần phụ trợ.
Thay vì tự ghi nhớ và xử lý tất cả các trường hợp này, nhà phát triển có thể sử dụng thư viện JavaScript web-vitals
để đo lường CLS, trong đó tính đến mọi thứ được đề cập ở trên ngoại trừ trường hợp iframe:
import {onCLS} from 'web-vitals';
// Measure and log CLS in all situations
// where it needs to be reported.
onCLS(console.log);
Cách cải thiện CLS
Để biết thêm hướng dẫn về cách xác định sự thay đổi bố cục trong thực tế và sử dụng dữ liệu trong phòng thí nghiệm để tối ưu hoá sự thay đổi đó, hãy xem hướng dẫn của chúng tôi về cách tối ưu hoá CLS.
Tài nguyên khác
- Hướng dẫn của Thẻ nhà xuất bản của Google về cách giảm thiểu sự thay đổi bố cục
- Tìm hiểu về Lỗi thay đổi bố cục tích luỹ của Annie Sullivan và Steve Kobes tại #PerfMatters (2020)
Nhật ký thay đổi
Đôi khi, chúng tôi phát hiện lỗi trong các API dùng để đo lường chỉ số và đôi khi là trong định nghĩa của chính các chỉ số đó. Do đó, đôi khi bạn phải thực hiện các thay đổi và những thay đổi này có thể xuất hiện dưới dạng điểm cải thiện hoặc hồi quy trong các báo cáo và trang tổng quan nội bộ.
Để giúp bạn quản lý việc này, tất cả thay đổi đối với việc triển khai hoặc định nghĩa của các chỉ số này sẽ xuất hiện trong Nhật ký thay đổi này.
Nếu có ý kiến phản hồi về các chỉ số này, bạn có thể gửi ý kiến đó trong nhóm Google web-vitals-feedback.