Attendre le javascript

Hier j’ai tenté de convaincre de mettre les codes javascript à la fin du document. Et là, d’ordinaire, chacun trouve une raison pour ne pas suivre le conseil. Des fois de très bonnes raison, souvent des contestables.

Pourquoi pas ?

L’objection naturelle la plus fréquente est que les utilisateurs risquent de voir la page se construire au fur et à mesure : d’abord une page sans javascript, puis l’ajout des événements, des liens, des transformations du reste de la page.

Tout d’abord, si votre page est inutilisable en attendant javascript, vous avez un problème fondamental. Il vous faut le régler, avant tout, quoi qu’il se passe. Rien à voir avec la performance, mais avec l’accessibilité (au sens large, pas étiquetée « handicapé »).

Un système d’onglets

Pour le reste, je vous propose un cas d’utilisation assez classique : Vous avez plusieurs zones de données, par exemple des paragraphes de texte ou des tableaux. Chaque zone a son propre titre. Sans javascript votre page a un rendu plutôt habituel, mais avec javascript vous utilisez les titres pour en faire une barre d’onglet où un clic fait apparaître le contenu correspondant.

Mettre le javascript en fin de page oblige l’utilisateur a subir la transformation en temps réel : Pendant le chargement de la page l’utilisateur verra la page dans sa version « sans javascript », et une fois la page chargée l’affichage change pour un système à onglet. C’est une expérience désagréable et perturbante, à éviter.

L’astuce

Le petit truc d’insérer un javascript juste en dessous de l’ouverture de la balise <body> ; oui, en haut du document, exceptionnellement. Ce javascript a pour but d’ajouter une classe à votre balise <body>.

<script type="application/javascript">
document.body.className = "js " + document.body.className ;
</script>

Aucun problème de performance, il n’y a pas de téléchargement externe et le code est virtuellement instantané à l’exécution. Ce petit code n’a donc aucun effet négatif.

Par contre il va vous permettre de savoir dès le début du rendu si vous avez une page avec support de javascript ou une page sans support javascript. Vous pourrez préparer les deux types d’affichages en CSS, il suffira de préfixer les règles de la version « avec support javascript » par body.js. A l’usage c’est souple et on se demande pourquoi on ne le faisait pas plus tôt.

Évaluation

Il restera le problème des animations et des gestions javascript complexes, l’astuce ne résolvant que la mise en page. Ce n’est donc par principe la solution à tous les cas d’utilisation. Ca en couvre quelques uns, de manière tout à fait élégante, et vous permettra de gagner en performances en reléguant quelques javascript supplémentaires à la fin de la page.

Ceci dit, que l’utilisateur doive attendre le chargement complet pour un glisser/déposer n’est pas toujours inacceptable si ça permet de servir la page plus rapidement. Il faut aussi garder à l’esprit que votre animation n’aurait pas été disponible plus rapidement dans votre ancien fonctionnement, c’est juste que maintenant l’utilisateur voit le contenu de la page en attendant.

Publié par edaspet

Plus d'informations sur mon profil en ligne

