Bên cạnh việc loại bỏ các lượt tải tài nguyên không cần thiết, điều tốt nhất bạn có thể làm để cải thiện tốc độ tải trang là giảm thiểu kích thước tải xuống tổng thể bằng cách tối ưu hoá và nén các tài nguyên còn lại.
Kiến thức cơ bản về nén dữ liệu
Sau khi bạn thiết lập trang web để tránh tải xuống bất kỳ tài nguyên nào không sử dụng, bước tiếp theo là nén mọi tài nguyên đủ điều kiện còn lại mà trình duyệt phải tải xuống. Tuỳ thuộc vào loại tài nguyên (văn bản, hình ảnh, phông chữ, v.v.), có nhiều kỹ thuật để bạn lựa chọn: công cụ chung có thể bật trên máy chủ web, tối ưu hoá trước khi xử lý cho các loại nội dung cụ thể và tối ưu hoá theo tài nguyên cụ thể cần có thông tin đầu vào của nhà phát triển.
Để mang lại hiệu suất tốt nhất, bạn cần kết hợp tất cả các kỹ thuật sau:
- Nén là quá trình mã hoá thông tin bằng cách sử dụng ít bit hơn.
- Việc loại bỏ dữ liệu không cần thiết luôn mang lại kết quả tốt nhất.
- Có nhiều kỹ thuật và thuật toán nén khác nhau.
- Bạn sẽ cần nhiều kỹ thuật để đạt được độ nén tốt nhất.
Quá trình giảm kích thước dữ liệu được gọi là nén dữ liệu. Nhiều người đã đóng góp các thuật toán, kỹ thuật và phương pháp tối ưu hoá để cải thiện tỷ lệ nén, tốc độ nén và bộ nhớ cần thiết cho nhiều thuật toán nén.
Việc thảo luận đầy đủ về nén dữ liệu nằm ngoài phạm vi của hướng dẫn này. Tuy nhiên, bạn cần hiểu rõ (ở mức độ tổng quan) cách hoạt động của tính năng nén và các kỹ thuật mà bạn có thể sử dụng để giảm kích thước của nhiều thành phần mà trang của bạn yêu cầu.
Để minh hoạ các nguyên tắc cốt lõi của những kỹ thuật này, hãy xem xét quy trình tối ưu hoá một định dạng tin nhắn văn bản đơn giản được tạo ra chỉ cho ví dụ này:
# Below is a secret message, which consists of a set of headers in
# key-value format followed by a newline and the encrypted message.
format: secret-cipher
date: 08/25/16
AAAZZBBBBEEEMMM EEETTTAAA
- Thông báo có thể chứa chú thích tuỳ ý (đôi khi được gọi là bình luận) được biểu thị bằng tiền tố "#". Chú thích không ảnh hưởng đến ý nghĩa của thông báo hoặc hành vi của thông báo.
- Thông báo có thể chứa tiêu đề, là các cặp khoá-giá trị (được phân tách bằng
":"trong ví dụ trước) xuất hiện ở đầu thông báo. - Thông báo mang tải trọng văn bản.
Có thể làm gì để giảm kích thước của thông báo trước đó, bắt đầu từ 200 ký tự?
- Nhận xét này rất thú vị nhưng không ảnh hưởng đến ý nghĩa của thông báo. Hãy loại bỏ tiếng ồn khi truyền tin nhắn.
- Có nhiều kỹ thuật hay để mã hoá tiêu đề một cách hiệu quả. Ví dụ: nếu biết rằng tất cả thông báo đều có "định dạng" và "ngày", bạn có thể chuyển đổi các thông báo đó thành mã nhận dạng số nguyên ngắn và chỉ gửi các mã nhận dạng đó. Tuy nhiên, điều đó có thể không đúng, vì vậy, tốt nhất là bạn nên tạm thời bỏ qua.
- Nội dung tải trọng chỉ có văn bản. Mặc dù chúng ta không biết nội dung thực sự của nó là gì (rõ ràng là nó đang sử dụng
"secret-cipher"), nhưng chỉ cần nhìn vào văn bản là có thể thấy có rất nhiều nội dung thừa trong đó. Thay vì gửi các chữ cái lặp lại, bạn có thể chỉ cần đếm số chữ cái lặp lại và mã hoá chúng hiệu quả hơn. Ví dụ:"AAA"trở thành"3A", đại diện cho một chuỗi gồm ba chữ A.
Việc kết hợp các kỹ thuật này sẽ tạo ra kết quả sau:
format: secret-cipher
date: 08/25/16
3A2Z4B3E3M 3E3T3A
Thông báo mới dài 56 ký tự, tức là bạn đã nén thông báo gốc 72%. Đó là một mức giảm đáng kể!
Đây là một ví dụ minh hoạ về cách các thuật toán nén có thể giảm kích thước chuyển của tài nguyên dựa trên văn bản một cách hiệu quả. Trên thực tế, thuật toán nén phức tạp hơn nhiều so với ví dụ trước và trên web, thuật toán nén có thể được dùng để giảm đáng kể thời gian tải tài nguyên xuống. Bằng cách áp dụng tính năng nén cho các thành phần dựa trên văn bản, một trang web có thể tốn ít thời gian hơn để tải tài nguyên, nhờ đó người dùng có thể thấy hiệu quả của các tài nguyên đó sớm hơn so với khi không nén.
Giảm thiểu: Tiền xử lý và tối ưu hoá theo bối cảnh cụ thể
Kỹ thuật đầu tiên được thảo luận ở đây là rút gọn. Mặc dù việc rút gọn không hoàn toàn là một thuật toán nén, nhưng đây là một cách để xoá các ký tự không cần thiết và thừa thãi được dùng trong mã nguồn để giúp con người dễ đọc tài nguyên hơn. Tuy nhiên, khả năng đọc đó không cần thiết để duy trì chức năng của mã nguồn đó trên các trang web chính thức và có thể làm chậm quá trình tải tài nguyên trên web.
Rút gọn là một loại hình tối ưu hoá dành riêng cho nội dung, có thể giảm đáng kể kích thước của tài nguyên được phân phối. Đây là những hoạt động tối ưu hoá được áp dụng hiệu quả nhất trong quá trình xây dựng và triển khai. Ví dụ: trình đóng gói là một loại phần mềm thường dùng có thể tự động rút gọn tài nguyên ngay trước khi triển khai mã chính thức mới cho một trang web.
Cách tốt nhất để nén dữ liệu thừa hoặc không cần thiết là loại bỏ dữ liệu đó. Tuy nhiên, bạn không thể xoá dữ liệu tuỳ ý. Tuy nhiên, trong một số bối cảnh mà chúng ta có kiến thức về nội dung cụ thể của định dạng dữ liệu và các thuộc tính của định dạng đó, thì chúng ta có thể giảm đáng kể kích thước của tải trọng mà không ảnh hưởng đến ý nghĩa hoặc chức năng thực tế của tải trọng đó.
<html>
<head>
<style>
/* awesome-container is only used on the landing page */
.awesome-container {
font-size: 120%;
}
.awesome-container {
width: 50%;
}
</style>
</head>
<body>
<!-- awesome container content: START -->
<div>
This is my awesome container, and it is <em>so</em> awesome.
</div>
<!-- awesome container content: END -->
<script>
awesomeAnalytics(); // Beacon conversion metrics
</script>
</body>
</html>
Hãy xem xét đoạn mã HTML trước đó và ba loại nội dung khác nhau mà đoạn mã đó chứa:
- Mã đánh dấu HTML.
- CSS để tuỳ chỉnh cách trình bày của trang.
- JavaScript để hỗ trợ các hoạt động tương tác và các chức năng nâng cao khác của trang.
Mỗi loại nội dung này có các quy tắc khác nhau về nội dung hợp lệ, quy tắc khác nhau về cách chỉ định nhận xét, v.v. Tuy nhiên, câu hỏi còn lại là "làm cách nào để giảm kích thước của trang này?"
- Nhận xét về mã là người bạn tốt nhất của nhà phát triển, nhưng trình duyệt không cần đến chúng! Việc loại bỏ các nhận xét trong CSS (
/* ... */), HTML (<!-- ... -->) và JavaScript (// ...) sẽ giúp giảm tổng kích thước chuyển của trang và các tài nguyên phụ của trang. - Trình nén CSS "thông minh" có thể nhận thấy rằng chúng ta đang sử dụng một cách không hiệu quả để xác định quy tắc cho
.awesome-containervà thu gọn hai nội dung khai báo thành một mà không ảnh hưởng đến bất kỳ kiểu nào khác, giúp tiết kiệm thêm byte. Trong một tập hợp lớn các quy tắc CSS, việc loại bỏ loại dư thừa này có thể tăng lên, nhưng có thể không phải là điều có thể áp dụng một cách quyết liệt, vì các bộ chọn thường nhất thiết phải được sao chép trong các ngữ cảnh khác nhau, chẳng hạn như trong các truy vấn đa phương tiện. - Dấu cách và thẻ là những tiện ích cho nhà phát triển trong HTML, CSS và JavaScript. Một trình nén bổ sung có thể loại bỏ tất cả các thẻ và dấu cách. Không giống như các kỹ thuật loại bỏ trùng lặp khác, bạn có thể áp dụng kiểu tối ưu hoá này một cách khá triệt để, miễn là các dấu cách hoặc thẻ đó không cần thiết cho việc trình bày trang. Ví dụ: bạn nên giữ lại các dấu cách trong các đoạn văn bản của một tài liệu HTML, vì chúng đảm bảo khả năng đọc của nội dung mà người dùng sẽ thực sự nhìn thấy.
<html><head><style>.awesome-container{font-size:120%;width:50%}</style></head><body><div>This is my awesome container, and it is <em>so</em> awesome.</div><script>awesomeAnalytics()</script></body></html>
Sau khi áp dụng các bước trước, trang sẽ giảm từ 516 xuống còn 204 ký tự, tức là tiết kiệm được khoảng 60%. Đúng là không dễ đọc, nhưng không cần dễ đọc thì mới dùng được. Các phương pháp phát triển hiện đại cũng cho phép bạn tách riêng các phiên bản mã nguồn dễ đọc và có định dạng phù hợp khỏi mã được tối ưu hoá mà bạn đưa vào phiên bản chính thức. Khi kết hợp với bản đồ nguồn (cung cấp bản trình bày dễ đọc về mã sản xuất đã chuyển đổi, giúp bạn dễ dàng khắc phục sự cố lỗi trong quá trình sản xuất), bạn có thể vừa có trải nghiệm tốt cho nhà phát triển vừa tối ưu hoá hiệu suất vì lợi ích của trải nghiệm người dùng.
Ví dụ trước minh hoạ một điểm quan trọng: một trình nén đa năng (ví dụ: một trình nén được thiết kế để nén văn bản tuỳ ý) có thể nén trang khá tốt trong ví dụ trước, nhưng trình nén này sẽ không bao giờ biết cách loại bỏ các nhận xét, thu gọn quy tắc CSS hoặc hàng chục hoạt động tối ưu hoá khác dành riêng cho nội dung. Đây là lý do tại sao việc xử lý trước, rút gọn và các hoạt động tối ưu hoá nhận biết theo bối cảnh khác lại quan trọng.
Tương tự, các kỹ thuật được mô tả ở trên có thể được mở rộng ra ngoài các thành phần dựa trên văn bản. Hình ảnh, video và các loại nội dung khác đều chứa các dạng siêu dữ liệu riêng và nhiều tải trọng khác nhau. Ví dụ: bất cứ khi nào bạn chụp ảnh bằng máy ảnh, tệp của ảnh đó thường nhúng nhiều thông tin bổ sung: chế độ cài đặt máy ảnh, vị trí, v.v. Tuỳ thuộc vào ứng dụng của bạn, dữ liệu này có thể rất quan trọng (ví dụ: trang web chia sẻ ảnh) hoặc có thể hoàn toàn không hữu ích. Bạn nên cân nhắc xem có nên xoá trang đó hay không. Trên thực tế, siêu dữ liệu này có thể tăng thêm tối đa hàng chục kilobyte cho mỗi hình ảnh.
Tóm lại, bước đầu tiên để tối ưu hoá hiệu quả của tài sản là tạo một kho lưu trữ các loại nội dung khác nhau và xem xét những loại tối ưu hoá dành riêng cho nội dung mà bạn có thể áp dụng để giảm kích thước của các loại nội dung đó. Sau đó, khi đã tìm ra các cơ hội, hãy tự động hoá các hoạt động tối ưu hoá này bằng cách thêm chúng vào các bước xây dựng và phát hành để đảm bảo rằng các hoạt động tối ưu hoá được áp dụng nhất quán cho mọi bản phát hành mới cho phiên bản chính thức.
Nén văn bản bằng thuật toán nén
Bước tiếp theo để giảm kích thước của thành phần dựa trên văn bản là áp dụng thuật toán nén cho các thành phần đó. Phương pháp này tiến thêm một bước bằng cách tích cực tìm kiếm các mẫu lặp lại trong tải trọng dựa trên văn bản trước khi gửi đến người dùng và giải nén các mẫu đó khi chúng đến trình duyệt của người dùng. Kết quả là các tài nguyên đó được giảm thiểu đáng kể, từ đó giúp thời gian tải xuống nhanh hơn.
- gzip và Brotli là các thuật toán nén thường dùng, hoạt động hiệu quả nhất trên các thành phần dựa trên văn bản: CSS, JavaScript, HTML.
- Tất cả trình duyệt hiện đại đều hỗ trợ phương thức nén gzip và Brotli, đồng thời sẽ thông báo về việc hỗ trợ cả hai phương thức này trong tiêu đề của yêu cầu HTTP
Accept-Encoding. - Bạn phải định cấu hình máy chủ để bật tính năng nén. Phần mềm máy chủ web thường sẽ cho phép các mô-đun nén tài nguyên dựa trên văn bản theo mặc định.
- Bạn có thể tinh chỉnh cả gzip và Brotli để cải thiện tỷ lệ nén bằng cách điều chỉnh mức độ nén. Đối với gzip, chế độ cài đặt nén nằm trong khoảng từ 1 đến 9, trong đó 9 là mức tốt nhất. Đối với Brotli, phạm vi này là từ 0 đến 11, trong đó 11 là mức tốt nhất. Tuy nhiên, chế độ cài đặt độ nén cao hơn sẽ cần nhiều thời gian hơn. Đối với những tài nguyên được nén linh động (tức là tại thời điểm yêu cầu), các chế độ cài đặt ở giữa phạm vi thường mang lại sự cân bằng tốt nhất giữa tỷ lệ nén và tốc độ. Tuy nhiên, bạn có thể nén tĩnh, tức là phản hồi được nén trước thời hạn và do đó có thể sử dụng chế độ cài đặt nén mạnh nhất hiện có cho mỗi thuật toán nén.
- Mạng phân phối nội dung (CDN) thường cung cấp tính năng nén tự động cho các tài nguyên đủ điều kiện. CDN cũng có thể quản lý tính năng nén động và tĩnh cho bạn, giúp bạn bớt lo lắng về một khía cạnh của tính năng nén.
gzip và Brotli là các trình nén phổ biến có thể áp dụng cho mọi luồng byte. Về cơ bản, các thuật toán này ghi nhớ một số nội dung đã kiểm tra trước đó của một tệp, sau đó cố gắng tìm và thay thế các đoạn dữ liệu trùng lặp một cách hiệu quả.
Trên thực tế, cả gzip và Brotli đều hoạt động hiệu quả nhất trên nội dung dựa trên văn bản, thường đạt tỷ lệ nén cao tới 70-90% đối với các tệp lớn hơn. Tuy nhiên, việc chạy các thuật toán này trên những thành phần đã được nén bằng thuật toán thay thế (chẳng hạn như hầu hết các định dạng hình ảnh sử dụng kỹ thuật nén không tổn hao hoặc có tổn hao) sẽ mang lại rất ít hoặc không mang lại sự cải thiện nào.
Tất cả trình duyệt hiện đại đều quảng cáo hỗ trợ gzip và Brotli trong tiêu đề yêu cầu HTTP Accept-Encoding. Tuy nhiên, nhà cung cấp dịch vụ lưu trữ có trách nhiệm đảm bảo rằng máy chủ web được định cấu hình đúng cách để phân phát tài nguyên nén khi ứng dụng yêu cầu.
| Tệp | Thuật toán | Kích thước chưa nén | Kích thước nén | Tỷ số nén |
|---|---|---|---|---|
| angular-1.8.3.js | Brotli | 1.346 KiB | 256 KiB | 81% |
| angular-1.8.3.js | gzip | 1.346 KiB | 329 KiB | 76% |
| angular-1.8.3.min.js | Brotli | 173 KiB | 53 KiB | 69% |
| angular-1.8.3.min.js | gzip | 173 KiB | 60 KiB | 65% |
| jquery-3.7.1.js | Brotli | 302 KiB | 69 KiB | 77% |
| jquery-3.7.1.js | gzip | 302 KiB | 83 KiB | 73% |
| jquery-3.7.1.min.js | Brotli | 85 KiB | 27 KiB | 68% |
| jquery-3.7.1.min.js | gzip | 85 KiB | 30 KiB | 65% |
| lodash-4.17.21.js | Brotli | 531 KiB | 73 KiB | 86% |
| lodash-4.17.21.js | gzip | 531 KiB | 94 KiB | Tăng 82% |
| lodash-4.17.21.min.js | Brotli | 71 KiB | 23 KiB | 68% |
| lodash-4.17.21.min.js | gzip | 71 KiB | 25 KiB | 65% |
Bảng trước cho thấy mức tiết kiệm mà cả phương thức nén Brotli và gzip có thể mang lại cho một vài thư viện JavaScript nổi tiếng. Mức tiết kiệm dao động từ 65% đến 86% tuỳ thuộc vào tệp và thuật toán. Để tham khảo, mức nén tối đa đã được áp dụng cho từng tệp cho cả Brotli và gzip. Nếu có thể, hãy ưu tiên Brotli hơn gzip.
Bật tính năng nén là một trong những cách tối ưu hoá đơn giản và hiệu quả nhất để triển khai. Nếu trang web của bạn không tận dụng được tính năng này, thì bạn đang bỏ lỡ một cơ hội lớn để cải thiện hiệu suất cho người dùng. May mắn là nhiều máy chủ web cung cấp cấu hình mặc định cho phép tối ưu hoá quan trọng này, và đặc biệt là CDN rất hiệu quả trong việc triển khai theo cách cân bằng tốc độ và tỷ lệ nén.
Một cách nhanh chóng để xem hoạt động nén là mở Chrome DevTools, mở bảng điều khiển Mạng, tải một trang mà bạn chọn và quan sát phần dưới cùng của bảng điều khiển mạng.
Giống như hình ảnh trước, bạn sẽ thấy thông tin chi tiết về:
- Số lượng yêu cầu, tức là số lượng tài nguyên được tải cho trang.
- Kích thước chuyển của tất cả các yêu cầu. Chỉ số này phản ánh mức độ hiệu quả của việc nén áp dụng cho bất kỳ tài nguyên nào của trang.
- Kích thước tài nguyên của tất cả các yêu cầu. Chỉ số này phản ánh kích thước của tài nguyên cho trang sau khi giải nén.
Ảnh hưởng đến Core Web Vitals
Bạn không thể đo lường mức độ cải thiện hiệu suất nếu không có các chỉ số phản ánh những điểm cải thiện đó. Sáng kiến Core Web Vitals ra đời nhằm tạo ra và nâng cao nhận thức về các chỉ số phản ánh trải nghiệm thực tế của người dùng. Điều này trái ngược với các chỉ số (chẳng hạn như thời gian tải trang đơn giản) không thể hiện rõ chất lượng trải nghiệm người dùng.
Khi bạn áp dụng các biện pháp tối ưu hoá nêu trong hướng dẫn này cho các tài nguyên trên trang web của mình, thì mức độ ảnh hưởng đến Core Web Vitals có thể khác nhau, tuỳ thuộc vào tài nguyên được tối ưu hoá và(các) chỉ số liên quan. Tuy nhiên, sau đây là một số trường hợp mà việc áp dụng các biện pháp tối ưu hoá này có thể cải thiện Core Web Vitals của trang web:
- Tài nguyên HTML được rút gọn và nén có thể cải thiện việc tải HTML đó, khả năng khám phá các tài nguyên phụ của HTML đó, từ đó cải thiện việc tải các tài nguyên phụ đó. Điều này có thể mang lại lợi ích cho Nội dung lớn nhất hiển thị (LCP) của trang. Mặc dù có thể sử dụng các gợi ý tài nguyên như
rel="preload"để ảnh hưởng đến khả năng khám phá tài nguyên, nhưng việc sử dụng quá nhiều gợi ý có thể gây ra vấn đề về tranh chấp băng thông. Bằng cách đảm bảo phản hồi HTML cho một yêu cầu điều hướng được nén, trình quét tải trước có thể khám phá các tài nguyên trong đó sớm nhất có thể. - Bạn cũng có thể tải một số ứng cử viên LCP sớm hơn bằng cách sử dụng tính năng nén. Ví dụ: hình ảnh SVG là đề xuất LCP có thể giảm thời lượng tải tài nguyên thông qua tính năng nén dựa trên văn bản. Điều này khác với các hoạt động tối ưu hoá mà bạn thực hiện cho các loại hình ảnh khác (vốn được nén bằng các phương thức nén khác), chẳng hạn như cách hình ảnh JPEG sử dụng phương thức nén có tổn hao.
- Ngoài ra, các nút văn bản cũng có thể là phần tử LCP. Cách áp dụng các kỹ thuật được mô tả trong hướng dẫn này phụ thuộc vào việc bạn có đang sử dụng phông chữ web cho văn bản trên trang web hay không. Nếu bạn đang sử dụng phông chữ web, thì các phương pháp hay nhất để tối ưu hoá phông chữ web sẽ được áp dụng. Tuy nhiên, nếu bạn không sử dụng phông chữ web mà sử dụng phông chữ hệ thống hiển thị mà không mất thời gian tải tài nguyên, thì việc rút gọn và nén CSS sẽ giảm thời gian này, tức là quá trình kết xuất các nút văn bản LCP tiềm năng có thể diễn ra sớm hơn.
Kết luận
Cách bạn tối ưu hoá việc mã hoá và chuyển các thành phần dựa trên văn bản là một khái niệm cơ bản về hiệu suất, nhưng lại có tác động lớn. Hãy đảm bảo rằng bạn đang làm mọi thứ có thể để đảm bảo rằng các tài nguyên đủ điều kiện để rút gọn và nén đều được hưởng lợi từ những hoạt động tối ưu hoá đó.
Quan trọng hơn, hãy đảm bảo rằng các quy trình này được tự động hoá. Để rút gọn, hãy sử dụng trình đóng gói để áp dụng tính năng rút gọn cho các tài nguyên đủ điều kiện. Đảm bảo rằng cấu hình máy chủ web của bạn hỗ trợ nén, nhưng hơn thế nữa, hãy sử dụng phương thức nén hiệu quả nhất hiện có. Để thực hiện việc này một cách đơn giản nhất có thể, hãy sử dụng CDN để tự động nén cho bạn, vì CDN không chỉ có thể nén tài nguyên cho bạn mà còn có thể thực hiện việc này rất nhanh chóng.
Bằng cách củng cố các khái niệm về hiệu suất cơ sở này vào cấu trúc của trang web, bạn có thể đảm bảo rằng các nỗ lực tối ưu hoá hiệu suất của mình đang đi đúng hướng và các hoạt động tối ưu hoá tiếp theo có thể dựa trên nền tảng vững chắc của các phương pháp cơ sở hiệu quả.