Site icon Blog ARC Optimizer

Extraction statique en CSS-in-JS pour l’efficacité dans les applications React

Extraction statique en CSS-in-JS pour l’efficacité dans les applications React


L’extraction statique dans CSS-in-JS n’est pas universelle et vous n’avez pas nécessairement besoin de l’extraction statique traditionnelle pour créer des applications React performantes. La meilleure optimisation est souvent celle qui est réellement livrée en production !

Si vous avez travaillé avec React, il y a de fortes chances que vous ayez rencontré le concept CSS-in-JS. CSS-in-JS a changé notre façon de penser le style des composants React en nous permettant de colocaliser les styles avec composants. Cela nous permet d’exploiter toute la puissance de JavaScript pour un style dynamique.

Certaines bibliothèques CSS-in-JS populaires utilisées dans l’industrie sont composants stylisés, Émotion, Astrogazon et linéaire.

Voir le post précédent sur Le guide ultime pour styliser les composants React pour plus de détails sur les différentes approches de style des composants React.

Comme tout outil puissant, CSS-in-JS comporte des compromis. Le principal d’entre eux : les frais généraux de performance. Dans cet article, nous explorerons comment l’extraction statique dans CSS-in-JS peut aider à atténuer ces problèmes de performances, conduisant à des applications React plus rapides et plus efficaces.

Le problème que nous résolvons

Quand on écrit quelque chose comme ça avec composants stylisés (Par exemple):

const Button = styled.button`
  background-color: #007bff;
  color: white;
  padding: 12px 24px;
  border-radius: 4px;
  
  &:hover {
    background-color: #0056b3;
  }
`;

Que se passe-t-il au moment de l’exécution (c’est-à-dire lorsque votre code s’exécute réellement dans le navigateur) ? La bibliothèque de composants stylisés doit analyser ce qui précède modèle littéralgénérez un nom de classe unique, injectez les styles dans le DOM et attachez cette classe à votre composant. Multipliez cela par chaque composant stylisé dans votre application, et vous pouvez commencer à voir où les performances pourraient devenir un problème.

Note: Bien que nous utiliserons des composants stylisés pour illustrer le concept d’extraction statique tout au long de cet article, il convient de noter que les composants stylisés ne prennent pas réellement en charge extraction CSS statique traditionnelle. Il s’agit d’un choix de conception délibéré que nous explorerons en détail plus tard. Cependant, comprendre comment l’extraction statique fonctionnerait avec des composants stylisés nous aide à saisir le concept plus large et à apprécier les différentes approches adoptées par les différentes bibliothèques CSS-in-JS.

Si nous examinons à nouveau l’exemple de bouton ci-dessus, nous remarquerons que les styles sont complètement statiques (c’est-à-dire qu’ils ne changent pas en fonction des conditions d’exécution). Pourtant, (d’une manière générale) ils sont toujours calculés au moment de l’exécution.

L’extraction statique résout ce problème en analysant le code CSS-in-JS pendant temps de construction (c’est-à-dire quand Vite, pack Web ou un bundler similaire traite le code) pour identifier les styles qui ne dépendent pas des accessoires ou de l’état. Étant donné que ces styles sont considérés comme statiques, ils sont « extraits » dans des fichiers CSS standards, ce qui signifie que notre application React n’a plus besoin d’exécuter du JavaScript pour ces styles au moment de l’exécution !

En d’autres termes, au lieu de calculer des styles statiques dans le navigateur, nous les précalculons et les incluons dans des fichiers CSS standards. Nos composants fonctionnent toujours exactement de la même manière, mais désormais le navigateur n’a plus à faire tout ce travail.

Avec cela, nous obtenons le meilleur des deux mondes. Nous pouvons continuer à écrire du CSS-in-JS comme nous en avons l’habitude, mais les styles statiques sont optimisés dans le CSS standard. Les styles dynamiques (ceux qui nécessitent réellement un calcul à l’exécution) restent au format CSS-in-JS.

La plupart des bibliothèques CSS-in-JS prenant en charge l’extraction statique le font via Babel plugins ou transformations au moment de la construction. Voyons comment configurer cela pour les composants stylisés. Nous allons d’abord installer le composants de style babel-plugin plugin :

npm install babel-plugin-styled-components

Configurez-le ensuite dans notre configuration Babel :


module.exports = {
  presets: ['@babel/preset-env', '@babel/preset-react'],
  plugins: [
    [
      'babel-plugin-styled-components',
      {
        displayName: true,  
        pure: true          
      }
    ]
  ]
};

Que pure: true L’option indique au plugin d’analyser nos composants stylisés et d’extraire tous les styles qui ne dépendent pas des accessoires ou des valeurs du thème. Les styles extraits se retrouvent dans des fichiers CSS qui sont chargés avec nos bundles JavaScript. Cela atteint essentiellement le même objectif de performances que l’extraction CSS statique traditionnelle, en réduisant les frais d’exécution et en améliorant l’efficacité globale des applications.

Vous vous demandez peut-être : que se passe-t-il lorsque les styles sont partiellement dynamiques ? C’est là que l’extraction statique devient intelligente. Considérez ce composant :

const Card = styled.div`
  background: white;
  border-radius: 8px;
  padding: 24px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  
  ${props => props.highlighted && `
    border: 2px solid #007bff;
    box-shadow: 0 4px 16px rgba(0, 123, 255, 0.2);
  `}
`;

Une configuration d’extraction statique intelligente extraira les styles de base (background, border-radius, padding et par défaut box-shadow) en CSS statique. Les styles conditionnels qui dépendent du highlighted prop reste en tant qu’environnement d’exécution CSS-in-JS. Vous bénéficiez de performances optimisées pour le cas courant tout en conservant toutes les capacités dynamiques.

