- Một định dạng tệp lưu trữ HTML đơn cho phép trình duyệt web lazy-loading hiệu quả, đạt đồng thời tính tĩnh, tính đơn nhất và hiệu quả trong khi vẫn bao gồm mọi tài nguyên
- Kết hợp HTML gốc và tài nguyên ở dạng tarball phía sau phần đầu HTML và JavaScript, rồi JS chỉ tải những phần cần thiết thông qua HTTP Range request
- Các giải pháp hiện có như SingleFile hay MHTML có tính tĩnh và tính đơn nhất nhưng thiếu hiệu quả, và Gwtar giải quyết điểm này
- Hoạt động chỉ bằng các tính năng chuẩn của trình duyệt mà không cần cấu hình bổ sung phía máy chủ; trong một số môi trường như Cloudflare, có thể xử lý bằng MIME type
x-gwtar
- Đồng thời đảm bảo khả năng lưu trữ lâu dài và khả năng truy cập cho các trang HTML dung lượng lớn, hữu ích cho lưu trữ web dài hạn và bảo quản tài liệu nghiên cứu có thể tái lập
Tổng quan về Gwtar
- Gwtar là một định dạng lưu trữ polyglot mới gồm một tệp HTML duy nhất, trong đó trình duyệt chỉ tải các phần cần thiết thông qua HTTP Range request
- Được dùng để phân phối các kho lưu trữ HTML lớn của Gwern.net
- JS trong phần đầu HTML sẽ dừng việc tải toàn bộ tệp và chỉ gọi các tài nguyên cần thiết bằng yêu cầu từng phần (range request)
- Kết quả là máy chủ chỉ cần cung cấp một tệp HTML duy nhất, nhưng người dùng chỉ tải những tài nguyên họ cần
- Toàn bộ chức năng được triển khai bằng các tính năng chuẩn của trình duyệt, giúp đảm bảo khả năng tương thích trong tương lai
Thế lưỡng nan ba mặt của lưu trữ HTML
- Lưu trữ HTML vốn có giới hạn cũ là chỉ thỏa mãn được hai trong ba yếu tố: tính tĩnh, tính đơn tệp, hiệu quả
- Ví dụ: SingleFile thì tĩnh và đơn tệp nhưng kém hiệu quả, còn WARC thì tĩnh và hiệu quả nhưng không phải một tệp duy nhất
- Snapshot tạo bằng SingleFile cung cấp một trang tĩnh hoàn chỉnh, nhưng inline toàn bộ tài nguyên bằng Base64, khiến kích thước tệp tăng lên tới hàng trăm MB
- Ngay cả khi người dùng chỉ xem một phần của trang, họ vẫn phải tải toàn bộ tệp, gây ra sự kém hiệu quả
- Để giải quyết việc này, Gwern.net từng dùng deconstruct_singlefile.php để tách tài nguyên ra, nhưng như vậy lại mất tính đơn tệp
Cách tiếp cận kỹ thuật của Gwtar
- Tận dụng HTTP Range request để chỉ tải có chọn lọc một phần của tệp
- Áp dụng cấu trúc lưu trữ nối tiếp (concatenated) bằng cách ghép tarball phía sau phần đầu HTML + JS
- Dùng lệnh
window.stop() của JS để dừng tải sau phần đầu, rồi chỉ yêu cầu các tài nguyên cần thiết
- Trình duyệt render như HTML thông thường, còn JS sẽ chặn các yêu cầu tài nguyên và chuyển chúng thành Range request
Tạo và triển khai
- Có thể chuyển đổi HTML SingleFile sang Gwtar bằng script PHP deconstruct_singlefile.php
- Hỗ trợ nén lại JPG/PNG/GIF và thêm dữ liệu PAR2 FEC (sửa lỗi chuyển tiếp)
- Sau khi JS chạy, trình duyệt chỉ tải các tài nguyên cần thiết bằng Range request; nếu tắt JS thì sẽ chuyển sang tải toàn bộ tệp
- Dựa trên tiêu chuẩn nên không cần cấu hình máy chủ hay phần mềm bổ sung, đồng thời có thể phục hồi từ một tệp đơn trở lại HTML nhiều tệp
Hiệu năng và khả năng tương thích
- Nếu không hỗ trợ Range request, toàn bộ tệp sẽ được tải xuống, nhưng có thể bù tốc độ bằng nén gzip/Brotli
- Cloudflare loại bỏ header Range khỏi phản hồi
text/html, vì vậy Gwern.net đặt MIME type là x-gwtar để обход vấn đề này
- Không thể xem tệp ở môi trường local :
- Điều này cũng giống SingleFileZ, vì chính sách bảo mật của trình duyệt (CORS, v.v.) chặn các yêu cầu từ JS
- Dù đáng tiếc, đây được xem là một đánh đổi chấp nhận được; việc duyệt local có thể giải quyết bằng cách chuyển đổi sang tệp không phụ thuộc JS
Tính năng mở rộng
- Có thể đính kèm dữ liệu nhị phân bổ sung ở cuối tệp Gwtar (ví dụ: FEC, chữ ký, metadata)
- Có thể dùng PAR2 để khôi phục khi một phần tệp bị hỏng
- Có thể chèn chữ ký GPG dưới dạng chú thích HTML để xác minh tính toàn vẹn
- Trong các phiên bản tương lai, dự kiến sẽ có xác minh hash tài nguyên, prefetch tự động, nén tích hợp, hỗ trợ nhiều trang
Khả năng ứng dụng
- Phù hợp với các trang HTML lớn hoặc nghiên cứu khoa học có thể tái lập bao gồm dataset nghiên cứu (ví dụ: SQLite3)
- Có thể tải trực tiếp cơ sở dữ liệu bằng Range request trong trình duyệt để phân tích
- Được đề xuất như một định dạng web archiving vừa đảm bảo khả năng bảo tồn dài hạn vừa đảm bảo khả năng truy cập
Giấy phép và phát triển tương lai
- Tài liệu và mã nguồn của Gwtar được phát hành dưới dạng CC-0 public domain
- Ở các phiên bản sau (v2), đang xem xét các nội dung như bắt buộc FEC, nén tích hợp, hỗ trợ nhiều tài liệu, cải thiện khử trùng lặp
1 bình luận
Ý kiến trên Hacker News
Hôm nay tôi mới lần đầu biết đến window.stop()
Hàm này có tác dụng dừng trình duyệt không tải thêm tài nguyên nữa
Các trình duyệt lớn đã hỗ trợ nó hơn 10 năm rồi (tài liệu MDN, Can I Use)
Có thể xem ví dụ sử dụng trong ảnh chụp màn hình này
Tôi đã viết chi tiết hơn trong bài blog của mình
Tuy vậy, nếu muốn tự triển khai tải xuống hoặc lazy-loading trong logic thiên về máy chủ thì đây có thể là một hướng tiếp cận thú vị
Ngoại trừ các tình huống đặc biệt như script khởi tạo hoặc chuyển hướng, thì khó khuyến nghị dùng nó
Tôi đăng các tệp dưới dạng các chunk base64 nén thông qua bundler tự làm, khá giống với cách này
Nếu nó hoạt động trong môi trường chia sẻ tệp đơn như vậy, tôi nghĩ nền tảng có thể sẽ chặn nó
PHP cũng có một tính năng tương tự là __halt_compiler(), tôi từng dùng nó để chèn tài liệu hoặc dữ liệu vào cuối tệp mà không cần comment
Lúc đầu tôi thấy khá thú vị, nhưng rồi lại chần chừ khi thấy định dạng này không thể mở trực tiếp từ tệp cục bộ
Nếu là một định dạng lưu trữ, thì truy cập cục bộ hẳn phải là một trong những trường hợp sử dụng quan trọng
Nhưng nếu không thể mở trực tiếp ở môi trường cục bộ thì lợi thế đó giảm đi rất nhiều (xem khái niệm backdoor pilot)
Ảnh, CSS, JS đều có thể inline bằng data-uri, font cũng vậy
Thậm chí sẽ linh hoạt hơn nếu các định dạng tài liệu của trình xử lý văn bản dùng HTML
python -m http.serverCũng có thể làm bằng lệnh Claude
Nếu tác giả đọc được bài này, tôi muốn định dạng archive có thêm trường ảnh chụp màn hình BASE64, trường mô tả, và timestamp ISO
Xa hơn nữa, sẽ lý tưởng nếu có thể lưu nhiều phiên bản của cùng một URL và có tính năng loại bỏ tài nguyên trùng lặp
Tôi không hiểu vì sao tác giả lại nhìn WARC theo hướng tiêu cực
Ngược lại, Gwtar có vẻ còn phức tạp hơn và kém linh hoạt hơn
Tôi tò mò vì sao định dạng polyglot ZIP/HTML của SingleFile lại bị gọi là “tĩnh và đơn lẻ nhưng kém hiệu quả”
Tôi muốn biết nó kém hiệu quả ở điểm nào so với Gwtar
Điểm mấu chốt là khi trình duyệt yêu cầu, nó có thể lấy đúng phần cần bằng range request thay vì phải tải toàn bộ tệp
Đây thực sự là một ý tưởng rất hay
Tôi nghĩ web app HTML tệp đơn là hình thức phần mềm có khả năng tồn tại lâu dài nhất
Ví dụ tôi đã làm có FuzzyGraph và HyperVault
Tôi cũng từng nghĩ đến việc triển khai thứ tương tự ở cấp Service Worker
Giữ nguyên trang, nhưng chặn mọi yêu cầu HTTP
Cấu trúc sẽ là chỉ nhận một phần HTML như window.stop(), còn phần còn lại xử lý dưới dạng blob tài sản
Nếu đưa chính Service Worker vào dưới dạng dataURI thì nó sẽ thành một tệp đơn hoàn chỉnh
Thú vị đấy, nhưng tôi không rõ vì sao lại cần lazy load với tệp cục bộ
Tệp đó sẽ lớn đến mức nào? Hay là muốn giữ nguyên cơ chế đã triển khai sẵn?
Cần range request để chỉ yêu cầu phần cần thiết thay vì tải toàn bộ qua mạng
Tất nhiên chia thành nhiều tệp là cách phổ biến hơn, nhưng đôi khi quản lý một tệp đơn lại tiện hơn
Có lẽ điều này cũng liên quan đến cấu trúc trang dựa trên MediaWiki của Gwern
Trước đây tôi cũng từng làm một thứ tương tự — dự án Zundler, một cách tiếp cận khá mang tính hack
Nó cũng hoạt động cục bộ, nhưng ban đầu phải giải nén toàn bộ
Tuy nhiên tôi tò mò họ đã vượt qua các giới hạn bảo mật bằng cách nào
Phần mô tả chỉ nhắc đến single-origin nên tôi vẫn chưa hiểu hoàn toàn