Accélérer vos pages Web : quelques réflexes ⚡️ (partie 2)

Alexandre Cantin
Jul 22 · 7 min read

Cet article sera le deuxième d’une série de trois :

  1. Images et polices personnalisées : https://link.medium.com/Hxw5ex6Zj8
  2. JavaScript et pré-chargement de ressources (cet article)
  3. Contenus animés et LightHouse (à venir)

🃏 3 - JavaScript

L’utilisation du JavaScript a littéralement explosé ses dernières années avec l’avènement de Node.js et ses nombreuses librairies disponibles via NPM, auxquelles s’ajoutent les Single Page Application : Angular, Vue et React.

3.1 - Code splitting

Le terme SPA (Single Page Application) résume à lui tout seul son principe sous-jacent : l’ensemble de notre application est contenu dans une unique page — et par conséquent dans un seul fichier JavaScript, dont la taille est forcément corrélée au nombre de fonctionnalités proposées par votre site.

Bien entendu, au niveau visuel, l’utilisateur a l’impression d’avoir face à lui plusieurs pages grâce à un découpage entre différents composants et notamment à l’aide d’un router. Dans l’univers de React, le router le plus utilisé et connu est le https://github.com/ReactTraining/react-router/ :

import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

import Home from './routes/Home';
import About from './routes/About';

const App = () => (
<Router>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/a-propos" component={About}/>
</Switch>
</Router>
);

Note : des équivalents existent pour Svelte / Vue / Angular mais nous nous focaliserons sur React ici 🙂

Dans cet exemple, notre bundle final contiendra le code de la page d’accueil et de la page “À propos”; mais aussi toutes les autres pages qui seront présentes dans ce router, pouvant se compter par dizaines.
Toutefois, vos utilisateurs parcourent rarement l’ensemble de vos pages mais récupère pourtant tout le JavaScript pour le faire : une optimisation en perspective donc !

Pour pallier ce problème, le code splitting a vu le jour. Ce dernier permet de subdiviser notre bundle en différentes sous-divisions pour n’envoyer aux utilisateurs que le strict nécessaire pour la page courante.

Dans l’écosystème React, cette possibilité nous est offerte par la combinaison de deux fonctions internes :

<Suspense fallback={<div>Chargement...</div>}>
...
</Suspense>

Au final, afin d’obtenir un code-splitting fonctionnel, nous devons adapter l’exemple précédent comme suit :

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
<Router>
<Suspense fallback={<div>Chargement...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/a-propos" component={About}/>
</Switch>
</Suspense>
</Router>
);

Bien sûr, cela peut sembler inutile de réaliser du code-splitting sur un site contenant deux pages 🙂 mais rassurez-vous, l’effet est démultiplié au fur à mesure que le nombre de pages augmente.

3.2 - Poids des librairies externes

3.2.1 - Bundle Phobia

NPM a permis l’introduction de bon nombre de librairies que nous pouvons inclure et utiliser dans notre JavaScript côté front. Toutefois, leur accumulation alourdit petit à petit le poids de nos fichiers et par conséquent ralentit le chargement de notre page. Surveiller le poids des librairies tierces est donc un réflexe nécessaire.

Pour cela, je ne peux que vous conseiller le site BundlePhobia dont le nom est éloquent : le site est à destination des développeurs craignant d’alourdir le poids de leur bundle.

Image for post
Image for post

BundlePhobia vous met à disposition un formulaire de recherche vous permettant d’indiquer la librairie à analyser. Il vous renvoie ensuite son poids et une estimation de son temps de chargement :

Image for post
Image for post

N’oubliez pas de vérifier si la librairie en question est aussi tree-shakable. Une librairie tree-shakable est une librairie dont les parties non utilisées seront retirées du bundle final, occasionnant donc une réduction du poids de nos fichiers JavaScript. Par chance, BundlePhobia nous l’indique 🥳

Pour finir, nous avons aussi une liste de librairies alternatives offrant des fonctionnalités similaires :

Image for post
Image for post

3.2.2 — Import Cost

Afin de surveiller le poids de votre librairie d’une manière plus régulière, une extension Visual Studio Code nommée Import Cost vous indique le poids des librairies que vous incorporez dans votre code :

Image for post
Image for post

Vous trouverez cette extension facilement dans le MarketPlace de Visual Studio Code :

Image for post
Image for post

💠 4 - Préchargement de ressources secondaires avec <link rel="preload" />

4.1 - Fonctionnement de preload

Les premiers fichiers téléchargés dans nos pages sont souvent la porte d’entrée pour le téléchargement d’autres fichiers (polices, scripts complémentaires, images…), ceci est d’autant plus vrai depuis l’arrivée de librairies/frameworks comme React, Vue, Angular ou encore Svelte.

Ce fonctionnement ralentit considérablement notre page car plusieurs vagues de téléchargement sont alors nécessaires pour générer le rendu final.

Toutefois, vu que nous connaissons les fichiers qui seront récupérés en deuxième ou troisième vague de téléchargement, ne pourrait-on pas indiquer au navigateur de le pré-télécharger afin de les avoir directement à disposition quand nous en aurons besoin ? C’est tout à fait possible avec <link rel="preload" /> :

<link rel="preload" href="/fonts/custom-font.woff2" as="font">

Dans cet exemple, nous indiquons à notre navigateur de pré-télécharger le fichier /fonts/custom-font.woff2 car nous en aurons besoin pour le premier affichage de notre page.
J'insiste lourdement sur le terme pour le premier affichage de notre page. En effet, si vous indiquez des ressources dont vous ne faites aucun usage direct, vous obtenez alors l'effet inverse : vous consommez des ressources réseaux au détriment de fichiers plus prioritaires ! À utiliser avec intelligence et précision donc 🙂.

D’ailleurs, Google Chrome nous indique si nous avons pré-téléchargé un fichier dont nous ne faisons pas usage dans trois secondes suivant la fin du chargement de la page (événement onload) :

Image for post
Image for post

4.2 - Spécifications

Au niveau de sa composition, cette balise autorise les attributs :

<link rel="preload" as="image" href="small-background.jpg" media="(max-width: 800px)">
<link rel="preload" as="image" href="large-background.jpg" media="(min-width: 801px)">

4.3 - Support navigateur

Au niveau de son support, et aussi bizarre que cela puisse paraître, seul Firefox ne supporte pas nativement l’attribut rel="preload" qui est actuellement au statut expérimental et doit être activé dans la configuration du navigateur. Espérons que cette situation sera rapidement corrigée 🙂.

Image for post
Image for post

Fin de la deuxième partie

Nous voici arrivés à la fin de cette deuxième partie consacrée aux optimisations liées JavaScript et le pré-chargement de ressources.
Dans le prochain et dernier épisode, nous finirons en beauté les contenus animées (vidéos/GIF) et Lighthouse.

Restez connecté 🙂.


🔰 Aller plus loin

Vidéos et articles

Voici un ensemble de ressources pour explorer l’univers de l’optimisation des chargements :

Sur Twitter

CodeShake

Learnings and insights from SFEIR community.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store