- Un format d’archive HTML monofichier permettant au navigateur web d’effectuer un chargement différé (lazy-loading) de manière efficace, en incluant toutes les ressources tout en combinant caractère statique, unicité du fichier et efficacité
- Combine un en-tête HTML et JavaScript avec le HTML source et les ressources sous forme de tarball, puis le JS ne charge que les portions nécessaires via des requêtes HTTP Range
- Les solutions existantes comme SingleFile ou MHTML offrent un format statique et monofichier, mais manquent d’efficacité ; Gwtar résout ce problème
- Fonctionne uniquement avec les fonctions standard du navigateur, sans configuration supplémentaire côté serveur ; dans certains environnements comme Cloudflare, il utilise le type MIME
x-gwtar
- Permet d’assurer à la fois la pérennité et l’accessibilité de grandes pages HTML, ce qui le rend utile pour l’archivage web à long terme et la conservation de matériaux de recherche reproductibles
Présentation de Gwtar
- Gwtar est un nouveau format d’archive polyglotte constitué d’un fichier HTML unique, dans lequel le navigateur ne charge que les parties nécessaires via des requêtes HTTP Range
- Utilisé sur Gwern.net pour distribuer de grandes archives HTML
- Le JS de l’en-tête HTML interrompt le téléchargement complet du fichier et ne récupère que les ressources nécessaires via des requêtes partielles (range requests)
- En conséquence, le serveur ne fournit qu’un seul fichier HTML, mais l’utilisateur ne télécharge que les ressources dont il a besoin
- Toutes les fonctionnalités reposent sur les capacités standard du navigateur, ce qui garantit la compatibilité future
Le triple dilemme des archives HTML
- Les archives HTML ont une limite classique : elles ne satisfont généralement que deux critères parmi caractère statique, fichier unique et efficacité
- Exemple : SingleFile est statique et monofichier mais inefficace, tandis que WARC est statique et efficace mais n’est pas un format monofichier
- Les captures générées avec SingleFile fournissent une page entièrement statique, mais intègrent toutes les ressources en Base64, ce qui fait facilement grimper la taille du fichier à plusieurs centaines de Mo
- Même si l’utilisateur ne consulte qu’une petite partie de la page, il doit télécharger l’intégralité du fichier, d’où une forte inefficacité
- Gwern.net a tenté de résoudre ce problème avec deconstruct_singlefile.php pour séparer les ressources, mais au prix de la perte du caractère monofichier
L’approche technique de Gwtar
- Utilise des requêtes HTTP Range pour télécharger sélectivement certaines parties du fichier
- Adopte une structure d’archive concaténée combinant HTML + en-tête JS et, à la suite, un tarball
- La commande JS
window.stop() interrompt le téléchargement après l’en-tête, puis seules les ressources nécessaires sont demandées
- Le navigateur effectue le rendu comme pour un HTML classique, tandis que le JS intercepte les requêtes de ressources pour les convertir en requêtes Range
Génération et implémentation
- Le script PHP deconstruct_singlefile.php permet de convertir un HTML SingleFile en Gwtar
- Prend en charge la recompression JPG/PNG/GIF ainsi que l’ajout de données PAR2 FEC (correction d’erreurs directe)
- Une fois le JS exécuté, le navigateur ne charge via Range que les ressources nécessaires ; si le JS est désactivé, le téléchargement complet du fichier sert de solution de repli
- Basé sur des standards, sans configuration serveur ni logiciel additionnel requis, et le fichier unique peut être restauré en HTML multifichier
Performances et compatibilité
- Si les requêtes Range ne sont pas prises en charge, le fichier entier est téléchargé, mais la compression gzip/Brotli peut compenser en partie la vitesse
- Cloudflare supprime l’en-tête Range des réponses
text/html, donc Gwern.net contourne cela en définissant le type MIME sur x-gwtar
- Consultation locale impossible :
- C’est aussi le cas de SingleFileZ, car les politiques de sécurité du navigateur (CORS, etc.) bloquent les requêtes JS
- C’est regrettable, mais considéré comme un compromis acceptable ; la consultation locale peut être résolue en convertissant vers un format non dépendant du JS
Fonctionnalités étendues
- Il est possible d’ajouter à la fin d’un fichier Gwtar des données binaires supplémentaires (par ex. FEC, signature, métadonnées)
- PAR2 permet de récupérer le fichier en cas de corruption partielle
- Une signature GPG peut être insérée sous forme de commentaire HTML pour permettre la vérification d’intégrité
- Les versions futures prévoient notamment la vérification de hash des ressources, le préchargement automatique, la compression intégrée et la prise en charge de plusieurs pages
Cas d’usage possibles
- Adapté aux grandes pages HTML ou à des recherches scientifiques reproductibles intégrant des jeux de données de recherche (par ex. SQLite3)
- Il devient possible de charger directement une base de données dans le navigateur via des requêtes Range pour l’analyser
- Le format est proposé comme format d’archivage web conciliant à la fois conservation à long terme et accessibilité
Licence et développement futur
- La documentation et le code de Gwtar sont publiés dans le domaine public CC-0
- Pour les versions futures (v2), sont envisagés notamment la généralisation obligatoire du FEC, la compression intégrée, la prise en charge de plusieurs documents et une meilleure déduplication
1 commentaires
Réactions sur Hacker News
Je viens d’apprendre l’existence de window.stop() aujourd’hui
Cette fonction permet d’arrêter le navigateur pour qu’il ne charge plus de ressources
Les principaux navigateurs la prennent déjà en charge depuis plus de 10 ans (documentation MDN, Can I Use)
On peut voir un exemple d’utilisation dans cette capture d’écran
J’ai résumé davantage de détails dans mon billet de blog
En revanche, cela peut être une approche intéressante si l’on veut implémenter soi-même le téléchargement ou le lazy-loading dans une logique centrée serveur
En dehors de cas particuliers comme des scripts d’initialisation ou de redirection, c’est difficile à recommander
Je publie des fichiers sous forme de chunks base64 compressés via un bundler que j’ai fabriqué, et cette méthode y ressemble
Si cela fonctionne dans ce genre d’environnement de partage en fichier unique, je me dis que la plateforme pourrait chercher à le bloquer
Il existe une fonction similaire en PHP, __halt_compiler(), que j’ai déjà utilisée pour ajouter de la documentation ou des données à la fin d’un fichier sans commentaire
Au début, j’ai trouvé ça intéressant, puis j’ai hésité en voyant que ce format ne s’ouvre pas directement en fichier local
Pour un format d’archivage, l’accès local devrait pourtant être l’un des cas d’usage essentiels
Mais si on ne peut pas l’ouvrir directement en local, l’intérêt diminue fortement (voir la notion de backdoor pilot)
Les images, le CSS et le JS peuvent tous être intégrés en ligne via des data-uri, et c’est aussi le cas des polices
D’ailleurs, les formats de documents de traitement de texte auraient sans doute été plus souples s’ils avaient utilisé du HTML
python -m http.serverpour résoudre ça facilementC’est aussi possible avec une commande Claude
Si l’auteur voit ce message, j’aimerais qu’il ajoute au format d’archive un champ de capture d’écran en BASE64, un champ de description et un horodatage ISO
Idéalement, il pourrait aussi permettre de stocker plusieurs versions d’une même URL et proposer une fonction de déduplication des assets
Je ne comprends pas pourquoi l’auteur a une vision négative de WARC
Au contraire, Gwtar me paraît plus complexe et moins souple
Je me demande pourquoi le format polyglotte ZIP/HTML de SingleFile est qualifié de « statique et mono-fichier mais inefficace »
J’aimerais savoir en quoi il est moins efficace que Gwtar
Le point essentiel est de savoir si le navigateur peut récupérer uniquement les portions requises via des range requests, sans devoir télécharger tout le fichier
C’est une idée vraiment géniale
Je pense que les webapps HTML en fichier unique sont la forme de logiciel la plus durable à long terme
Parmi les exemples que j’ai créés, il y a FuzzyGraph et HyperVault
J’avais aussi envisagé d’implémenter quelque chose de similaire au niveau du Service Worker
L’idée serait de laisser la page telle quelle tout en interceptant toutes les requêtes HTTP
Comme avec window.stop(), on ne recevrait qu’une partie du HTML, et le reste serait traité comme des blobs d’assets
En mettant le Service Worker lui-même en dataURI, on obtiendrait un véritable fichier unique
C’est intéressant, mais je ne vois pas bien pourquoi il faudrait du lazy load pour un fichier local
Le fichier est-il censé devenir si gros ? Ou bien s’agit-il simplement de conserver une fonctionnalité déjà implémentée ?
Il faut des range requests pour demander uniquement les parties nécessaires sans tout récupérer depuis le réseau
Bien sûr, il est plus courant de découper cela en plusieurs fichiers, mais il arrive que la gestion d’un fichier unique soit plus pratique
C’est peut-être aussi lié à la structure du site basé sur MediaWiki de Gwern
J’avais moi aussi créé quelque chose de similaire il y a quelque temps — un projet nommé Zundler, avec une approche assez bidouille
Cela fonctionne aussi en local, mais il faut d’abord décompresser l’ensemble
En revanche, je me demande comment les restrictions de sécurité ont été contournées
La description ne mentionne que la question du single-origin, donc j’ai du mal à comprendre complètement