Tăng hiệu quả nén với từ điển dùng chung

Nén dữ liệu là một kỹ thuật tối ưu hoá hiệu suất đã được thử nghiệm theo thời gian, giúp giảm kích thước của các tài nguyên trang đủ điều kiện. Trong một số trường hợp, thông thường người dùng chủ yếu sử dụng gzip trên các máy chủ web để nén các tài nguyên trang dựa trên văn bản phổ biến như các tệp HTML, CSS và JavaScript rồi gửi chúng đến máy khách tại nơi có thể giải nén các tệp này. Kết quả là thời gian tải tài nguyên nhanh hơn mà không ảnh hưởng đến hành vi dự kiến của trang.

Mặc dù gzip có hiệu quả cao theo đúng nghĩa của nó, những cải tiến hơn nữa về khả năng nén trên web đã được thực hiện trong những năm gần đây. Vào năm 2016, thuật toán Brotli đã được đưa vào Chrome, mang lại tỷ lệ nén tốt hơn tổng thể cho các tài nguyên đủ điều kiện. Đến cuối năm 2017, tất cả các trình duyệt hiện đại đều hỗ trợ Brotli và việc hỗ trợ máy chủ cho Brotli bắt đầu trở nên rộng rãi hơn. Gần đây hơn, Chrome đã cung cấp tính năng nén ZStandard.

Tuy nhiên, công việc này không dừng lại ở đó! Nhóm Chrome đang nỗ lực làm cho các từ điển dùng chung có thể sử dụng được trên web. Các từ điển này hiện có trong bản dùng thử theo nguyên gốc cho cả Brotli và ZStandard. Từ điển dùng chung có thể bổ sung tính năng nén Brotli và ZStandard để cung cấp tỷ lệ nén cao hơn đáng kể cho các trang web thường xuyên gửi mã được cập nhật và trong một số trường hợp có thể phân phối tỷ lệ nén 90% hoặc tốt hơn. Bài đăng này sẽ đi sâu hơn về cách hoạt động của từ điển dùng chung và cách bạn có thể đăng ký bản dùng thử theo nguyên gốc để sử dụng chúng cho Brotli và ZStandard trên trang web của bạn.

Giải thích từ điển được chia sẻ

Nén là quá trình tìm các chuỗi dư thừa trong một dữ liệu đầu vào và sử dụng thông tin đó để tạo một đầu ra nhỏ hơn nhiều, có thể đảo ngược sau này. Nén hoạt động tốt trên web vì giảm đáng kể thời gian tải tài nguyên. Cả Brotli và ZStandard đều có thể tăng hiệu quả hơn nữa bằng cách sử dụng từ điển nén. Đây là tập hợp các mẫu bổ sung mà các thuật toán này có thể sử dụng trong quá trình nén. Trên thực tế, hiệu quả cao của Brotli đạt được ở mức độ nào đó là nhờ sử dụng từ điển nội bộ.

Tuy nhiên, bạn có thể sử dụng từ điển tùy chỉnh do người dùng tuyển chọn với Brotli và ZStandard có chứa các mẫu dành riêng cho tài nguyên cụ thể. Trong thực tế, từ điển tuỳ chỉnh là một tệp bên ngoài có thể áp dụng cho mọi dữ liệu đầu vào. Từ điển có thể mang tính đặc trưng cao đối với mã sản xuất của một ứng dụng hoặc thực sự là bất kỳ nội dung nào. Khả năng áp dụng một từ điển nhất định vào dữ liệu đầu vào có thể có tác động lớn đến hiệu quả nén tổng thể. Từ điển có độ tương đồng cao với nội dung của một dữ liệu đầu vào sẽ cho ra kết quả đầu ra có tỷ lệ nén cao hơn so với từ điển có nội dung chung chung hoặc không giống nhau.

