Jonathan Hervieux

Engineering Manager

@Takima

1. Du vocabulaire

Web Vitals

1. Du vocabulaire

- FCP (First Contentful Paint)

- TTFB (Time To First Byte)

1. Du vocabulaire

- FID (First Input Delay)

1. Du vocabulaire

1. Du vocabulaire

1. Du vocabulaire

  • Core Web Vitals        
    • LCP -> performance de chargement
    • INP -> interactivité
    • CLS -> stabilité visuelle               

 

📝 Take Away

✔️

 

Comment on les mesure ?  

 

2. Comment mesurer les web vitals ? 

LightHouse

Avec une simulation

- DevTools

- Extension (Firefox)

2. Comment mesurer les web vitals ?

Avec une simulation

- DevTools

- Extension (Firefox)

2. Comment mesurer les web vitals ?

- DevTools

- Extension (Firefox)

 

- Sur un outil de CI/CD avec ligthouse-ci

Avec une simulation

2. Comment mesurer les web vitals ?

- DevTools

- Extension (Firefox)

 

- Sur un outil de CI/CD avec ligthouse-ci

Avec une simulation

2. Comment mesurer les web vitals ?

Lighthouse CI Server

- DevTools

 

- Sur un outil de CI/CD avec ligthouse-ci

Avec une simulation

En conditions réelles

(Real User Monitoring)

- librairie js web-vitals

import { getCLS, getFID, getLCP } from 'web-vitals';

getCLS(console.log);
getFID(console.log);
getLCP(console.log);

2. Comment mesurer les web vitals ?

- avec les SDK de vos outils d'observabilité (Datadog, Sentry, ...)

2. Comment mesurer les web vitals ?

2. Comment mesurer les web vitals ?

2. Comment mesurer les web vitals ?

1. Du vocabulaire

  • Core Web Vitals        
  • LCP, INP, CLS...                        

 

📝 Take Away

✔️

✔️

 

Comment on les améliore ?  

 

2. Mesurer les web vitals

  • DevTools / lightouse-ci        
  • RUM (librairie web-vitals)                 

 

✔️

✔️

T = 0

T = beaucoup de temps après T0

html
css
js
png / jpg

temps (ms)

FCP

réseau

CPU

TTI

}

exécution

3. Améliorer les web-vitals

3. Améliorer les web vitals

Envoyer moins de contenu

Images

3. Améliorer les web vitals

WebP

(2010)

AVIF

(2019)

JPEG XL
(2020)

Images

3. Améliorer les web vitals

<picture>
  <source srcset="image.avif" type="image/avif" />
  <source srcset="image.webp" type="image/webp" />
  <source srcset="image.jpeg" type="image/jpeg" />
  <img src="image.jpeg" alt="Image" />
</picture>

Tag picture

Javascript

3. Améliorer les web vitals

webpack-bundle-analyzer

vite-bundle-analyzer

bundlephobia

Javascript

3. Améliorer les web vitals

Minification

 

Tree shaking

Tree shaking

module.exports = {
  plugins: [
    purgecssPlugin({
      content: ["./src/**/*""],
    })
  ],
  build: {
    css: 'lightningcss'
  }
}

Minification

Plugin postcss-purgecss

Automatique ou configurable

vite.config.js

CSS

3. Améliorer les web vitals

Tailwind : automatique depuis la v4

1. Du vocabulaire

  • Les web vitals        
  • FCP, LCP, CLS...                         

 

📝 Take Away

✔️

✔️

2. Mesurer les web vitals

  • DevTools / lightouse-ci        
  • RUM (librairie web-vitals)                   

 

✔️

✔️

3. Améliorer les web vitals

  • Utiliser des formats modernes
  • Réfléchir à ses dépendances
  • Minification + tree shaking
  • S'applique aussi au CSS    

 

✔️

✔️

✔️

✔️

Résultat du build

3. Améliorer les web vitals

https://my-website.com

Compression

3. Améliorer les web vitals

Gzip 

 

Brotli 

--> 453.96 kB (- 73%)

 

--> 363.22 kB (- 78%)

Compression

3. Améliorer les web vitals

import viteCompression from 'vite-plugin-compression';

export default () => {
  return {
    plugins: [
      viteCompression(),
      viteCompression({ algorithm: 'brotliCompress' }),
    ],
  };
};
vite.config.js

1. Du vocabulaire

  • Les web vitals        
  • FCP, LCP, CLS...                         

 

📝 Take Away

✔️

✔️

2. Mesurer les web vitals

  • DevTools / lightouse-ci        
  • RUM (librairie web-vitals)                   

 

✔️

✔️

3. Améliorer les web vitals

  • Utiliser des formats modernes
  • Minification + tree shaking
  • S'applique aussi au CSS
  • Compresser      

 

✔️

✔️

✔️

✔️

T = 0

html
css
js
png / jpg

temps (ms)

FCP

réseau

CPU

TTI

}

exécution

T = un peu moins de temps après

3. Améliorer les web vitals

3. Améliorer les web vitals

Zoom (SPA)

temps (ms)

index.html

main.js

Parsing + exécution

Un gros chunk

App.jsx
import React from 'react';

import Navbar from '../Navbar';
import Shelf from '../Shelf';
import Filter from '../Shelf/Filter';
import FloatCart from '../FloatCart';

const App = () => (
  <>
    <Navbar />
    <main>
      <Filter />
      <Shelf />
    </main>
    <FloatCart />
  <>
);

export default App;

3. Améliorer les web vitals

Code splitting / Lazy Loading

// ...

const App = () => (
  <>
    <Navbar />
    <Routes>
      <Profile path="/profile" />
      <Orders path="/orders" />
      <Products path="/products" />
    </Routes>
    <FloatCart />
  <>
);
App.jsx

3. Améliorer les web vitals

- Import dynamique

 

- React.lazy()

Code splitting / Lazy Loading

3. Améliorer les web vitals

temps (ms)

index.html

main.js

Parsing + exécution

Un gros chunk

3. Améliorer les web vitals

temps (ms)

index.html

main.js

Chunk 1

Chunk 2

Chunk 3

<link rel=”preload”>
<link rel=”prefetch”>

3. Améliorer les web vitals

Ressource hints

Téléchargement + parsing

Téléchargement

App.jsx
const OrdersPage = React.lazy(() => import(/* webpackChunkName: 'orders' */ '../Orders'));
const ProfilePage = React.lazy(() => import(/* webpackChunkName: 'profile' */ '../Profile'));
const ProductsPage = React.lazy(() => import(/* webpackChunkName: 'products' */ '../Products'));
const Cart = React.lazy(() => import(/* webpackChunkName: 'cart' */'../Cart'));
// ...
plugins: [
    // ...
    new PreloadPlugin({
        rel: 'preload',
    	include: ['cart']
    )},
    new PreloadPlugin({
        rel: 'prefetch',
    	include: ['profile', 'products', 'orders']
    )},
],
webpack.config.js

3. Améliorer les web vitals

Preload / prefetch

3. Améliorer les web vitals

Preload / prefetch

temps (ms)

index.html

main.js

Chunk 1

Chunk 2

Chunk 3

3. Améliorer les web vitals

Preconnect

{
  //...
  webpack: {
    plugins: {
      add: [
        new HtmlWebpackPreconnectPlugin(),
      ],
    },
    configure: (webpackConfig) => {
      const { isFound, match } = getPlugin(webpackConfig, pluginByName("HtmlWebpackPlugin"));
      if (isFound) {
        match.userOptions.preconnect = ["http://localhost:8081"];
      }
      return webpackConfig;
    },
  },
};

webpack.config.js

3. Améliorer les web vitals

Preconnect

3. Améliorer les web vitals

Inline JS et CSS

temps (ms)

index.html

main.js

Chunk 1

Chunk 2

Chunk 3

3. Améliorer les web vitals

1. Du vocabulaire

  • Les web vitals        
  • FCP, LCP, CLS...                         

 

📝 Take Away

✔️

✔️

2. Mesurer les web vitals

  • DevTools / lightouse-ci        
  • librairie web-vitals                   

 

✔️

✔️

3. Améliorer les web vitals

  • Utiliser des formats modernes
  • Minification + tree shaking
  • S'applique aussi au CSS
  • Compresser      

 

  • Code splitting + lazy loading    
  • Preload / prefetch
  • Preconnect
  • Inline le code critique

✔️

✔️

✔️

✔️

✔️

✔️

✔️

✔️

Et plein d'autres choses...

stratégie de mise en cache (assets, app shell...)

HTTP2 / CDN

SSR

optimisations propres aux frameworks

Merci !

✉️   jhervieux@takima.fr

jonathan-hervieux

Made with Slides.com