Ajax enlève le gros clignotement du Web

Je viens d’essayer Google Maps et j’ai déplacé la carte plusieurs fois juste pour vérifier : pas de page blanche, pas de gros rechargement. Les nouvelles rues arrivent pendant que la carte reste sous la souris. Le Web vient de bouger.

Le nom Ajax rassemble des pièces déjà disponibles : HTML et CSS pour la page, le DOM pour sa structure, JavaScript pour coordonner et XMLHttpRequest pour parler au serveur en arrière-plan. Au lieu de demander tout le document, le navigateur demande les données d’une région, puis remplace seulement les nœuds concernés.

Dans Internet Explorer, un petit appel ressemble encore à ceci :

var xhr = new ActiveXObject("Microsoft.XMLHTTP");
xhr.open("GET", "/clients/recherche?q=velo", true);
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
        if (xhr.status == 200) {
            afficherResultats(xhr.responseXML);
        } else {
            afficherErreur("Recherche impossible.");
        }
    }
};
xhr.send(null);

Le true rend l’appel asynchrone. JavaScript rend la main au navigateur, qui peut repeindre et recevoir d’autres gestes. Plus tard, la pile réseau signale un changement d’état et le callback s’exécute dans la boucle d’événements. Ce n’est pas un deuxième thread qui peut modifier le DOM n’importe quand; les callbacks se succèdent, mais leur ordre de retour ne correspond pas forcément à l’ordre de départ.

Si la personne tape v, vé, puis vélo, trois recherches peuvent partir. La réponse à v peut arriver après celle de vélo et écraser le résultat récent. Je conserve un numéro :

requête 41: "v"
requête 42: "vé"
requête 43: "vélo"  ← seule réponse encore autorisée à mettre l'écran à jour

On peut aussi annuler la requête précédente ou attendre un court délai après la dernière touche. Pour une écriture, annuler côté navigateur ne garantit pas que le serveur n’a rien reçu. L’opération garde un identifiant unique et le serveur reste responsable de la déduplication.

La carte utilise une autre idée importante : découper les images en tuiles. La position et le niveau de zoom déterminent les tuiles visibles. JavaScript demande d’abord celles au centre, réutilise le cache pour les zones déjà vues et remplace progressivement une image grossière par des détails. L’interface bouge parce que le réseau n’est plus dans le chemin de chaque geste.

Le navigateur possède maintenant un état riche : sélection, requêtes actives, données affichées, erreurs, parfois modifications non sauvegardées. Je le représenterais explicitement plutôt que dans les couleurs des boutons. Le bouton Précédent et les signets dépendent de l’URL; une navigation importante devrait mettre à jour l’adresse ou au moins offrir un lien partageable. Sinon l’utilisateur retourne à la page d’avant alors qu’il voulait seulement revenir à la carte précédente.

La sécurité reste côté serveur. La politique de même origine empêche normalement le script de lire librement un autre domaine, mais elle ne valide pas les données. Tout paramètre doit être contrôlé et encodé avant d’entrer dans SQL ou le HTML. Insérer directement une réponse contenant du texte utilisateur avec innerHTML peut exécuter un script. Une requête provenant d’une page authentifiée peut aussi envoyer les cookies de session; une action sensible doit vérifier un jeton propre au formulaire, pas seulement le cookie.

Une panne doit être visible et réparable. J’ajoute un délai maximal, un indicateur lié à la demande courante, un bouton de reprise et un état vide distinct d’une erreur. Après trois échecs, je n’affiche pas Loading... pour l’éternité. Le log serveur reçoit un identifiant que le message client peut citer sans dévoiler l’exception.

Pour mon premier écran Ajax, je choisirais une lecture filtrée, instrumenterais durée et ordre, puis simulerais une réponse lente et une erreur 500. La fluidité ne vient pas seulement de XMLHttpRequest; elle vient d’un état explicite qui sait quelle réponse est encore pertinente et comment revenir d’une panne.