Gỡ lỗi thay đổi bố cục

Tìm hiểu cách xác định và khắc phục việc thay đổi bố cục.

Katie Hempenius
Katie Hempenius

Phần đầu tiên của bài viết này thảo luận về công cụ để gỡ lỗi thay đổi bố cục, trong khi phần thứ hai thảo luận về quy trình tư duy cần áp dụng khi xác định nguyên nhân dẫn đến thay đổi bố cục.

Công cụ

API Bố cục không ổn định

Layout Instability API là cơ chế trình duyệt để đo lường và báo cáo sự thay đổi bố cục. Tất cả công cụ dành cho Cuối cùng, việc gỡ lỗi thay đổi bố cục (bao gồm cả Công cụ cho nhà phát triển) được xây dựng dựa trên API Không ổn định bố cục. Tuy nhiên, việc sử dụng trực tiếp Layout Instability API công cụ gỡ lỗi mạnh mẽ nhờ tính linh hoạt.

Cách sử dụng

Cùng một đoạn mã đo lường Điểm số tổng hợp về mức thay đổi bố cục (CLS) cũng có thể để gỡ lỗi thay đổi bố cục. Đoạn mã dưới đây ghi lại thông tin về bố cục chuyển sang bảng điều khiển. Việc kiểm tra nhật ký này sẽ cung cấp cho bạn thông tin về thời điểm, địa điểm và cách thức thay đổi bố cục.

let cls = 0;
new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

Khi chạy tập lệnh này, hãy lưu ý rằng:

  • Tùy chọn buffered: true cho biết rằng PerformanceObserver nên kiểm tra mục hiệu suất của trình duyệt vùng đệm cho các mục nhập hiệu suất được tạo trước khởi tạo. Do đó, PerformanceObserver sẽ báo cáo bố cục những thay đổi xảy ra cả trước và sau khi khởi tạo. Lưu trữ trong khi kiểm tra nhật ký bảng điều khiển. Khoảng thời gian ban đầu của việc thay đổi bố cục có thể phản ánh tồn đọng báo cáo, thay vì sự xuất hiện đột ngột của nhiều thay đổi bố cục.
  • Để tránh ảnh hưởng đến hiệu suất, PerformanceObserver sẽ đợi đến khi luồng không hoạt động để báo cáo về việc thay đổi bố cục. Kết quả là, tuỳ thuộc vào cách thức bận luồng chính, có thể có đôi chút chậm trễ giữa thời điểm bố cục shift xảy ra và khi được ghi vào bảng điều khiển.
  • Tập lệnh này bỏ qua các thay đổi về bố cục xảy ra trong vòng 500 mili giây từ hoạt động đầu vào của người dùng nên không được tính vào CLS.

Thông tin về việc thay đổi bố cục được báo cáo bằng cách sử dụng kết hợp 2 API: LayoutShiftLayoutShiftAttribution giao diện. Mỗi giao diện này được giải thích chi tiết hơn trong các phần sau.

LayoutShift

Mỗi lần thay đổi bố cục được báo cáo bằng giao diện LayoutShift. Nội dung của một mục nhập có dạng như sau:

duration: 0
entryType: "layout-shift"
hadRecentInput: false
lastInputTime: 0
name: ""
sources: (3) [LayoutShiftAttribution, LayoutShiftAttribution, LayoutShiftAttribution]
startTime: 11317.934999999125
value: 0.17508567530168798

Mục nhập ở trên cho biết thay đổi bố cục trong đó 3 phần tử DOM thay đổi vị trí. Điểm số về mức thay đổi bố cục của lần thay đổi bố cục cụ thể này là 0.175.

Đây là các thuộc tính của thực thể LayoutShift có liên quan nhất đến gỡ lỗi thay đổi bố cục:

