Trong lớp học lập trình này, hiệu suất của trang web sau đây sẽ được cải thiện bằng cách tải trước và tìm nạp trước một số tài nguyên:
Đo lường
Trước tiên, hãy đo lường hiệu suất của trang web trước khi thêm bất kỳ điểm tối ưu hoá nào.
- Để xem trước trang web, hãy nhấn vào Xem ứng dụng, rồi nhấn vào Toàn màn hình
.
Chạy quy trình kiểm tra hiệu suất Lighthouse (Lighthouse > Options (Tuỳ chọn) > Performance (Hiệu suất)) trên phiên bản đang hoạt động của Glitch (xem thêm phần Khám phá các cơ hội cải thiện hiệu suất bằng Lighthouse).
Lighthouse cho thấy quy trình kiểm tra không thành công sau đây đối với một tài nguyên được tìm nạp muộn:

- Nhấn tổ hợp phím `Control+Shift+J` (hoặc `Command+Option+J` trên máy Mac) để mở DevTools.
- Nhấp vào thẻ Mạng.

Tệp main.css
không được một phần tử Link (<link>
) đặt trong tài liệu HTML tìm nạp, mà là một tệp JavaScript riêng biệt, fetch-css.js
, sẽ đính kèm phần tử Link vào DOM sau sự kiện window.onLoad
. Điều này có nghĩa là tệp chỉ được tìm nạp sau khi trình duyệt hoàn tất việc phân tích cú pháp và thực thi tệp JS. Tương tự, phông chữ web (K2D.woff2
) được chỉ định trong main.css
chỉ được tìm nạp một lần sau khi tệp CSS tải xuống xong.
Chuỗi yêu cầu quan trọng thể hiện thứ tự của các tài nguyên được trình duyệt ưu tiên và tìm nạp. Đối với trang web này, trang hiện có dạng như sau:
├─┬ / (initial HTML file)
└── fetch-css.js
└── main.css
└── K2D.woff2
Vì tệp CSS nằm ở cấp thứ ba của chuỗi yêu cầu, nên Lighthouse đã xác định tệp này là một tài nguyên được phát hiện muộn.
Tải trước các tài nguyên quan trọng
Tệp main.css
là một thành phần quan trọng cần thiết ngay khi trang được tải. Đối với các tệp quan trọng như tài nguyên này được tìm nạp muộn trong ứng dụng của bạn, hãy sử dụng thẻ tải trước đường liên kết để thông báo cho trình duyệt tải xuống sớm hơn bằng cách thêm một phần tử Đường liên kết vào đầu tài liệu.
Thêm thẻ tải trước cho ứng dụng này:
<head>
<!-- ... -->
<link rel="preload" href="main.css" as="style">
</head>
Thuộc tính as
được dùng để xác định loại tài nguyên đang được tìm nạp và as="style"
được dùng để tải trước các tệp biểu định kiểu.
Tải lại ứng dụng rồi xem bảng điều khiển Mạng trong Công cụ cho nhà phát triển.

Lưu ý cách trình duyệt tìm nạp tệp CSS trước khi JavaScript chịu trách nhiệm tìm nạp tệp đó hoàn tất quá trình phân tích cú pháp. Với tính năng tải trước, trình duyệt biết cách tìm nạp trước tài nguyên với giả định rằng tài nguyên đó rất quan trọng đối với trang web.
Nếu không được sử dụng đúng cách, tính năng tải trước có thể gây hại cho hiệu suất bằng cách đưa ra các yêu cầu không cần thiết đối với những tài nguyên không được sử dụng. Trong ứng dụng này, details.css
là một tệp CSS khác nằm ở gốc của dự án nhưng được dùng cho một /details route
riêng biệt. Để minh hoạ ví dụ về cách sử dụng không chính xác tính năng tải trước, hãy thêm một gợi ý tải trước cho tài nguyên này.
<head>
<!-- ... -->
<link rel="preload" href="main.css" as="style">
<link rel="preload" href="details.css" as="style">
</head>
Tải lại ứng dụng rồi xem bảng điều khiển Mạng.
Một yêu cầu được đưa ra để truy xuất details.css
mặc dù trang web không sử dụng yêu cầu này.

Chrome sẽ hiển thị cảnh báo trong bảng điều khiển Console khi trang không sử dụng tài nguyên được tải trước trong vòng vài giây sau khi tài nguyên đó được tải.

Hãy sử dụng cảnh báo này làm chỉ báo để xác định xem bạn có tài nguyên được tải trước nào mà trang web của bạn không sử dụng ngay lập tức hay không. Giờ đây, bạn có thể xoá đường liên kết tải trước không cần thiết cho trang này.
<head>
<!-- ... -->
<link rel="preload" href="main.css" as="style">
<link rel="preload" href="details.css" as="style">
</head>
Để xem danh sách tất cả các loại tài nguyên có thể được tìm nạp cùng với các giá trị chính xác cần dùng cho thuộc tính as
, hãy tham khảo bài viết về Tải trước trên MDN.
Tìm nạp trước các tài nguyên trong tương lai
Tìm nạp trước là một gợi ý khác của trình duyệt mà bạn có thể dùng để đưa ra yêu cầu về một tài sản được dùng cho một tuyến điều hướng khác nhưng có mức độ ưu tiên thấp hơn so với các tài sản quan trọng khác cần thiết cho trang hiện tại.
Trong trang web này, khi nhấp vào hình ảnh, bạn sẽ được chuyển đến một tuyến đường details/
riêng.
Một tệp CSS riêng biệt, details.css
, chứa tất cả các kiểu cần thiết cho trang đơn giản này. Thêm một phần tử đường liên kết vào index.html
để tìm nạp trước tài nguyên này.
<head>
<!-- ... -->
<link rel="prefetch" href="details.css">
</head>
Để hiểu cách này kích hoạt yêu cầu đối với tệp, hãy mở bảng điều khiển Mạng trong Công cụ cho nhà phát triển và bỏ chọn tuỳ chọn Tắt bộ nhớ đệm.

