François Castets

Journal

14 October 202614 October 2026 3 min de lecturemin read Cartographie et géolocalisationMapping and geolocation

Afficher 3 645 marqueurs sur une carte sans faire fondre le téléphonePutting 3,645 markers on a map without melting the phone

Mille marqueurs sur une carte web et le défilement se met à saccader. Regroupement, rendu vectoriel et chargement par zone : ce qui marche vraiment.A thousand markers on a web map and scrolling starts to stutter. Clustering, vector rendering and loading by viewport: what actually works.

Une carte avec trente marqueurs, tout le monde sait faire. Une carte avec 3 645 marqueurs, c’est un autre métier. Au-delà de mille, la plupart des bibliothèques de cartographie commencent à saccader au défilement, et sur un téléphone d’entrée de gamme, la page devient inutilisable.Anyone can build a map with thirty markers. A map with 3,645 markers is a different trade. Past a thousand, most mapping libraries start stuttering when you pan, and on an entry-level phone the page becomes unusable.

Le problème n'est pas la carte, ce sont les éléments HTMLThe problem is not the map, it is the HTML elements

Par défaut, chaque marqueur est un élément HTML posé par-dessus la carte, repositionné à chaque mouvement. Trois mille éléments à repositionner soixante fois par seconde, c’est trois mille calculs de style par image. Le navigateur n’y arrive pas, et le ventilateur du portable se met en route.By default, each marker is an HTML element laid over the map and repositioned on every movement. Three thousand elements repositioned sixty times a second means three thousand style calculations per frame. The browser cannot keep up, and the laptop fan spins up.

La solution tient en un changement de couche : les marqueurs ne sont plus des éléments HTML, mais des points dessinés dans un canevas, rendus par la carte graphique via WebGL. Le navigateur n’a plus trois mille objets à suivre, il a une seule surface à redessiner. Le coût ne dépend plus vraiment du nombre de points.The fix is a change of layer: markers stop being HTML elements and become points drawn into a canvas, rendered by the graphics card through WebGL. The browser no longer tracks three thousand objects, it redraws a single surface. The cost stops depending much on the number of points.

Le regroupement, pour les yeux autant que pour la machineClustering, for the eyes as much as for the machine

Même avec un rendu rapide, trois mille points sur une carte de France, c’est une bouillie illisible. Les marqueurs proches sont donc regroupés en pastilles portant un nombre, qui se séparent à mesure qu’on zoome. Le calcul des groupes se fait une fois par niveau de zoom, pas à chaque mouvement.Even with fast rendering, three thousand points on a map of France is illegible mush. Nearby markers are therefore grouped into numbered pills that split apart as you zoom in. The grouping is computed once per zoom level, not on every movement.

  • Au niveau national : une pastille par région, une vingtaine de points à dessiner.At country level: one pill per region, about twenty points to draw.
  • Au niveau départemental : une pastille par ville.At area level: one pill per town.
  • À partir du niveau quartier : les salles individuelles, avec leur vignette au survol.From neighbourhood level: individual rooms, with their thumbnail on hover.

Ne charger que ce qu'on regardeLoad only what is on screen

Le dernier levier est le plus simple : la carte ne demande au serveur que les salles contenues dans la zone affichée, avec une marge. Quand le visiteur se déplace, une nouvelle demande part — mais seulement après qu’il a arrêté de bouger, sans quoi on envoie une requête par pixel parcouru.The last lever is the simplest: the map only asks the server for the rooms inside the current viewport, plus a margin. When the visitor pans, a new request goes out — but only after they stop moving, otherwise you fire one request per pixel travelled.

Attendre 250 millisecondes après le dernier mouvement avant d’interroger le serveur : c’est imperceptible pour le visiteur, et cela divise par vingt le nombre de requêtes pendant un déplacement.Waiting 250 milliseconds after the last movement before querying the server is imperceptible to the visitor, and it divides the number of requests during a pan by twenty.

Le résultatThe result

La carte tient 60 images par seconde sur un téléphone de milieu de gamme, avec les 3 645 salles disponibles. Le premier affichage transfère moins de 40 Ko de données de points, parce qu’on n’envoie que les coordonnées et un identifiant — le reste de la fiche n’est demandé qu’au clic.The map holds 60 frames per second on a mid-range phone with all 3,645 rooms available. The first render transfers under 40 KB of point data, because only coordinates and an identifier are sent — the rest of the entry is requested on click.

Ce qui coûte cher sur une carte, ce n’est jamais la carte. Ce sont les milliers de petits objets qu’on pose dessus sans y penser.What costs you on a map is never the map. It is the thousands of little objects you drop on top of it without thinking.

Le projet derrière cette noteThe project behind this note

Tout est parti de Escape Gamer, nouvelle version. La fiche détaille le contexte, ce qui a été construit et ce que le client en a tiré.It all started with Escape Gamer, nouvelle version. The project page covers the context, what was built and what the client got out of it.

À lire ensuiteRead next