Nếu tập lệnh của bên thứ ba đang làm chậm tốc độ tải trang, bạn có hai lựa chọn để cải thiện hiệu suất:
- Hãy xoá nếu phần mở rộng đó không đem lại giá trị rõ ràng cho trang web của bạn.
- Tối ưu hoá quá trình tải.
Bài đăng này giải thích cách tối ưu hoá quá trình tải tập lệnh của bên thứ ba bằng các kỹ thuật sau:
- Sử dụng thuộc tính
async
hoặcdefer
trên thẻ<script>
- Thiết lập kết nối sớm với các nguồn gốc bắt buộc
- Tải từng phần
- Tối ưu hoá cách bạn phân phát tập lệnh của bên thứ ba
Sử dụng async
hoặc defer
Vì tập lệnh đồng bộ làm chậm quá trình tạo và hiển thị DOM, nên bạn phải luôn tải các tập lệnh bên thứ ba một cách không đồng bộ trừ phi tập lệnh phải chạy trước khi có thể hiển thị trang.
Các thuộc tính async
và defer
cho trình duyệt biết rằng trình duyệt có thể tiếp tục phân tích cú pháp HTML trong khi tải tập lệnh trong nền, sau đó thực thi tập lệnh sau khi tải. Bằng cách này, việc tải tập lệnh xuống không chặn quá trình tạo DOM hoặc hiển thị trang, cho phép người dùng xem trang trước khi tất cả tập lệnh tải xong.
<script async src="script.js">
<script defer src="script.js">
Sự khác biệt giữa thuộc tính async
và defer
là khi trình duyệt thực thi các tập lệnh.
async
Các tập lệnh có thuộc tính async
sẽ thực thi ngay cơ hội đầu tiên sau khi tải xuống xong và trước sự kiện tải của cửa sổ. Điều này có nghĩa là có thể (và có thể) tập lệnh async
sẽ không chạy theo thứ tự xuất hiện trong HTML. Điều này cũng có nghĩa là chúng có thể làm gián đoạn quá trình tạo DOM nếu hoàn tất quá trình tải xuống trong khi trình phân tích cú pháp vẫn đang hoạt động.
![Sơ đồ tập lệnh chặn trình phân tích cú pháp với thuộc tính không đồng bộ](https://web.dev/static/articles/efficiently-load-third-party-javascript/image/diagram-parser-blocking-020263bc7658c.png?authuser=5&hl=vi)
async
vẫn có thể chặn phân tích cú pháp HTML.defer
Các tập lệnh có thuộc tính defer
sẽ thực thi sau khi phân tích cú pháp HTML hoàn tất, nhưng trước sự kiện DOMContentLoaded
. defer
đảm bảo rằng các tập lệnh chạy theo thứ tự xuất hiện trong HTML và không chặn trình phân tích cú pháp.
![Sơ đồ luồng trình phân tích cú pháp với một tập lệnh có thuộc tính trì hoãn](https://web.dev/static/articles/efficiently-load-third-party-javascript/image/diagram-parser-flow-a-s-f9a9ef751f974.png?authuser=5&hl=vi)
defer
sẽ chạy cho đến khi trình duyệt hoàn tất phân tích cú pháp HTML.- Hãy sử dụng
async
nếu bạn cần chạy tập lệnh sớm hơn trong quá trình tải. - Sử dụng
defer
cho các tài nguyên ít quan trọng hơn, chẳng hạn như trình phát video dưới màn hình đầu tiên.
Việc sử dụng các thuộc tính này có thể làm tăng đáng kể tốc độ tải trang. Ví dụ: Telegraph đã trì hoãn tất cả các tập lệnh của họ, bao gồm cả quảng cáo và số liệu phân tích, đồng thời cải thiện thời gian tải quảng cáo thêm trung bình 4 giây.
Thiết lập kết nối sớm với các nguồn gốc bắt buộc
Bạn có thể tiết kiệm 100–500 mili giây bằng cách thiết lập kết nối sớm với các nguồn gốc quan trọng của bên thứ ba.
2 loại <link>
, preconnect
và dns-prefetch
, có thể trợ giúp tại đây:
preconnect
<link rel="preconnect">
cho trình duyệt biết rằng trang của bạn muốn thiết lập kết nối đến một nguồn khác và bạn muốn quá trình này bắt đầu càng sớm càng tốt. Khi trình duyệt yêu cầu một tài nguyên từ nguồn gốc được kết nối trước, quá trình tải xuống sẽ bắt đầu ngay lập tức.
<link rel="preconnect" href="https://cdn.example.com">
dns-prefetch
<link rel="dns-prefetch>
xử lý một tập hợp con nhỏ mà <link rel="preconnect">
xử lý. Việc thiết lập kết nối bao gồm việc tra cứu DNS và quá trình bắt tay TCP, cũng như đối với các nguồn gốc bảo mật, quy trình thương lượng TLS.
dns-prefetch
yêu cầu trình duyệt chỉ phân giải DNS của một miền cụ thể trước khi miền đó được gọi một cách rõ ràng.
Gợi ý preconnect
chỉ nên sử dụng cho các kết nối quan trọng nhất. Đối với các miền bên thứ ba ít quan trọng hơn, hãy sử dụng <link rel=dns-prefetch>
.
<link rel="dns-prefetch" href="http://example.com">
Hỗ trợ trình duyệt cho dns-prefetch
hơi khác so với hỗ trợ preconnect
, vì vậy dns-prefetch
có thể đóng vai trò dự phòng cho các trình duyệt không hỗ trợ preconnect
. Sử dụng các thẻ liên kết riêng biệt để triển khai tính năng này một cách an toàn:
<link rel="preconnect" href="http://example.com">
<link rel="dns-prefetch" href="http://example.com">
Tải từng phần tài nguyên của bên thứ ba
Tài nguyên bên thứ ba được nhúng có thể làm chậm đáng kể quá trình tải trang nếu chúng được thiết kế không đúng cách. Nếu những quảng cáo đó không quan trọng hoặc nằm dưới màn hình đầu tiên (tức là nếu người dùng phải cuộn để xem), thì tải từng phần là một cách hiệu quả để cải thiện tốc độ trang và chỉ số hiển thị. Bằng cách này, người dùng nhận được nội dung trang chính nhanh hơn và có trải nghiệm tốt hơn.
![Sơ đồ một trang web hiển thị trên thiết bị di động với nội dung có thể cuộn mở rộng ra ngoài màn hình. Nội dung dưới màn hình đầu tiên bị giảm độ bão hoà vì chưa được tải.](https://web.dev/static/articles/efficiently-load-third-party-javascript/image/a-diagram-a-webpage-show-0c848a2212482.png?authuser=5&hl=vi)
Một phương pháp hiệu quả là tải từng phần nội dung của bên thứ ba sau khi nội dung trang chính tải xong. Quảng cáo là một lựa chọn phù hợp cho phương pháp này.
Quảng cáo là nguồn thu nhập quan trọng của nhiều trang web, nhưng người dùng luôn tìm kiếm nội dung. Bằng cách tải quảng cáo từng phần và phân phối nội dung chính nhanh hơn, bạn có thể tăng tỷ lệ phần trăm khả năng xem tổng thể của quảng cáo. Ví dụ: MediaVine đã chuyển sang quảng cáo tải từng phần và nhận thấy tốc độ tải trang cải thiện 200%. Google Ad Manager có tài liệu về cách tải quảng cáo từng phần.
Bạn cũng có thể thiết lập để nội dung của bên thứ ba chỉ tải khi người dùng cuộn đến phần đó trên trang lần đầu tiên.
Intersection Observer là API trình duyệt phát hiện hiệu quả thời điểm một phần tử vào hoặc thoát khỏi khung nhìn của trình duyệt. Bạn có thể sử dụng API này để triển khai kỹ thuật này. lazysizes là một thư viện JavaScript phổ biến dành cho việc tải từng phần hình ảnh và iframes
.
Hộp cát về quyền riêng tư hỗ trợ hoạt động nhúng và tiện ích trên YouTube.
Giao diện này cũng hỗ trợ không bắt buộc cho Intersection Observer.
Việc sử dụng thuộc tính loading
cho hình ảnh và iframe tải từng phần là một giải pháp thay thế tuyệt vời cho các kỹ thuật JavaScript và gần đây, tính năng này đã có trong Chrome 76!
Tối ưu hoá cách bạn phân phát tập lệnh của bên thứ ba
Sau đây là một số chiến lược đề xuất để tối ưu hoá việc sử dụng tập lệnh của bên thứ ba.
Dịch vụ lưu trữ CDN của bên thứ ba
Các nhà cung cấp bên thứ ba thường cung cấp URL cho các tệp JavaScript mà họ lưu trữ, thường là trên mạng phân phối nội dung (CDN). Lợi ích của phương pháp này là bạn có thể bắt đầu nhanh chóng (chỉ cần sao chép và dán URL) mà không phải tốn chi phí bảo trì. Nhà cung cấp bên thứ ba xử lý việc cập nhật tập lệnh và cấu hình máy chủ.
Tuy nhiên, vì chúng không có cùng nguồn gốc với các tài nguyên còn lại, nên việc tải tệp từ CDN công khai sẽ phát sinh chi phí mạng. Trình duyệt cần tiến hành tra cứu DNS, thiết lập kết nối HTTP mới, và đối với các nguồn gốc bảo mật, hãy bắt tay SSL với máy chủ của nhà cung cấp.
Khi sử dụng tệp từ máy chủ của bên thứ ba, bạn hiếm khi có quyền kiểm soát việc lưu vào bộ nhớ đệm. Việc phụ thuộc vào chiến lược lưu vào bộ nhớ đệm của người khác có thể khiến các tập lệnh được tìm nạp lại từ mạng quá thường xuyên.
Tập lệnh bên thứ ba tự lưu trữ
Các tập lệnh của bên thứ ba tự lưu trữ là một lựa chọn mang lại cho bạn nhiều quyền kiểm soát hơn đối với quá trình tải của một tập lệnh. Khi tự tổ chức, bạn có thể:
- Giảm thiểu thao tác tra cứu DNS và thời gian khứ hồi.
- Cải thiện tiêu đề lưu vào bộ nhớ đệm HTTP.
- Hãy tận dụng HTTP/2 hoặc HTTP/3 mới hơn.
Ví dụ: Casper đã cố gắng giảm 1, 7 giây thời gian tải bằng cách tự lưu trữ một tập lệnh thử nghiệm A/B.
Tuy nhiên, việc tự lưu trữ có một nhược điểm lớn là tập lệnh có thể bị lỗi thời và sẽ không nhận được bản cập nhật tự động khi có thay đổi về API hoặc bản sửa lỗi bảo mật.
Sử dụng trình chạy dịch vụ để lưu tập lệnh vào bộ nhớ đệm từ máy chủ của bên thứ ba
Bạn có thể sử dụng trình chạy dịch vụ để lưu các tập lệnh từ máy chủ của bên thứ ba vào bộ nhớ đệm thay vì tự lưu trữ. Điều này giúp bạn kiểm soát tốt hơn việc lưu vào bộ nhớ đệm, trong khi vẫn duy trì được các lợi ích của CDN của bên thứ ba.
Bạn có thể kiểm soát tần suất tìm nạp lại tập lệnh từ mạng và tạo chiến lược tải để điều tiết các yêu cầu về tài nguyên không thiết yếu của bên thứ ba cho đến khi người dùng đến được một lượt tương tác quan trọng trên trang.
Với preconnect
, bạn có thể thiết lập các kết nối sớm đồng thời giúp giảm chi phí mạng.