Thuộc tính Mô tả
sources Thuộc tính sources liệt kê các phần tử DOM đã di chuyển trong quá trình thay đổi bố cục. Mảng này có thể chứa tối đa 5 nguồn. Trong trường hợp có hơn 5 phần tử bị ảnh hưởng bởi việc thay đổi bố cục, thì 5 nguồn thay đổi bố cục lớn nhất (được đo lường bằng mức tác động đến độ ổn định của bố cục) sẽ được báo cáo. Thông tin này được báo cáo bằng giao diện LayoutShiftAttribution (được giải thích chi tiết hơn ở bên dưới).
value Thuộc tính value báo cáo điểm thay đổi bố cục cho một lần thay đổi bố cục cụ thể.
hadRecentInput Thuộc tính hadRecentInput cho biết liệu sự thay đổi bố cục có xảy ra trong vòng 500 mili giây từ hoạt động đầu vào của người dùng hay không.
startTime Thuộc tính startTime cho biết thời điểm xảy ra thay đổi bố cục. startTime được biểu thị bằng mili giây và được đo lường tương ứng với thời gian bắt đầu tải trang.
duration Thuộc tính duration sẽ luôn được đặt thành 0. Thuộc tính này được kế thừa từ giao diện PerformanceEntry (giao diện LayoutShift mở rộng giao diện PerformanceEntry). Tuy nhiên, khái niệm về thời lượng không áp dụng cho các sự kiện thay đổi bố cục, do đó, thời lượng được đặt thành 0. Để biết thông tin về giao diện PerformanceEntry, hãy tham khảo quy cách.

LayoutShiftAttribution

Giao diện LayoutShiftAttribution mô tả một thao tác chuyển của một DOM . Nếu nhiều phần tử thay đổi trong một lần thay đổi bố cục, sources thuộc tính chứa nhiều mục nhập.

Ví dụ: JSON dưới đây tương ứng với sự thay đổi bố cục với một nguồn: dịch chuyển xuống của phần tử DOM <div id='banner'> từ y: 76 sang y:246.

// ...
  "sources": [
    {
      "node": "div#banner",
      "previousRect": {
        "x": 311,
        "y": 76,
        "width": 4,
        "height": 18,
        "top": 76,
        "right": 315,
        "bottom": 94,
        "left": 311
      },
      "currentRect": {
        "x": 311,
        "y": 246,
        "width": 4,
        "height": 18,
        "top": 246,
        "right": 315,
        "bottom": 264,
        "left": 311
      }
    }
  ]

Thuộc tính node xác định phần tử HTML đã thay đổi. Di chuột lên mục này trong Công cụ cho nhà phát triển sẽ làm nổi bật phần tử trang tương ứng.

Thuộc tính previousRectcurrentRect báo cáo kích thước và vị trí của nút.

  • Toạ độ xy báo cáo toạ độ x và toạ độ y tương ứng với góc trên cùng bên trái của phần tử
  • Thuộc tính widthheight báo cáo chiều rộng và chiều cao tương ứng của phần tử.
  • Các thuộc tính top, right, bottomleft báo cáo x hoặc y các giá trị toạ độ tương ứng với cạnh đã cho của phần tử. Trong khu vực khác các từ, giá trị của top bằng y; giá trị của bottom bằng y+height.

Nếu tất cả các thuộc tính của previousRect đều được đặt thành 0, thì điều này có nghĩa là phần tử đó có chuyển vào khung hiển thị. Nếu tất cả các thuộc tính của currentRect đều được đặt thành 0, thì điều này có nghĩa là phần tử đã dịch chuyển ra khỏi khung hiển thị.

Một trong những điều quan trọng nhất cần hiểu rõ khi diễn giải những dữ liệu đầu ra này các phần tử được liệt kê dưới dạng nguồn là những phần tử thay đổi trong thay đổi bố cục. Tuy nhiên, có thể những thành phần này chỉ mang tính gián tiếp có liên quan đến "nguyên nhân gốc" về tính bất ổn định của bố cục. Sau đây là một vài ví dụ.

Ví dụ #1

Thay đổi bố cục này sẽ được báo cáo bằng một nguồn: phần tử B. Tuy nhiên, nguyên nhân gốc rễ của việc thay đổi bố cục này là sự thay đổi kích thước của phần tử A.

Ví dụ cho thấy sự thay đổi bố cục do thay đổi về kích thước phần tử

Ví dụ #2

Thay đổi bố cục trong ví dụ này sẽ được báo cáo bằng 2 nguồn: phần tử A và phần tử B. Nguyên nhân gốc rễ của việc thay đổi bố cục này là sự thay đổi vị trí của phần tử A.

Ví dụ cho thấy sự thay đổi bố cục do vị trí phần tử thay đổi

Ví dụ 3

Thay đổi bố cục trong ví dụ này sẽ được báo cáo bằng một nguồn: phần tử B. Việc thay đổi vị trí của phần tử B đã dẫn đến sự thay đổi bố cục này.

Ví dụ cho thấy sự thay đổi bố cục do vị trí phần tử thay đổi