Dưới đây là một ví dụ về mức độ hiệu quả của từ điển nén tùy chỉnh: giả sử trang web của bạn sử dụng khung Angular và phiên bản hiện tại bạn đang sử dụng là phiên bản 1.7.9. Phiên bản này của khung Angular là khoảng 172 KiB không nén. Khi được nén bằng chế độ cài đặt mặc định của Brotli, kích thước của tệp sẽ trở thành khoảng 53 KiB. Điều này mang lại tỷ lệ nén gần 70%. Tuy nhiên, giả sử bạn quyết định nâng cấp lên Angular 1.8.3 sau này. Do phiên bản Angular này có kích thước tương đương với phiên bản 1.7.9, bạn có thể mong đợi tỷ lệ nén khá giống với phiên bản trước.

Đây là lúc từ điển tùy chỉnh có thể trở nên hữu ích khi sử dụng quy trình được gọi là nén delta. Quá trình này là khi bạn có thể sử dụng từ điển của phiên bản trước của tài nguyên để nén phiên bản mới hơn. Sử dụng ví dụ trước, nếu bạn nén phiên bản 1.8.3 của Angular bằng cách sử dụng phiên bản 1.7.9 làm từ điển, đầu ra sẽ chỉ hơn 4 KiB. Tỷ lệ này thể hiện tỷ lệ nén gần 98%. Rõ ràng, từ điển nén có thể có tác động lớn đến hiệu suất tải và hiệu quả của chúng đã được thể hiện trong các ứng dụng thực tế!

Tuy nhiên, có một thách thức khi làm cho quy trình này hoạt động trên web. Điểm mấu chốt là nếu sử dụng từ điển để nén một tài nguyên, bạn cần có chính từ điển đó để giải nén tài nguyên đó. Quy trình này đã được thử nghiệm trên web trước đây (cụ thể là SDCH), nhưng rất khó triển khai một cách an toàn. Đề xuất mới nhất về tính năng nén từ điển dùng chung này sẽ giải quyết những mối lo ngại đó trong khi vẫn mang lại lợi ích đáng kể cho cả tài nguyên tĩnh và động.

Cách Chrome quảng cáo dịch vụ hỗ trợ cho từ điển dùng chung

Tất cả trình duyệt đều quảng cáo các thuật toán nén mà họ hỗ trợ thông qua tiêu đề của yêu cầu Accept-Encoding. Nội dung của tiêu đề là danh sách mã hoá được hỗ trợ được phân tách bằng dấu phẩy:

Accept-Encoding: gzip, br, zstd

Tiêu đề Accept-Encoding cụ thể này cho biết rằng trình duyệt yêu cầu tài nguyên hỗ trợ các thuật toán nén gzip, Brotli và ZStandard. Sau đó, máy chủ web phản hồi yêu cầu có thể quyết định thuật toán sử dụng khi phản hồi yêu cầu.

Khi bạn bật tính năng hỗ trợ từ điển dùng chung và có sẵn từ điển liên quan cho một tài nguyên, các mã thông báo bổ sung sẽ được thêm vào tiêu đề Accept-Encoding. Các mã thông báo này là br-d đối với Brotli và zstd-d đối với Zstandard. Chrome cũng sẽ bao gồm hàm băm của một từ điển có sẵn. Chúng tôi sẽ đề cập đến dữ liệu này ở phần tiếp theo.

Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:

Nếu máy chủ web được định cấu hình để nhận dạng mã thông báo này và nhận dạng được từ điển, thì máy chủ web có thể phản hồi yêu cầu đó bằng tài nguyên đã được nén bằng từ điển cho chế độ mã hoá thích hợp. Cách đạt được điều này trong thực tế phụ thuộc vào việc yêu cầu dành cho tài nguyên tĩnh hay động.

Nén từ điển dùng chung cho các tài nguyên tĩnh

Tài nguyên trang tĩnh là tài nguyên luôn tạo ra cùng một phản hồi cho một URL được yêu cầu. Các ví dụ phổ biến về tài nguyên trang tĩnh có thể nén là tệp JavaScript và CSS. Các tài nguyên này thường được tạo phiên bản cho mục đích lưu vào bộ nhớ đệm theo một cách nào đó, đôi khi bằng cách băm nội dung của tệp trong tên tệp (ví dụ: styles.abcd1234.css) hoặc một số phương pháp khác để tạo vân tay số cho tài nguyên. Các loại tài nguyên này là ứng cử viên tuyệt vời cho quá trình nén delta mà từ điển dùng chung cung cấp, vì các tài nguyên tĩnh thường được lưu vào bộ nhớ đệm trong thời gian dài và có xu hướng được cập nhật với một số tần suất.

