Web perf : analyser et optimiser un front

Jonathan Hervieux @djow__

🕐 PLUS QUE

14 mins et 42 s

  • Amabay
  • Cdiscount
  •  Rakuten

Jonathan Hervieux

Développeur

@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        
  • FCP, LCP, CLS...                   

 

📝 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

Javascript

3. Améliorer les web vitals

Minification

 

Tree shaking

TerserWebpackPlugin

Javascript

3. Améliorer les web vitals

webpack-bundle-analyzer

bundlephobia

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

Gzip 

brotli

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,
        }),
      ]
    }
  }
}

-55%

-60%

Compression

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
  • 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
  • Penser à inline

✔️

✔️

✔️

✔️

✔️

✔️

✔️

✔️

Et plein d'autres choses...

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

lazy loading des images

HTTP2

cache réponses API

SSR

Merci !

 

🙏

Made with Slides.com