Ví dụ #4

Mặc dù phần tử B thay đổi kích thước nhưng không có sự thay đổi bố cục trong ví dụ này.

Ví dụ cho thấy một phần tử thay đổi kích thước nhưng không làm thay đổi bố cục

Kiểm tra bản minh hoạ cách các thay đổi của DOM được API Không ổn định bố cục báo cáo.

Công cụ cho nhà phát triển

Bảng điều khiển hiệu suất

Ngăn Trải nghiệm của bảng điều khiển Hiệu suất của Công cụ cho nhà phát triển hiển thị tất cả các thay đổi về bố cục xảy ra trong một dấu vết hiệu suất nhất định, ngay cả khi chúng xảy ra trong vòng 500 mili giây kể từ một lượt tương tác của người dùng và do đó không được tính vào CLS (Mức thay đổi bố cục tích luỹ). Di chuột qua một thay đổi cụ thể về bố cục trong bảng điều khiển Trải nghiệm được làm nổi bật phần tử DOM bị ảnh hưởng.

Ảnh chụp màn hình về việc thay đổi bố cục hiển thị trong bảng điều khiển Mạng Công cụ cho nhà phát triển

Để xem thêm thông tin về việc thay đổi bố cục, hãy nhấp vào sự thay đổi bố cục này, sau đó mở ngăn Tóm tắt. Liệt kê các thay đổi đối với phương diện của phần tử sử dụng định dạng [width, height]; thay đổi đối với vị trí của phần tử được liệt kê bằng cách sử dụng định dạng [x,y]. Thuộc tính Đã nhập gần đây cho biết liệu một Sự thay đổi bố cục xảy ra trong vòng 500 mili giây kể từ một lượt tương tác của người dùng.

Ảnh chụp màn hình &quot;Tóm tắt&quot; Công cụ cho nhà phát triển nhấn phím tab để thay đổi bố cục

Để biết thông tin về khoảng thời gian thay đổi bố cục, hãy mở thẻ Nhật ký sự kiện. Thời lượng thay đổi bố cục cũng có thể ước chừng bằng cách xem Ngăn Trải nghiệm cho độ dài của hình chữ nhật chuyển bố cục màu đỏ.

Ảnh chụp màn hình &quot;Nhật ký sự kiện&quot; trong Công cụ cho nhà phát triển nhấn phím tab để thay đổi bố cục

Để biết thêm thông tin về cách sử dụng bảng Hiệu suất, hãy tham khảo bài viết Hiệu suất Bản phân tích Tệp đối chiếu.

Làm nổi bật khu vực thay đổi bố cục

Làm nổi bật khu vực thay đổi bố cục có thể là một kỹ thuật hữu ích để thu hút cảm nhận nhanh vị trí và thời gian thay đổi bố cục xảy ra trên một trang.

Để bật tính năng Khu vực chuyển bố cục trong Công cụ cho nhà phát triển, hãy chuyển đến phần Cài đặt > Công cụ khác > Kết xuất > Khu vực thay đổi bố cục sau đó làm mới trang mà bạn muốn gỡ lỗi. Các khu vực thay đổi bố cục sẽ được đánh dấu ngắn gọn bằng màu tím.

Quá trình tư duy để xác định nguyên nhân dẫn đến sự thay đổi bố cục

Bạn có thể làm theo các bước dưới đây để xác định nguyên nhân khiến bố cục thay đổi bất kể thời điểm hay cách thức thay đổi bố cục. Bạn có thể thực hiện các bước này bổ sung bằng cách chạy Lighthouse. Tuy nhiên, hãy lưu ý rằng Lighthouse có thể chỉ xác định những thay đổi về bố cục xảy ra trong lần tải trang đầu tiên. Trong Ngoài ra, Lighthouse cũng chỉ có thể đưa ra đề xuất cho một số nguyên nhân về bố cục thay đổi—ví dụ: các phần tử hình ảnh không có chiều rộng và chiều cao rõ ràng.

Xác định nguyên nhân dẫn đến việc thay đổi bố cục

Các sự kiện sau có thể gây ra việc thay đổi bố cục:

  • Thay đổi đối với vị trí của phần tử DOM
  • Các thay đổi đối với kích thước của phần tử DOM
  • Chèn hoặc xoá phần tử DOM
  • Ảnh động kích hoạt bố cục