Bạn có thể chỉ định từ điển cho tài nguyên tĩnh bằng cách thiết lập tiêu đề phản hồi Use-As-Dictionary cho tài nguyên đó. Tiêu đề nhận một trong một vài cặp giá trị/khoá, nhưng cặp giá trị bắt buộc duy nhất là match chấp nhận cú pháp URLPattern chỉ định đường dẫn tài nguyên nơi sử dụng từ điển:

Use-As-Dictionary: match="/dist/styles.*.css"

Hãy coi tiêu đề Use-As-Dictionary là một cơ chế áp dụng cho các phiên bản sau này của tài nguyên khớp với mẫu được chỉ định trong đó. Giả sử trang web của bạn giao tất cả các kiểu trong một tệp CSS duy nhất. Để đơn giản, hãy giả sử phiên bản đầu tiên của tài nguyên đó nằm tại /dist/styles.v1.css và được gửi cùng với một tiêu đề phản hồi Use-As-Dictionary chứa giá trị match/dist/styles.*.css.

Sau một thời gian, bạn cập nhật CSS của trang web và gửi phiên bản mới của CSS đó tại /dist/styles.v2.css. Vì giá trị match dùng trong tiêu đề phản hồi Use-As-Dictionary của phiên bản trước áp dụng cho yêu cầu này, nên trình duyệt sẽ gửi tiêu đề Available-Dictionary chứa giá trị băm của từ điển được mã hoá dưới dạng chuỗi byte trường có cấu trúc:

Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:

Tại thời điểm này, máy chủ phải định cấu hình nén ở phía máy chủ để đảm bảo sử dụng từ điển phù hợp. Sau đó, tài nguyên được nén bằng từ điển đó sẽ được gửi và từ điển có sẵn trong bộ nhớ đệm của trình duyệt của người dùng sẽ được dùng để giải nén tài nguyên đó.

Nếu bạn thường xuyên gửi mã mới cho trang web của mình, thì phương pháp nén delta có thể rất hữu ích. Tuy nhiên, quá trình này rất linh hoạt. Nếu trình duyệt không xác định được rằng có từ điển nào trong bộ nhớ đệm của trình duyệt hay không, thì trình duyệt sẽ không chỉ định mã thông báo br-d hoặc zstd-d bổ sung trong tiêu đề Accept-Encoding. Trong trường hợp đó, quy trình nén tiêu chuẩn sẽ được áp dụng.

Nén từ điển dùng chung cho các tài nguyên động

Các tài nguyên động cũng có thể hưởng lợi từ tính năng nén từ điển dùng chung. Tài nguyên động là những tài nguyên thay đổi dựa trên ngữ cảnh—chẳng hạn như trang web tin tức nơi trang chính được cập nhật thường xuyên dưới dạng thời điểm tin tức. Tài liệu HTML thường là tài nguyên động. Trong những trường hợp như vậy, từ điển có thể chứa hầu hết cấu trúc HTML phổ biến của trang web và mã mẫu dẫn đến các trang nén nơi chỉ gửi các phần duy nhất của mỗi trang.

Do bản chất của tài nguyên được tạo động, bạn phải tải từ điển trên ứng dụng để sử dụng sau này. Việc tải trước một từ điển có nghĩa là việc áp dụng quá trình nén từ điển được chia sẻ cho các tài nguyên động chỉ mang tính suy đoán. Hy vọng trong những trường hợp như vậy là trang web của bạn nhận được đủ lưu lượng truy cập để chi phí từ điển có thể được khấu hao qua một số lượng lớn các điều hướng. Nếu bạn quyết định dùng thử, bước đầu tiên là chỉ định vị trí của từ điển thông qua phần tử <link> trong HTML của trang:

<link rel="dictionary" href="/dictionary.dat">

Khi gặp phần tử <link> này, Chrome có thể tìm nạp từ điển khi trang ở trạng thái rảnh và ở mức ưu tiên thấp để tránh tranh chấp băng thông. Bản thân phản hồi cho từ điển phải chỉ định tiêu đề Use-As-Dictionary và chỉ định đường dẫn tài nguyên động mà tiêu đề đó áp dụng:

