Fix CLS: luôn set width/height trên images/videos, reserve space cho dynamic content, dùng font-display: swap với size-adjust, dùng transform thay vì top/margin cho animations.
- CLS đo mức độ layout shift unexpected trong quá trình loading — score là sum của (impact fraction * distance fraction) cho mỗi shift.
- Target <0.1; >0.25 là poor.
- Nguyên nhân phổ biến và fix: Images/videos không có dimensions — luôn set width/height attributes (aspect-ratio CSS tự tính) hoặc dùng aspect-ratio: 16/9 container; browser reserve space trước khi image load.
- Fonts gây FOUT (Flash of Unstyled Text) khi web font load — dùng font-display: swap với size-adjust để match fallback font metrics; font-display: optional skip web font nếu không cached (zero CLS nhưng có thể không dùng web font); preload critical fonts.
- Dynamically injected content (banners, cookie notices, ads) shift content — reserve space trước bằng min-height container; không inject content above existing content sau page load.
- Dynamic ads: Google Ads có thể gây CLS — fix bằng reserve fixed space cho ad slot.
- Infinite scroll: thêm items dưới thay vì trên viewport. transform: translateY() thay vì top/margin cho animations — transform không trigger layout.
- CLS sau interaction (300ms window) không tính vào score — UX vẫn tệ nhưng không penalty.
- Debugging: Chrome DevTools Performance panel, Layout Shift Regions (Rendering tab).