Cụ thể, phần tử DOM ngay trước phần tử được dịch chuyển là phần tử yếu tố có nhiều khả năng tham gia vào việc "gây ra" nhất thay đổi bố cục. Do đó, khi tìm hiểu lý do xảy ra sự thay đổi bố cục, hãy xem xét:

  • Vị trí hoặc kích thước của phần tử trước đó có thay đổi không?
  • Phần tử DOM có được chèn hoặc xóa trước phần tử được dịch chuyển không?
  • Vị trí của phần tử được dịch chuyển có bị thay đổi rõ ràng không?

Nếu phần tử trước đó không gây ra thay đổi bố cục, hãy tiếp tục tìm kiếm bằng cách xem xét các phần tử có trước và gần đó.

Ngoài ra, hướng và khoảng cách của việc thay đổi bố cục có thể đưa ra gợi ý về căn nguyên. Ví dụ: sự dịch chuyển đi xuống lớn thường biểu thị chèn phần tử DOM, trong khi sự thay đổi bố cục 1 px hoặc 2 px thường biểu thị việc áp dụng các kiểu CSS xung đột hoặc việc tải và áp dụng một phông chữ trên web.

Biểu đồ thể hiện sự thay đổi bố cục do hoán đổi phông chữ
Trong ví dụ này, việc hoán đổi phông chữ làm cho các phần tử trang dịch chuyển lên trên 5 pixel.

Dưới đây là một số hành vi cụ thể thường gây ra sự thay đổi bố cục nhất sự kiện:

Những thay đổi đối với vị trí của một phần tử (không phải do sự chuyển động của một phần tử khác)

Loại thay đổi này thường là do:

  • Biểu định kiểu được tải muộn hoặc ghi đè các kiểu đã khai báo trước đó.
  • Hiệu ứng ảnh động và hiệu ứng chuyển tiếp.

Các thay đổi đối với kích thước của phần tử

Loại thay đổi này thường là do:

  • Biểu định kiểu được tải muộn hoặc ghi đè các kiểu đã khai báo trước đó.
  • Hình ảnh và iframe không có thuộc tính widthheight sẽ tải sau "ô" của họ đã được kết xuất.
  • Khối văn bản không có thuộc tính width hoặc height hoán đổi phông chữ sau đã được hiển thị văn bản.

Chèn hoặc xoá các phần tử DOM

Đây thường là kết quả của:

  • Chèn quảng cáo và nội dung nhúng khác của bên thứ ba.
  • Chèn biểu ngữ, cảnh báo và phương thức.
  • Cuộn vô hạn và các mẫu trải nghiệm người dùng khác có tải thêm nội dung ở trên nội dung hiện có.

Ảnh động kích hoạt bố cục

Một số hiệu ứng ảnh động có thể kích hoạt . Điểm chung ví dụ về điều này là khi các phần tử DOM có dạng "ảnh động" bằng cách tăng thuộc tính như top hoặc left thay vì sử dụng CSS transform thuộc tính này. Đọc Cách tạo ảnh động CSS hiệu suất cao để biết thêm thông tin.

Tái tạo các thay đổi về bố cục

Bạn không thể sửa những thay đổi về bố cục mà bạn không thể tái tạo. Một trong những cách đơn giản nhất những việc hiệu quả nhất bạn có thể làm để hiểu rõ hơn về bố cục trang web của mình độ ổn định là mất 5-10 phút để tương tác với trang web của bạn với mục tiêu kích hoạt thay đổi bố cục. Luôn mở bảng điều khiển trong khi thực hiện việc này và sử dụng API Bố cục không ổn định để báo cáo về việc thay đổi bố cục.

Đối với những thay đổi về bố cục khó xác định, hãy cân nhắc lặp lại bài tập này với thiết bị và tốc độ kết nối khác nhau. Cụ thể, việc sử dụng tốc độ kết nối có thể giúp bạn dễ dàng xác định sự thay đổi bố cục. Ngoài ra, bạn có thể dùng câu lệnh debugger để thao tác với bố cục dễ dàng hơn ca.

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      debugger;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

Cuối cùng, đối với các vấn đề về bố cục không thể tái tạo trong quá trình phát triển, hãy cân nhắc dùng Layout Instability API cùng với công cụ ghi nhật ký giao diện người dùng của bạn lựa chọn để thu thập thêm thông tin về các vấn đề này. Trả phòng ví dụ về mã về cách theo dõi phần tử bị dịch chuyển lớn nhất trên một trang.