Xác định JavaScript chạy nặng

JavaScript chạy nặng có thể gây ảnh hưởng bất lợi đến cả hiệu suất tải trang và khả năng tương tác. Các ứng dụng web hiện đại phụ thuộc nhiều vào JavaScript hơn bao giờ hết, từ nhiều nguồn. Các tài nguyên này bao gồm chính mã xử lý ứng dụng (và mã khung mà ứng dụng dựa vào), cũng như các tập lệnh của bên thứ ba bổ sung chức năng như tiện ích trò chuyện và trình phát video. Các tập lệnh tiếp thị và phân tích ở chế độ nền cũng là những yếu tố thường gặp và rất dễ bị bỏ quên.

Việc xác định nguyên nhân gốc của một trang web không phản hồi có thể rất khó khăn, đòi hỏi một số kiến thức chuyên môn nhất định để chạy quy trình theo dõi hoặc lập hồ sơ hiệu suất web và cách diễn giải kết quả. Ngoài ra, dữ liệu thực tế thường rất khác với dữ liệu trong phòng thí nghiệm, vốn chỉ mô phỏng một nhóm nhỏ các tình huống thực tế của người dùng. Điều này có thể gây khó khăn cho việc xác định nguyên nhân gốc của hiệu suất kém, đặc biệt là đối với các lượt tương tác.

Long Animation Frames API là một API gọn nhẹ, có thể dùng để xác định JavaScript chạy nặng trong thực tế. Tập lệnh chạy nặng có thể là một tập lệnh chạy trong thời gian dài hoặc một tập lệnh chạy nhiều lần trong vòng đời của trang.

Cách triển khai

Khung hoạt hoạ cần nhiều thời gian được giám sát bằng giao diện PerformanceObserver. API này phát ra một mục nhập long-animation-frame khi một khung ảnh động mất hơn 50 mili giây để kết xuất. Mục này chứa thông tin về khung hoạt hoạ cần nhiều thời gian, bao gồm cả thời lượng của khung hình và các tập lệnh được thực thi trong khung hình.

Mục nhập long-animation-frame chứa thuộc tính scripts, là một mảng gồm các đối tượng PerformanceScript. Mỗi đối tượng PerformanceScript chứa thông tin về tập lệnh được thực thi trong khung hoạt hoạ cần nhiều thời gian, bao gồm cả sourceURL và duration của tập lệnh.

Ví dụ về cách xác định các tập lệnh chạy lâu nhất góp phần tạo nên khung hoạt hoạ cần nhiều thời gian

// Accumulate all script entries across the page lifecycle so no
// data is lost between observer callbacks.
const allScripts = [];

const observer = new PerformanceObserver(list => {
  // Collect all script entries across frames to find the biggest offenders.
  allScripts.push(...list.getEntries().flatMap(entry => entry.scripts));

  // Group by sourceURL so you can identify which scripts contribute
  // the most total time, even if each individual invocation is short.
  const scriptSource = [...new Set(allScripts.map(script => script.sourceURL))];
  const scriptsBySource = scriptSource.map(sourceURL => ([sourceURL,
      allScripts.filter(script => script.sourceURL === sourceURL)
  ]));
  const processedScripts = scriptsBySource.map(([sourceURL, scripts]) => ({
    sourceURL,
    count: scripts.length,
    totalDuration: scripts.reduce((subtotal, script) => subtotal + script.duration, 0)
  }));

  // Only include scripts above a certain threshold to reduce noise.
  const heavyScripts = processedScripts.filter(script => {
    return script.totalDuration > 100;
  });

  // Sort by total duration so the worst offenders appear first,
  // making it easier to prioritize optimization efforts.
  heavyScripts.sort((a, b) => b.totalDuration - a.totalDuration);

  // Log to the console for local debugging. In production, replace
  // this with a call to send the data to your analytics service.
  console.table(heavyScripts);
});

// Use buffered: true to capture any long frames that occurred before
// this observer was registered.
observer.observe({type: 'long-animation-frame', buffered: true});

Các phương pháp hay nhất

  • NÊN ưu tiên Long Animation Frames API hơn các giải pháp thay thế như JS Self-Profiling API, vì API này có mức hao tổn thời gian chạy cao hơn.
  • NÊN tóm tắt thông tin chính vì Long Animation Frames API chứa nhiều thông tin chi tiết.
  • NÊN gửi thông tin bắt buộc đến một dịch vụ phân tích trong phiên bản chính thức.

Hỗ trợ trình duyệt và chiến lược dự phòng

Long Animation Frames API bị các trình duyệt không hỗ trợ bỏ qua, vì vậy, bạn có thể sử dụng API này một cách an toàn mà không cần dự phòng. Trong hầu hết các trường hợp, những cơ hội cải thiện hiệu suất mà công cụ này xác định cũng sẽ áp dụng cho các trình duyệt khác.