Use-As-Dictionary: match="/product/*"

Từ đây, luồng phần lớn giống như đối với tài nguyên tĩnh. Trình duyệt sẽ thấy rằng từ điển tự áp dụng cho các tài nguyên phù hợp và trình duyệt sẽ đính kèm tiêu đề Available-Dictionary vào yêu cầu kèm theo hàm băm về nội dung của từ điển, tương tự như luồng tài nguyên tĩnh đã giải thích trước đó.

Nén các tài nguyên tĩnh tại thời gian xây dựng

Nếu đã quen thuộc với các trình đóng gói, bạn có thể đã quen thuộc với nhiều trình bổ trợ có thể nén tài nguyên trong thời gian xây dựng, sau đó phân phát các tài nguyên được nén đó. Ví dụ: Apache cho phép bạn sử dụng lệnh để phân phát các tài nguyên được nén sẵn đó tại thời điểm yêu cầu.

Hầu hết các trình đóng gói dựa trên Node.js có hỗ trợ nén đều sử dụng thư viện Zlib tích hợp của Node. Zlib hỗ trợ các Brotli và các trình đóng gói sử dụng giao diện này thường cung cấp giao diện để chuyển trực tiếp các tuỳ chọn vào Zlib, giúp hỗ trợ nén bằng từ điển. Dưới đây là một số trình đóng gói hỗ trợ sử dụng từ điển:

Lưu ý rằng các từ điển có sẵn cho mọi phiên bản tài nguyên đã cho có thể sử dụng một trong bất kỳ phiên bản tài nguyên nào trước đó. Điều này có nghĩa là bạn sẽ cần phân tích lưu lượng truy cập của người dùng để lên kế hoạch cho phù hợp. Hãy cố gắng tạo ra sự cân bằng và tạo ra những tài nguyên mang lại lợi ích cho số người dùng cũ nhiều nhất có thể. Nhà cung cấp CDN hiện đang thử nghiệm nén từ điển được chia sẻ. Chưa có cách triển khai nào để sử dụng công khai, nhưng chúng tôi hy vọng điều đó sẽ thay đổi!

Hãy dùng thử ngay!

Việc tích hợp tính năng nén từ điển được chia sẻ với khả năng nén hiện có của trình duyệt có thể cải thiện đáng kể hiệu suất tải cho những trang web thường xuyên gửi mã sản xuất được cập nhật và nhận được lưu lượng truy cập đáng kể từ khách truy cập cũ. Nếu bạn muốn thử nén từ điển được chia sẻ, bạn có hai lựa chọn:

  1. Nếu chỉ muốn tự mình chỉnh sửa tính năng nén từ điển dùng chung để tìm hiểu cách hoạt động của tính năng này, bạn có thể bật tính năng thử nghiệm Truyền tải từ điển nén trên trang chrome://flags.
  2. Nếu bạn muốn dùng thử tính năng này trên trang web phát hành chính thức của mình và xem lợi ích của việc nén từ điển dùng chung đối với người dùng thực, hãy đăng ký bản dùng thử theo nguyên gốc để nhận mã thông báo và tìm hiểu cách hoạt động của bản dùng thử theo nguyên gốc.

Kết luận

Chúng tôi rất vui mừng về bước tiến lớn này trong công nghệ nén trên web, và nó có thể giúp các ứng dụng hiện có mà mọi người sử dụng mỗi ngày nhanh hơn bao nhiêu. Chúng tôi khuyến khích bạn dùng thử và quan trọng nhất là chúng tôi muốn lắng nghe suy nghĩ của bạn nếu bạn làm như vậy! Nếu bạn phát hiện lỗi, hãy gửi báo cáo lỗi đó tại crbug.com. Để xem các tài nguyên và công cụ khác, hãy truy cập vào use-as-từ sử dụng.com. Cuối cùng, nếu bạn muốn tìm hiểu sâu hơn về cách thức hoạt động của tất cả lỗi này, bạn nên sử dụng phần giải thích để xem tiếp!