Oeuvre : https://code-art.pictures/
Cela peut paraître surprenant de nos jours, mais le trafic Internet reste un problème dans de nombreux scénarios. Les réseaux mobiles ont souvent des forfaits de données limités, les batteries des appareils ne sont pas infinies et, plus important encore, l'attention de l'utilisateur en attendant le chargement de votre site est limitée. C'est pourquoi la taille du bundle est toujours importante. Voici sept conseils à considérer.
En 2020, je maintenais une application promotionnelle pour un réseau social local. Il s’agissait d’une application Webpack React TypeScript typique ciblant ES5. Lorsque le webpack 5 est sorti, j'ai décidé de mettre à niveau. Tout s'est bien passé ; J'ai surveillé l'analyse des erreurs et les commentaires des utilisateurs, et il n'y a rien eu d'inattendu. Ce n'est qu'au bout d'une semaine que j'ai découvert par hasard que mon bundle contenait des fonctions fléchées : il s'agissait d'une nouvelle fonctionnalité du webpack.
Voici un excellent article sur l'état de l'ES5. Points clés à retenir :
Voici quelques fonctionnalités qui vous permettent d'écrire du code meilleur et plus compact.
Les générateurs sont un moyen efficace de parcourir des structures imbriquées :
type TreeNode<T> = { left?: TreeNode<T> value: T right?: TreeNode<T> }; function* traverse<T>(root: TreeNode<T>): Generator<T> { if (root.left) yield* traverse(root.left) yield root.value if (root.right) yield* traverse(root.right) }
Les minificateurs savent avec certitude que ces champs ne peuvent pas avoir d'usages externes, même dans les objets exportés, et sont libres de raccourcir leurs noms.
Source
export class A { #myFancyStateObject }
Pack
export class A{#t}
Cela ne fonctionnera pas, bien sûr, avec les champs privés TypeScript, car la connaissance de leur caractère privé disparaît une fois que tsc a fait son travail.
Avez-vous entendu parler de Promise.withResolvers() ou Map.groupBy() ? Ces API ne sont pas largement disponibles au moment d’écrire ces lignes, mais le seront bientôt. Prenez un moment pour vous familiariser avec eux dès maintenant et soyez prêt à les adopter dans quelques années.
Il existe d'innombrables blogs et podcasts, mais je trouve que les meilleures « newsletters » sont les nouveaux fichiers .d.ts dans le référentiel TypeScript. Ouvrez simplement, par exemple, es2024.collection.d.ts et profitez-en ?
Remarquez-vous le motif répété ?
type TreeNode<T> = { left?: TreeNode<T> value: T right?: TreeNode<T> }; function* traverse<T>(root: TreeNode<T>): Generator<T> { if (root.left) yield* traverse(root.left) yield root.value if (root.right) yield* traverse(root.right) }
Le code répété augmente non seulement la taille du paquet, mais rend également plus difficile la compréhension du rôle de chaque partie. Cela conduit souvent les développeurs à écrire du nouveau code au lieu d'identifier et de réutiliser les fonctions utilitaires existantes, ce qui gonfle encore davantage l'ensemble.
Il existe déjà une multitude d'excellents documents sur ce sujet, alors plutôt que de le raconter à nouveau, je recommande un classique : Refactoring de Martin Fowler. Il couvre non seulement des exemples simples comme celui ci-dessus, mais également des cas complexes tels que des hiérarchies couplées et des conceptions répétées.
Maintenant, améliorons notre petit exemple. Il semble que clamp soit souvent utilisé pour limiter les paramètres aux plages d'index de tableau, nous pouvons donc créer un raccourci :
export class A { #myFancyStateObject }
Ce changement rend explicite que n est probablement destiné à être un nombre entier, ce qui n'est pas actuellement vérifié. Il met également en évidence un cas limite non géré : les tableaux vides. En faisant cette petite déduplication, on a aussi découvert deux bugs potentiels ?
Je ne me souviens pas de la source exacte de ce dicton, mais je pense qu'il est juste :
La suringénierie consiste à résoudre un problème que vous n'avez pas.
Dans le monde du développement web, j'ai observé deux principaux types de suringénierie.
Considérez ce code. Les remplissages sont des multiples de 4 pixels et les couleurs d'arrière-plan sont des nuances de bleu. Ce n’est probablement pas une coïncidence, et si c’est le cas, cela pourrait indiquer une possible duplication. Mais avons-nous vraiment suffisamment d'informations pour extraire le composant générique Button, ou sommes-nous en train de faire de la suringénierie ?
CSS
export class A{#t}
JSX
const clamp = (min, val, max) => Math.max(min, Math.min(val, max)) const x = clamp(0, v1, a.length - 1) const y = clamp(0, v2, b.length - 1) const z = clamp(0, v3, c.length - 1)
Ce conseil entre quelque peu en conflit avec « Éviter la duplication ». Une déduplication excessive du code peut conduire à une ingénierie excessive. Alors, où tracez-vous la limite ? Personnellement, j'utilise le chiffre magique « 3 » : une fois que je vois trois endroits avec un motif similaire, il est peut-être temps d'extraire le composant générique.
Dans le cas de nos boutons bleus, je pense que la meilleure solution serait d'utiliser des variables CSS, au moins pour le remplissage, plutôt que de créer un nouveau composant.
Oui, je parle de ce que nous aimons : Next.js, React, Vue, etc. Si votre application n'implique pas beaucoup d'interactivité au niveau des éléments DOM, ou n'est pas dynamique, ou est très simple, envisagez d'autres options :
L'objectif actuel de TypeScript est principalement de vérifier le type de JavaScript, mais cela n'a pas toujours été le cas. Avant ES6, il y a eu de nombreuses tentatives pour créer un « meilleur JavaScript » et TypeScript ne faisait pas exception. Certaines fonctionnalités remontent à ces débuts.
Non seulement ils sont difficiles à utiliser correctement, mais ils se transposent également dans des structures assez verbeuses :
TypeScript
type TreeNode<T> = { left?: TreeNode<T> value: T right?: TreeNode<T> }; function* traverse<T>(root: TreeNode<T>): Generator<T> { if (root.left) yield* traverse(root.left) yield root.value if (root.right) yield* traverse(root.right) }
JavaScript
export class A { #myFancyStateObject }
Le manuel officiel TypeScript recommande d'utiliser des objets simples au lieu d'énumérations. Vous pouvez également envisager les types de syndicats.
Les espaces de noms étaient une solution de modules pré-ESM. Non seulement ils augmentent la taille du bundle, mais comme les espaces de noms sont destinés à être globaux, il devient très difficile d'éviter les conflits de noms dans les grands projets.
TypeScript
export class A{#t}
JavaScript
const clamp = (min, val, max) => Math.max(min, Math.min(val, max)) const x = clamp(0, v1, a.length - 1) const y = clamp(0, v2, b.length - 1) const z = clamp(0, v3, c.length - 1)
Au lieu d'espaces de noms, utilisez des modules ES.
Remarque : les espaces de noms sont cependant toujours utiles pour écrire des définitions de types pour les bibliothèques globales.
Chacune de ces petites astuces peut vous faire gagner plusieurs dizaines d'octets dans le bundle. S'ils sont appliqués de manière cohérente, ils peuvent apporter un résultat visible.
Par exemple, une chaîne vide est fausse. Pour vérifier s'il est défini et non vide, vous pouvez simplement écrire :
const clampToRange = (n, {length}) => clamp(0, n, length - 1) const x = clampToRange(v1, a) // ...
Je crois qu'utiliser == pour contraindre null à indéfini, ou vice versa, est totalement justifié.
.btn-a { background-color: skyblue; padding: 4px; } .btn-b { background-color: deepskyblue; padding: 8px; }
<button className='btn-a' onClick={handleClick}> Show </button> // ... <button className='btn-b' onClick={handleSubmit}> Submit </button>
Au lieu de ça :
enum A { x, y }
Écrivez ceci :
var A; (function (A) { A[A["x"] = 0] = "x"; A[A["y"] = 1] = "y"; })(A || (A = {}));
Au lieu de ça :
namespace A { export let x = 1 }
Écrivez ceci :
var A; (function (A) { A.x = 1; })(A || (A = {}));
Vous pouvez également geler l'objet pour protéger ses propriétés des modifications.
Pour chaque bundler, il existe des outils pour visualiser son contenu, tels que webpack-bundle-analyzer pour webpack et vite-bundle-analyzer pour Vite. Des outils comme ceux-ci vous aident à identifier les problèmes courants avec votre offre groupée :
En plus de ces outils, c'est une bonne idée de lire occasionnellement les liasses manuellement pour repérer les irrégularités. Par exemple, vous pouvez trouver des assistants ES5 dans un bundle ES6 ou des assistants CJS dans un projet ESM en raison d'une mauvaise configuration de TypeScript. Ces problèmes peuvent ne pas être détectés par les outils automatisés, mais peuvent néanmoins augmenter le temps de chargement et potentiellement vous coûter votre atout le plus précieux : l'attention de l'utilisateur.
Merci d'avoir lu. Bon codage !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!