Je construis 10MPage.com qui capture l'état d'Internet en 2025. Chaque internaute est autorisé à télécharger une petite image de 64x64 pixels et à contribuer à cette archive.
Comme son nom l'indique, il doit être capable de gérer 10 millions de ces petites images. Lorsque j'ai eu l'idée de ce concept pour la première fois, je me demandais comment les rendre efficacement. Dans cet article, je parlerai de mes premiers essais et de la solution finale.
Avant de continuer, jetez un œil à 10MPage.com et voyez si vous pouvez comprendre comment procéder. Et si vous avez atteint 10 MPage, pourquoi ne pas réclamer une vignette pour vous-même ? :)
Le premier choix que j'ai dû faire était de savoir si je voulais utiliser des éléments HTML ou un canevas plein écran.
J'ai d'abord testé avec des balises
<div> <p>With this CSS:<br> </p> <pre class="brush:php;toolbar:false"> <style> body { margin: 0; padding: 0; overflow: auto; /* Enable scrolling */ } .grid { display: block; position: relative; width: 100%; /* The grid will take the full width */ } .row { display: flex; /* Each row is a flex container */ } .tile { width: 64px; height: 64px; box-sizing: border-box; border: 1px solid #ccc; /* Visual separation between tiles */ } .tile img { width: 64px; height: 64px; object-fit: cover; } </style> </p> <p>Voici à quoi ça ressemble :</p> <p><img src="https://img.php.cn/upload/article/000/000/000/173668501716928.jpg" alt="How I managed to render million small images on a webpage"></p> <p>Ce qui est bien, mais il y a quelques points qui pourraient poser problème :</p> <ul> <li>Défilement du navigateur</li> <li>Grand DOM</li> <li>Chargement paresseux</li> </ul> <h3> Toile </h3> <p>L'approche suivante s'est faite via une toile, pour plus de simplicité j'ai décidé de simplement dessiner un damier. L'ajout du défilement était également simple, voici à quoi cela ressemblait :<br> </p> <pre class="brush:php;toolbar:false"><corps> <toile> <p>Capture d'écran :<br> <img src="https://img.php.cn/upload/article/000/000/000/173668501927013.jpg" alt="How I managed to render million small images on a webpage"></p> <p>Cette approche est intéressante car elle me permet de tout restituer via du code, ce qui facilitera les fonctionnalités plus avancées.</p> <h3> Choisir les balises d'image ou le canevas </h3> <p>En fin de compte, j'ai décidé d'utiliser Canvas car il est plus flexible que les divs. Cela est dû à des éléments tels que le chargement des animations, le défilement fluide, le chargement paresseux et le fait qu'il est entièrement rendu via du code qui donne beaucoup de contrôle. </p> <p>Mais le chargement d'un grand nombre de petites images entraîne beaucoup de surcharge, pour minimiser le fait que je souhaite regrouper les petites images dans des blocs plus grands.</p> <h2> Optimiser la livraison des carreaux </h2> <p>Le chargement de chaque image séparément ajoute beaucoup de requêtes réseau. Calculons rapidement sur un écran 1080p. La largeur est de 1920 pixels, ce qui équivaudrait à 1920/64 = 30 tuiles. Avec une hauteur de 1080 pixels cela deviendrait 1080/64 = ~17 tuiles. Ainsi, pour afficher un plein écran de tuiles sur un écran FullHD, il faudrait rendre 30*17 = 510 petites images. </p><p>Mais il faut pouvoir scroller ! Et lors du défilement, je ne veux pas afficher beaucoup d'icônes de chargement avant le rendu. Cela signifie donc que nous devons également précharger les images environnantes. Si nous voulons précharger autour, nous devrons ajouter huit fois plus de tuiles. Imaginez que le rectangle noir soit l'affichage :</p> <p><img src="https://img.php.cn/upload/article/000/000/000/173668502115888.jpg" alt="How I managed to render million small images on a webpage"></p> <p>*<em>Cela deviendrait 510*8 = 4080 images ! *</em></p> <p>Il n'est pas réaliste de restituer autant d'images aussi rapidement. La solution ? Combinez les tuiles individuelles en blocs plus grands.</p> <p>En utilisant PHP, j'ai écrit un contrôleur qui génère une image contenant 16*16 tuiles. Chaque bloc mesure 64 * 16 = 1024 pixels en largeur et en hauteur. Vous pouvez le voir lorsque vous allez sur 10MPage et regardez dans l'onglet réseau de votre console.</p> <p><img src="https://img.php.cn/upload/article/000/000/000/173668502382486.jpg" alt="How I managed to render million small images on a webpage"></p> <p>Le script ajoutera un point d'interrogation pour les places non remplies.</p> <p>Ainsi, au lieu de 4080 images pour 1920 * 3 = 5760 pixels par 1080 * 3 = 3240 pixels, nous n'avons désormais besoin que de 24 images : 5760 / 1024 = ~6, 3240 / 1024 = ~4 (les deux arrondies), 6* 4 = 24. Ce qui est faisable !</p> <h2> Cacher les blocs </h2> <p>J'ai implémenté quelques éléments pour « cacher » que les tuiles sont chargées dans des blocs plus grands.</p> <h3> L'écran de chargement a toujours des tuiles 64x64 </h3> <p>Écran de chargement<br> <img src="https://img.php.cn/upload/article/000/000/000/173668502441571.jpg" alt="How I managed to render million small images on a webpage"></p> <h3> La grille complète est toujours rendue carrée </h3> <p>Afin de masquer les grands espaces en bas ou à droite de la grille, la grille ne chargera jamais de blocs si elle n'est pas carrée. Vous ne verrez pas de bloc en bas puis un bloc vide à gauche ou à droite de celui-ci.</p> <p>Merci d'avoir lu cet article, j'espère que vous avez appris quelque chose. <br> Si c’est le cas, pourquoi ne pas ajouter votre langage de programmation préféré, votre crypto-monnaie ou votre animal de compagnie à la 10MPage ? C'est gratuit !</p>
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!