Giảm tải JavaScript bằng cách phân tách mã

Không ai thích chờ đợi. Hơn 50% người dùng sẽ rời bỏ một trang web nếu trang web đó mất hơn 3 giây để tải.

Việc gửi tải trọng JavaScript lớn ảnh hưởng đáng kể đến tốc độ của trang web. Thay vì gửi tất cả JavaScript cho người dùng ngay khi tải trang đầu tiên của ứng dụng, hãy chia gói của bạn thành nhiều phần và chỉ gửi những phần cần thiết ngay từ đầu.

Tại sao việc phân tách mã lại có lợi?

Phân tách mã là một kỹ thuật nhằm giảm thiểu thời gian khởi động. Khi gửi ít JavaScript hơn khi khởi động, chúng ta có thể giúp ứng dụng tương tác nhanh hơn bằng cách giảm thiểu công việc của luồng chính trong khoảng thời gian quan trọng này.

Đối với Chỉ số quan trọng chính của trang web, việc giảm tải trọng JavaScript được tải xuống khi khởi động sẽ góp phần cải thiện thời gian Lượt tương tác đến nội dung hiển thị tiếp theo (INP). Lý do đằng sau việc này là bằng cách giải phóng luồng chính, ứng dụng có thể phản hồi nhanh hơn các hoạt động đầu vào của người dùng bằng cách giảm chi phí khởi động liên quan đến việc phân tích cú pháp, biên dịch và thực thi JavaScript.

Tuỳ thuộc vào cấu trúc trang web của bạn (đặc biệt là nếu trang web của bạn phụ thuộc nhiều vào tính năng kết xuất phía máy khách), việc giảm kích thước tải trọng JavaScript chịu trách nhiệm kết xuất mã đánh dấu có thể giúp cải thiện thời gian Nội dung lớn nhất hiển thị (LCP). Điều này có thể xảy ra khi tài nguyên LCP bị trễ trong việc được trình duyệt phát hiện cho đến khi hoàn tất việc đánh dấu phía máy khách hoặc khi luồng chính quá bận để hiển thị phần tử LCP đó. Cả hai trường hợp này đều có thể làm chậm thời gian LCP của trang.

Đo

Lighthouse sẽ cho thấy kết quả kiểm tra không đạt khi mất nhiều thời gian để thực thi tất cả JavaScript trên một trang.

Một quy trình kiểm tra Lighthouse không thành công cho thấy các tập lệnh mất quá nhiều thời gian để thực thi.

Phân tách gói JavaScript để chỉ gửi mã cần thiết cho tuyến ban đầu khi người dùng tải ứng dụng. Điều này giúp giảm thiểu lượng tập lệnh cần được phân tích cú pháp và biên dịch, nhờ đó thời gian tải trang nhanh hơn.

Các trình đóng gói mô-đun phổ biến như webpack, ParcelRollup cho phép bạn phân tách các gói bằng cách sử dụng lệnh nhập động. Ví dụ: hãy xem xét đoạn mã sau đây cho thấy ví dụ về một phương thức someFunction được kích hoạt khi gửi biểu mẫu.

import moduleA from "library";

form
.addEventListener("submit", e => {
  e
.preventDefault();
  someFunction
();
});

const someFunction = () => {
 
// uses moduleA
}

Trong đó, someFunction sử dụng một mô-đun được nhập từ một thư viện cụ thể. Nếu mô-đun này không được sử dụng ở nơi khác, bạn có thể sửa đổi khối mã để sử dụng tính năng nhập động chỉ tìm nạp mô-đun này khi người dùng gửi biểu mẫu.

form.addEventListener("submit", e => {
  e
.preventDefault();
 
import('library.moduleA')
   
.then(module => module.default) // using the default export
   
.then(() => someFunction())
   
.catch(handleError());
});

const someFunction = () => {
   
// uses moduleA
}

Mã tạo nên mô-đun không được đưa vào gói ban đầu và hiện được tải lười hoặc chỉ được cung cấp cho người dùng khi cần sau khi gửi biểu mẫu. Để cải thiện thêm hiệu suất trang, hãy tải trước các phần quan trọng để ưu tiên và tìm nạp các phần đó sớm hơn.

Mặc dù đoạn mã trước là một ví dụ đơn giản, nhưng việc tải lười các phần phụ thuộc của bên thứ ba không phải là một mẫu phổ biến trong các ứng dụng lớn hơn. Thông thường, các phần phụ thuộc của bên thứ ba được chia thành một gói nhà cung cấp riêng biệt có thể được lưu vào bộ nhớ đệm vì các phần phụ thuộc này không thường xuyên cập nhật. Bạn có thể đọc thêm về cách SplitChunksPlugin có thể giúp bạn thực hiện việc này.

Việc phân tách theo tuyến hoặc cấp thành phần khi sử dụng khung phía máy khách là một phương pháp đơn giản hơn để tải từng phần của ứng dụng. Nhiều khung phổ biến sử dụng webpack cung cấp các tính năng trừu tượng để tải lười dễ dàng hơn so với việc tự mình tìm hiểu các cấu hình.