Les limites de mémoire du navigateur lors du traitement de fichiers
Mon fichier ne fait que 15 MB. Pourquoi l'onglet a-t-il manqué de mémoire ?
Le fichier sur le disque, c'est la version compressée
Tout le malentendu tient en une phrase : le chiffre affiché par le gestionnaire de fichiers est la taille des données compressées, et rien ne peut être traité tant que c'est compressé. Pour redimensionner, recompresser, convertir ou analyser une image, il faut d'abord la décoder en pixels bruts, et les pixels bruts sont énormes.
Le calcul est simple. En mémoire, un pixel occupe normalement quatre octets : rouge, vert, bleu et alpha. Une photographie de 4000 × 3000 fait douze millions de pixels, donc le bitmap décodé pèse environ 48 MB. Le JPEG dont elle vient faisait peut-être 4 MB. Le fichier a été multiplié par douze avant même que le travail ne commence.
| Dimensions | Pixels | Bitmap décodé |
|---|---|---|
| 1920 × 1080 | 2,1 millions | environ 8 MB |
| 4000 × 3000 | 12 millions | environ 48 MB |
| 6000 × 4000 | 24 millions | environ 96 MB |
| 10000 × 10000 | 100 millions | environ 400 MB |
Et une seule copie ne suffit jamais
Une chaîne de traitement réaliste conserve plusieurs copies à la fois : les octets compressés en entrée, le bitmap source décodé, un bitmap de sortie aux nouvelles dimensions, les tampons internes de l'encodeur et le résultat compressé. Un outil qui affiche en plus un aperçu en garde une de plus. Pour la photographie de 4000 × 3000 ci-dessus, un pic de mémoire de travail de deux à trois cents mégaoctets est tout à fait banal, pour un fichier qui semblait faire 4 MB.
La rastérisation d'un PDF se comporte de la même façon, page par page : une page A4 rendue à 300 DPI fait environ 2480 × 3508 pixels, soit à peu près 35 MB une fois décodée, et un outil qui rend plusieurs pages à la fois multiplie ce chiffre. La vidéo est encore pire, car un décodeur doit garder plusieurs images de référence en mémoire en même temps.
Où se situent les vrais plafonds
- Le budget mémoire d'un onglet est fixé par le navigateur, pas par le site, et il est inférieur à la mémoire installée sur la machine. Il se réduit encore quand d'autres onglets travaillent.
- Les modules WebAssembly compilés pour le modèle mémoire 32 bits courant peuvent adresser au maximum quatre gibioctets, et les navigateurs en autorisent souvent nettement moins par instance.
- Chaque tampon a sa propre longueur maximale, bien inférieure à la mémoire totale qu'une page peut utiliser.
- Les systèmes d'exploitation mobiles suppriment un onglet devenu trop volumineux, sans avertissement et sans erreur que la page puisse intercepter.
- La mémoire graphique forme une réserve distincte, plus petite. Un Canvas dépassant la dimension maximale de la plateforme échoue purement et simplement, quelle que soit la mémoire système libre.
Aucune de ces limites n'est publiée sous la forme d'un chiffre unique que l'on pourrait consulter, car elles dépendent du navigateur, de sa version, de l'appareil et de ce qui tourne à côté. C'est là la vraie difficulté : un outil ne peut pas demander quelle quantité de mémoire il a le droit d'utiliser.
Pourquoi les téléphones sont le cas le plus strict
Les téléphones ont moins de mémoire physique, pas de swap au sens où on l'entend sur un ordinateur de bureau, et un système d'exploitation agressif quand il s'agit de la reprendre aux processus d'arrière-plan. Or un onglet de navigateur devient un processus d'arrière-plan dès l'instant où vous répondez à un message. Les navigateurs mobiles s'imposent donc des budgets plus serrés et suppriment un onglet plus vite, et cette suppression vous apparaît en général comme une page qui se recharge en perdant votre travail, pas comme une erreur.
Conséquence pratique : une tâche qui aboutit sur un ordinateur portable peut être impossible sur un téléphone avec le même fichier. Ce n'est pas un défaut de l'outil. C'est une limite matérielle, et la réponse honnête consiste à le dire avant de commencer plutôt qu'à planter à mi-parcours.
Comment se comporte un outil prudent
- Il estime la mémoire de travail à partir des dimensions décodées avant d'allouer quoi que ce soit, et refuse une tâche qui manifestement ne tiendra pas.
- Sur un appareil limité, il traite un fichier à la fois au lieu de lancer un lot en parallèle.
- Il transfère les tampons entre la page et ses workers au lieu de les copier, pour qu'un gros fichier n'existe pas en double.
- Il libère chaque résultat dès qu'il est écrit, et révoque les URL temporaires qui, sinon, maintiendraient les données en vie.
- Il traite en flux, page par page ou image par image, là où le format le permet, au lieu de charger un document entier en mémoire.
- Il plafonne le nombre de pixels qu'il accepte, ce qui empêche aussi un petit fichier se déployant en un Canvas gigantesque de faire tomber l'onglet.
Que faire quand une tâche échoue
- Fermez les autres onglets. Ils se disputent le même budget, et les navigateurs ne le répartissent pas équitablement.
- Traitez moins de fichiers à la fois. Une file d'attente d'un seul fichier est plus lente et a bien plus de chances d'aboutir.
- Réduisez d'abord les dimensions. Diviser par deux le plus grand côté divise la mémoire de travail par quatre, et c'est souvent ce que vous vouliez de toute façon.
- Découpez un gros PDF et traitez les morceaux.
- Passez sur un ordinateur de bureau pour les plus gros travaux. Ce n'est pas un échec du traitement local ; c'est le bon usage du matériel dont vous disposez.
- Redémarrez le navigateur si un onglet est ouvert depuis des jours. Les onglets qui durent accumulent de la mémoire qu'un rechargement libère.
La limite de toute estimation
Les navigateurs n'exposent qu'une indication grossière de la mémoire disponible, et certains n'exposent rien du tout. Tout chiffre affiché par un outil local est donc une estimation construite à partir des dimensions du fichier lui-même et d'un modèle prudent de la chaîne de traitement, pas une lecture faite auprès du système d'exploitation. C'est utile pour décider s'il vaut la peine de tenter une tâche. Ce n'est pas la promesse qu'elle aboutira, car le facteur décisif — ce que fera le reste de l'appareil dans les trente prochaines secondes — échappe à une page web.
Outils pour cette tâche
Sources
- W3C — WebAssembly Core Specification, memory model
- W3C — Device Memory API, and why the value is coarse
- WHATWG — HTML Standard, transferable objects