Différentes bibliothèques, différentes approches

L’écosystème CSS-in-JS a développé différentes philosophies autour de l’extraction statique. Passons un peu de temps dans cette section pour expliquer plus en détail comment ces différentes bibliothèques abordent le concept d’extraction statique.

composants stylisés

Bien que nous ayons utilisé les composants stylisés comme exemple pour illustrer le concept d’extraction statique ci-dessus, les composants stylisés ne prennent pas officiellement en charge l’extraction statique traditionnelle. Comme l’a expliqué un membre du projet (co-créateur) dans un Problème GitHubils ont fait ce choix délibérément :

« Nous ne prenons pas en charge l’extraction CSS statique… L’extraction statique ne génère pas de CSS dynamique, ce qui signifie que votre page apparaîtra cassée jusqu’à l’exécution du JS, ou que vous devrez attendre que le JS soit chargé. »

Au lieu de cela, les composants stylisés se concentrent sur :

  • Rendu côté serveur (SSR) qui envoie uniquement les CSS critiques pour le rendu initial
  • Injection d’exécution efficace avec batching et optimisation
  • Maintenir l’ordre des styles pour une spécificité prévisible

Le pure: true l’option dans babel-plugin-styled-components n’extrait pas réellement les fichiers CSS ; il marque les composants comme étant sans effets secondaires pour un meilleur secouer les arbres et élimination du code mort.

Émotion

Emotion prenait initialement en charge l’extraction statique, mais je l’ai déprécié dans la version 10. Leur raisonnement était pragmatique :

« À mesure que l’émotion est devenue plus performante et que des fonctionnalités telles que la composition
ont été ajoutés, l’extraction statique est devenue moins importante… Bibliothèques
comme les linaria font bien l’extraction statique et les personnes qui y travaillent
se concentrent sur ce problème spécifique.

Lorsqu’Emotion prenait en charge l’extraction, cela fonctionnait comme ceci :


{
  "plugins": [["emotion", { "extractStatic": true }]]
}

Cela générerait des .emotion.css fichiers pour les styles sans interpolations. Cependant, cela brisait les modèles de composition et limitait la flexibilité de la bibliothèque.

linéaire

Linaria adopte une approche complètement différente : il s’agit d’un CSS-in-JS sans exécution. Tout est extrait au moment de la construction :

import { css } from '@linaria/core';
import { styled } from '@linaria/react';

const button = css`
  background-color: #007bff;
  color: white;
`;

const Button = styled.button`
  padding: 12px 24px;
  border-radius: 4px;
`;

Linaria compile cela en fichiers CSS purs sans aucune surcharge d’exécution. Il fournit même un collect assistant pour l’extraction CSS critique :

import { collect } from '@linaria/server';

const { critical, other } = collect(html, css);


Astrogazon

Astroturf se situe quelque part entre Linaria et CSS-in-JS traditionnel, offrant plusieurs API pour différents cas d’utilisation :

import { css, stylesheet } from 'astroturf';


const btnClass = css`
  color: blue;
  border: 1px solid blue;
`;


const styles = stylesheet`
  .btn {
    padding: 0.5rem 1rem;
  }
  
  .primary {
    background-color: blue;
  }
`;

Pour les valeurs dynamiques, Astroturf transpile intelligemment les interpolations en propriétés CSS personnalisées :

function Button({ bgColor }) {
  return (
    <button
      css={css`
        background-color: ${bgColor};
      `}
    >
      Click me
    </button>
  );
}

L’extraction statique dans CSS-in-JS n’est pas une solution universelle. L’écosystème a développé différentes approches basées sur différentes priorités. styled-components a choisi l’expérience et la flexibilité des développeurs plutôt que l’extraction. Emotion a essayé l’extraction mais a trouvé cela limitant. Linaria et Astroturf se sont mis à fond sur l’extraction au moment de la construction.

L’idée clé ? Vous n’avez pas nécessairement besoin d’une extraction statique traditionnelle pour créer des applications React performantes. Les bibliothèques CSS-in-JS modernes sont assez rapides et des techniques telles que SSR, le fractionnement de code et le CSS critique peuvent souvent offrir de meilleures performances réelles que l’extraction statique naïve.

Voici comment vous pouvez envisager de choisir une option de style :

Optez pour des composants stylisés + SSR lorsque vous accordez avant tout de l’importance à l’expérience du développeur, vous effectuez déjà un rendu côté serveur ou votre application a des exigences de performances modérées. L’expérience du développeur est inégalée et les performances sont suffisantes pour la plupart des applications.

Choisissez Linaria ou Astroturf lorsqu’une surcharge d’exécution nulle est critique, vous créez quelque chose de sensible aux performances (pensez aux sites de commerce électronique ou d’actualités) ou vous êtes à l’aise avec les contraintes de temps de construction. Le compromis est une flexibilité moindre pour le style dynamique, mais pour de nombreuses applications, cela en vaut la peine.

Rester avec Modules CSS ou CSS vanille lorsque vous souhaitez un contrôle total sur l’extraction, préférez la séparation des préoccupations ou l’exécution de CSS-in-JS, c’est comme amener un bazooka dans un combat au couteau.

L’avenir nous réserve probablement un terrain d’entente : créer des outils suffisamment intelligents pour extraire automatiquement ce qui peut l’être tout en préservant la flexibilité que nous attendons du CSS-in-JS.

D’ici là, choisissez l’approche qui correspond le mieux aux besoins de votre projet et n’oubliez pas : la meilleure optimisation est souvent celle qui est réellement livrée en production !




Source link
Quitter la version mobile