12 réponses sur « Attendre le javascript »

  1. Bon zou, je me sens obligé de commenter à chaque fois, pour la postérité 🙂

    Je me demande donc si, au lieu de toucher au DOM si tôt, il ne serait pas mieux de faire, exceptionnellement, un document.write. Je sais, c’est moche et tout, mais toucher au DOM si tôt n’est pas très joli joli non plus 🙂

  2. Pour l’astuce de la class, moi j’ajoute un id #js sur l’élément (comme ça l’astuce marche pour les scripts qui sont toujours dans le <body>), mais le principe reste le même.

    Sinon, dans le cas ou on a des éléments très long à charger dans la page (au pif les scripts de pub), il ne serait pas plus judicieux d’essayer de placer ceux-ci le plus tard possible dans le code html puis de placer nos scripts juste AVANT afin qu’ils soient exécutés en fin de page mais pas trop tard quand même ?

  3. @Rik: Disons que j’espère toujours avoir un jour un meta « non je n’utilise pas document.write » et voir le navigateur se permettre beaucoup plus d’optimisations et de parallélisation.
    Puis bon, se baser sur document.write imposerait de générer une balise, donc générer sa fermeture à la fin de la page avec un js correspondant. C’est un coup à se planter et à faire l’un sans l’autre.

    @Country: L’identifiant me sert éventuellement pour autre chose. Là c’est vraiment une option parmi d’autres le fait de gérer le js. Je suis plus confortable avec l’idée de voir ça en classe.
    Sinon oui, si tu y arrives mettre les scripts de pub en dernier (après les tiens) c’est probablement une bonne idée. Le problème est qu’ils font quasiment tous des document.write à gogo, donc il ne sont pas souvent déplaçables où tu veux.

  4. Ok, mea culpa, j’avais en tête un truc genre <body class= »document.write(‘js’) »>. Il a fallu que je l’écrive pour me rendre compte que c’est complètement débile. Je demanderais presque au censeur de supprimer ma contribution tellement j’ai honte.

  5. Merci pour ta réponse. Et en effet ceux que j’ai font bien plein de document.write, mais j’essaye de les placer le plus bas possible puis de les repositionner en position absolue en CSS (bon, pas tout le temps parce que parfois c’est pas possible, mais j’essaie).

  6. Tiens je n’avais pas réagi là-dessus.

    C’est une astuce intéressante mais moi qui suis un parano (ça veut dire chieur en jargon technique, comme on le sait tous) : si j’affecte une classe js sur mon body pour cacher, comme dans ton exemple, les éléments associés à des onglets, mais que par manque de bol le JS qui permet de jouer avec les onglets, celui-là-même que je dois aller chercher à la fin de la page, ne se charge pas, bin boum : page à peu près inutilisable.

    J’en déduis qu’il faut vraiment y aller très mollo avec cette technique.

    (je dis ça parce que je suis justement en train d’utiliser un proxy anémique, où ce genre de solution serait plutôt un appeau à enquiquinements)

  7. En même temps Stéphane, si ton js a une erreur tu vas à la base risquer des problèmes. Imagines que que ton js se charge à moitié ? quoi que tu fasses tu auras forcément des emmerdes.

    Là on peut jouer avec le support ou non du navigateur. Après c’est à toi de t’assurer que la plate-forme que tu met en route elle fonctionne. Sinon quoi que tu fasses tu risqueras toujours d’avoir une page qui pose problème. (bref : fixes ton proxy us ou changes en au lieu de reporter le problème sur ton js)

  8. @Éric : « mon », « mon », comme tu y vas. 🙂

    Je parlais dans l’absolu, remplaçons « mon » par « le proxy d’un client lambda dont l’employeur ne considère pas le web comme une priorité », ou « l’ADSL du mec qui n’habite pas Paris Centre », etc.

    Donc selon moi : si le fichier JS est chargé à moitié ou que le JS dudit fichier provoque une erreur, alors le contenu restera exposé. Si j’applique la technique décrite ci-dessus, je cache les contenus sans moyen de les afficher à moins de désactiver les CSS.

  9. Salut, je me dis qu’ajuster la « présentation » du document en CSS selon qu’il y ai du js ou pas, il reste le problème majeur de la gestion des événements sur les onglets. Que t’ai un joli onglet mais aucune réaction au clic, voir pire un suivi du lien pour un mode accessible… Pas convaincu.

  10. Tu peux te permettre de ne montrer que le premier onglet actuellement actif jusqu’à ce que le js soit chargé. Par contre entre temps la page aura déjà pris son allure « avec onglet » et ce premier onglet actif sera lisible.

    Après tout est une histoire de compromis. Je ne donne que le schéma qui doit être celui par défaut. Il y aura des exceptions à gérer (par contre ne pensez pas tous être dans une exception, l’exception doit rester exceptionnelle)

Les commentaires sont fermés.