Tải lại ứng dụng và lưu ý cách một yêu cầu có mức độ ưu tiên rất thấp được thực hiện cho details.css
sau khi tất cả các tệp khác đã được tìm nạp.

Khi Công cụ cho nhà phát triển đang mở, hãy nhấp vào hình ảnh trên trang web để chuyển đến trang details
.
Vì phần tử liên kết được dùng trong details.html
để tìm nạp details.css
, nên một yêu cầu được đưa ra cho tài nguyên như dự kiến.

Nhấp vào yêu cầu mạng details.css
trong Công cụ cho nhà phát triển để xem thông tin chi tiết. Bạn sẽ nhận thấy rằng tệp được truy xuất từ bộ nhớ đệm của ổ đĩa trên trình duyệt.

Bằng cách tận dụng thời gian chờ của trình duyệt, tính năng tìm nạp trước sẽ đưa ra yêu cầu sớm cho một tài nguyên cần thiết cho một trang khác. Điều này giúp tăng tốc các yêu cầu điều hướng trong tương lai bằng cách cho phép trình duyệt lưu tài sản vào bộ nhớ đệm sớm hơn và phân phát tài sản đó từ bộ nhớ đệm khi cần.
Tải trước và tìm nạp trước bằng webpack
Bài đăng Giảm tải trọng JavaScript bằng cách phân tách mã khám phá việc sử dụng tính năng nhập động để chia một gói thành nhiều đoạn. Điều này được minh hoạ bằng một ứng dụng đơn giản nhập động một mô-đun từ Lodash khi biểu mẫu được gửi.

Bạn có thể truy cập vào Glitch cho ứng dụng này tại đây.
Khối mã sau đây (nằm trong src/index.js,
) chịu trách nhiệm nhập phương thức một cách linh động khi người dùng nhấp vào nút.
form.addEventListener("submit", e => {
e.preventDefault()
import('lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
Việc chia một gói sẽ giúp cải thiện thời gian tải trang bằng cách giảm kích thước ban đầu của gói. Webpack phiên bản 4.6.0 hỗ trợ tải trước hoặc tìm nạp trước các đoạn được nhập động. Lấy ứng dụng này làm ví dụ, phương thức lodash
có thể được tìm nạp trước trong thời gian trình duyệt ở trạng thái rảnh; khi người dùng nhấn nút, sẽ không có độ trễ để tìm nạp tài nguyên.
Sử dụng tham số nhận xét webpackPrefetch
cụ thể trong một lần nhập động để tìm nạp trước một đoạn mã cụ thể.
Sau đây là giao diện của ứng dụng cụ thể này.
form.addEventListener("submit", e => {
e.preventDefault()
import(/* webpackPrefetch: true */ 'lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
Sau khi ứng dụng được tải lại, webpack sẽ chèn một thẻ tìm nạp trước cho tài nguyên vào đầu tài liệu. Bạn có thể thấy điều này trong bảng điều khiển Phần tử trong Công cụ cho nhà phát triển.
Việc quan sát các yêu cầu trong bảng điều khiển Mạng cũng cho thấy rằng đoạn này được tìm nạp với mức độ ưu tiên thấp sau khi tất cả các tài nguyên khác đã được yêu cầu.

Mặc dù tìm nạp trước có ý nghĩa hơn đối với trường hợp sử dụng này, nhưng webpack cũng hỗ trợ tải trước các đoạn được nhập một cách linh động.
import(/* webpackPreload: true */ 'module')
Kết luận
Sau khi hoàn thành lớp học lập trình này, bạn sẽ hiểu rõ cách tải trước hoặc tìm nạp trước một số tài sản có thể cải thiện trải nghiệm người dùng trên trang web của bạn. Điều quan trọng cần lưu ý là bạn không nên sử dụng những kỹ thuật này cho mọi tài nguyên và việc sử dụng không đúng cách có thể làm giảm hiệu suất. Bạn chỉ nhận thấy kết quả tốt nhất khi tải trước hoặc tìm nạp trước một cách chọn lọc.
Tóm tắt:
- Sử dụng preload cho những tài nguyên được phát hiện muộn nhưng lại rất quan trọng đối với trang hiện tại.
- Sử dụng tìm nạp trước cho những tài nguyên cần thiết cho một tuyến đường điều hướng hoặc hành động của người dùng trong tương lai.
Hiện tại, không phải trình duyệt nào cũng hỗ trợ cả tính năng tải trước và tìm nạp trước. Điều này có nghĩa là không phải người dùng nào của ứng dụng cũng nhận thấy hiệu suất được cải thiện.
Nếu bạn muốn biết thêm thông tin về các khía cạnh cụ thể của cách tải trước và tìm nạp trước có thể ảnh hưởng đến trang web của bạn, hãy tham khảo các bài viết sau: