Performance web :

les bases appliquées à React

Jonathan Hervieux @djow__

Jonathan Hervieux

Tech lead

@Takima / @Cartier

1. Du vocabulaire

Indicateurs de performance, les web vitals

1. Du vocabulaire

- FCP (First Contentful Paint)

- TTFB (Time To First Byte)

1. Du vocabulaire

- TBT (Total Blocking Time)

- TTI (Time To Interactive)

1. Du vocabulaire

1. Du vocabulaire

1. Du vocabulaire

  • Les web vitals        
    • LCP -> performance de chargement
    • FID -> interactivité
    • CLS -> stabilité visuelle               

 

📝 Take Away

✔️

 

Comment on les mesure ?  

 

2. Comment mesurer les web vitals ? 

LightHouse

Avec une simulation

- DevTools

2. Comment mesurer les web vitals ?

Avec une simulation

- DevTools

2. Comment mesurer les web vitals ?

- DevTools

 

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

Avec une simulation

2. Comment mesurer les web vitals ?

- 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 ?

2. Comment mesurer les web vitals ?

2. Comment mesurer les web vitals ?

2. Comment mesurer les web vitals ?

1. Du vocabulaire

  • Les web vitals        
  • FCP, LCP, 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

AVIF

JPEG XL

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

Images

3. Améliorer les web vitals

<picture>
  <source srcset="image.jpeg?as=avif&width=800" type="image/avif" />
  <source srcset="image.jpeg?as=webp&width=800" type="image/webp" />
  <source srcset="image.jpeg?width=800" type="image/jpeg" />
  <img src="image.jpeg?width=200" alt="Image" />
</picture>

Exemple avec Parcel

Javascript

3. Améliorer les web vitals

webpack-bundle-analyzer

bundlephobia

Javascript

3. Améliorer les web vitals

Minification

 

Tree shaking

Tree shaking

{
  // ...
  webpack: {
    plugins: {
      add: [
        // ...
        new PurgecssPlugin({
          paths: glob.sync(`${path.join(__dirname, './src')}/**/*`,  { nodir: true }),
        }),
      ]
    }
  }
}

Minification

PurgeCssPlugin

CssMinimizerWebpackPlugin

craco.config.js

CSS

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        
  • RUM (librairie web-vitals)                   

 

✔️

✔️

3. Améliorer les web vitals

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

 

✔️

✔️

✔️

Compression

3. Améliorer les web vitals

Gzip 

brotli

-55%

-60%

Compression

3. Améliorer les web vitals

craco.config.js
{
  // ...
  webpack: {
    plugins: {
      add: [
        // ...
        new CompressionPlugin({
          filename: '[path].gz',
          algorithm: 'gzip',
          test: /\.(js|css|html)$/,
          minRatio: 0.8,
        }),
        new CompressionPlugin({
          filename: '[path].br',
          algorithm: 'brotliCompress',
          test: /\.(js|css|html)$/,
          compressionOptions: { level: 11 },
          minRatio: 0.8,
        }),
      ]
    }
  }
}

Compression

3. Améliorer les web vitals

{
  "compressors": {
    "*.{html,css,js,svg,map}": [
      "...",
      "@parcel/compressor-gzip",
      "@parcel/compressor-brotli"
    ]
  }
}
.parcelrc
import viteCompression from 'vite-plugin-compression';

export default () => {
  return {
    plugins: [viteCompression()],
  };
};
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

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;
const Navbar = import('../Navbar');
const Shelf = import('../Shelf');
const Filter = import('../Shelf/Filter');
const FloatCart = import('../FloatCart');

3. Améliorer les web vitals

Code splitting

App.jsx
import React, { Suspense } from 'react';
import Loader from '../Loader';

const Navbar = React.lazy(() => import('../Navbar'));
const Shelf = React.lazy(() => import('../Shelf'));
const Filter = React.lazy(() => import('../Filter'));
const FloatCart = React.lazy(() => import('../FloatCart'));

const App = () => (
  <React.Fragment>
    <Suspense fallback={<Loader/>}>
      <Navbar />
    </Suspense>
      <main>
        <Suspense fallback={<Loader/>}>
          <Filter />
        </Suspense>
        <Suspense fallback={<Loader/>}>
          <Shelf />
        </Suspense>
      </main>
    <Suspense fallback={<Loader/>}>
      <FloatCart />
    </Suspense>
  </React.Fragment>
);

3. Améliorer les web vitals

Lazy Loading

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

3. Améliorer les web vitals

Preload / prefetch

App.jsx
const Navbar = React.lazy(() => import(/* webpackChunkName: 'navbar' */ '../Navbar'));
const Shelf = React.lazy(() => import(/* webpackChunkName: 'shelf' */ '../Shelf'));
const Filter = React.lazy(() => import(/* webpackChunkName: 'filter' */ '../Shelf/Filter'));
const FloatCart = React.lazy(() => import(/* webpackChunkName: 'float-cart' */'../FloatCart'));
// ...
plugins: [
    // ...
    new PreloadPlugin({
        rel: 'preload',
    	include: ['navbar', 'shelf']
    )},
    new PreloadPlugin({
        rel: 'prefetch',
    	include: ['filter', 'float-cart']
    )},
],
craco.config.js

3. Améliorer les web vitals

Preload / prefetch

navbar.a4dee578.chunk.js

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;
    },
  },
};
craco.config.js

3. Améliorer les web vitals

Preconnect

<!doctype html>
<html lang="fr">
  <head>
      <title>Mon App</title>
      <script defer="defer" src="/static/js/main.eabb2562.js"></script>
      <link href="/static/css/main.00b42aeb.css" rel="stylesheet">
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
index.html

3. Améliorer les web vitals

Inline JS et CSS

temps (ms)

index.html

main.js

main.css

1.chunk.js

2.chunk.js

3.chunk.js

// ...
plugins: [
    // ...
    new HtmlInlineScriptPlugin([
      /main~.+[.]js$/,
    ]),
],
craco.config.js

3. Améliorer les web vitals

Inline JS et CSS

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...)

lazy loading des images

HTTP2

SSR

profiling

Merci !

 

🙏

Made with Slides.com