Développement et architecture des Applications Web Modernes
Retrouver les fondamentaux
Hubert Sabionnière
Wassim Chegham
Préface
Déconstruire pour ensuite mieux (re)construire
Introduction
1. Pourquoi ce livre ?13
1.1 État des lieux13
1.2 Approche générale14
1.3 Modernité et minimalisme15
1.4 À qui s'adresse ce livre ?16
2. Contenu17
2.1 Déroulement17
2.2 Chapitres17
2.3 Conseils de lecture21
Chapitre 1
Comprendre l'histoire du Web et de ses standards
1. Être un « bon citoyen » du Web23
2. IETF, les réseaux et Internet25
2.1 Origines de la standardisation des réseaux25
2.2 Indépendance et internationalisation26
2.3 RFC : un fondamental de la collaboration27
3. Invention de l'hypertexte30
3.1 Modéliser la connaissance30
3.2 Première implémentation32
4. Origines du Web35
5. W3C, standardiser et promouvoir le Web38
5.1 Origines (1991-1997)38
5.2 Fonctionnement40
5.3 Organisation générale42
5.4 Préévaluation par la communauté43
5.5 Élaboration des recommandations47
5.6 Working groups50
6. WHATWG, HTML et DOM51
6.1 Critiques et dissensions au W3C51
6.2 Le Web comme plateforme de développement applicatif54
6.3 Ouverture et réconciliation56
6.4 Domaines d'autorité57
6.5 Développement continu59
6.6 Processus et hiérarchie61
7. TC39, de JavaScript à ECMAScript62
7.1 Première standardisation65
7.2 Évolutions de JavaScript66
7.3 Moderniser le développement web pour de bon69
7.4 Processus actuel71
7.5 Organisation73
8. Références75
Chapitre 2
Suivre les évolutions de la plateforme
1. Les précurseurs85
1.1 Les premiers navigateurs (1993-1994)85
1.2 Dynamiser le Web (1994-1995)90
2. De Netscape à Internet Explorer92
2.1 La première guerre des navigateurs (1995-2001)92
2.2 Naissance de Mozilla (1998-2004)96
2.3 Internet Explorer contre Firefox (2004-2010)100
3. Naissance de Chrome et de Safari102
4. L'entrée dans le Web moderne105
4.1 Le succès des smartphones (2011-2017)105
4.2 Le règne de Google (2017- ? )107
4.3 Situation actuelle (2021)111
5. A L'écoute des nouveaux standards112
5.1 L'inintelligibilité supposée des standards112
5.2 Trouver et suivre les propositions116
6. Progresser avec les navigateurs modernes120
6.1 Trois approches distinctes120
6.2 Google Chrome121
6.3 Apple Safari et WebKit122
6.4 Mozilla et Firefox123
6.5 Veille et montée en compétences126
6.6 Perspectives présentes et futures128
7. Références130
Chapitre 3
Adopter une approche par composant
1. Introduction à la programmation par composant137
1.1 Un cadre de référence nécessaire138
1.2 Niveau de complexité et réutilisabilité139
1.3 Qu'est-ce qu'un composant ?140
1.4 Définir un composant143
1.5 Les limites initiales du développement web145
2. Premières fondations pour le Web148
2.1 Plug-ins148
2.2 Une seconde génération de frameworks152
2.3 Cas d'étude : AngularJS154
3. Liens avec une approche fonctionnelle158
3.1 Fonctions et réactivité159
3.2 Approche générale160
3.3 Représenter HTML dans JavaScript162
3.4 Le problème du rendering166
3.5 Le problème de la gestion d'état169
3.6 Vers un langage fonctionnel ?174
4. Naissance d'un standard177
4.1 Les prédécesseurs178
4.2 Première émergence des Web Components180
4.3 Introduction aux Web Components181
4.4 Anticiper et dépasser le standard183
5. Références187
Chapitre 4
Faire bon usage des Web Components
1. Introduction195
2. Étendre le vocabulaire HTML197
2.1 Définir un élément personnalisé197
2.2 Éviter les conflits199
2.3 Utiliser un nom valide201
2.4 Créer une classe204
2.5 Afficher un message206
2.6 Créer un élément personnalisé programmatiquement206
2.7 Cycle de vie210
2.8 Support214
3. Créer et utiliser un arbre fantôme217
3.1 Notions fondamentales217
3.2 light DOM et shadow DOM221
3.3 Restreindre l'accès au shadom DOM224
4. Définir le style d'un Web Component228
4.1 Style externe230
4.2 Élément hôte238
4.3 Style par défaut de l'élément hôte240
4.4 Contexte242
4.5 Customisation244
5. Templates et composition246
5.1 <template>247
5.2 <slot> et composition252
5.3 Slots nommés255
6. Attributs et propriétés258
6.1 Principe : suivre la logique du standard HTML258
6.2 Mise en place d'un Web Component de démonstration259
6.3 Exposer l'état du composant261
6.4 Effectuer des actions simples262
6.5 Récupérer des valeurs primitives264
6.6 Réagir aux changements de valeur d'un attribut266
6.7 Manipuler des valeurs non primitives268
6.8 Charger des propriétés dynamiquement270
7. Limites des Web Components272
8. Références275
Chapitre 5
Développer une application monopage
1. Structure et objectifs279
1.1 Les défauts des sites web multipages279
1.2 Offrir une meilleure expérience utilisateur281
1.3 Architecture283
2. Principes essentiels du routage287
3. Manipuler l'URL du document289
3.1 L'interface Location291
3.2 Utiliser l'identificateur de fragment de l'URL293
3.3 Hash et historique294
3.4 L'interface History296
3.5 Compatibilité301
3.6 Réécriture des URL côté serveur303
4. Définir des routes306
4.1 Uniformiser le rendu dynamique307
4.2 Définir une collection de routes309
4.3 Définir une route par défaut311
4.4 Approche des principaux frameworks315
5. Transmettre des données317
5.1 Paramètres de route318
5.2 Paramètres d'URL323
5.3 Objets état associés à l'historique328
6. Navigation et changement de route331
6.1 Gestion globale333
6.2 Évènement popstate.336
7. Au-delà du routage338
7.1 Modularité338
7.2 Limitations du routage341
8. Références342
Chapitre 6
Afficher des données dynamiquement
1. Optimiser le chargement initial347
1.1 Faire primer l'expérience utilisateur347
1.2 Capturer l'attention des utilisateurs348
1.3 Audit des performances du chargement initial350
1.4 Éviter les contenus bloquants355
1.5 Améliorer le chargement des scripts356
1.6 Accélérer l'affichage d'un texte357
1.7 Ne charger que les styles utiles358
1.8 Au-delà du simple chargement360
2. Comparer différentes approches361
2.1 Présentation de la solution employée367
2.2 Implémentation des tests de performance369
2.3 Est-il vraiment important de comparer les performances ?374
3. Bien utiliser la DOM API376
3.1 Créer un ensemble d'éléments376
3.2 Mettre à jour le contenu d'un élément378
4. Littéraux de gabarit et innerHTML382
4.1 Gérer les évènements383
4.2 Mettre à jour le contenu de l'élément388
4.3 Performances390
5. HyperScript393
5.1 Une bibliothèque, une fonction et une syntaxe394
5.2 HyperScript, React et les VDOM396
5.3 Syntaxes alternatives pour HyperScript399
5.4 Créer une fonction HyperScript400
5.5 Performances402
6. Minimiser les accès au DOM404
6.1 Identifier les responsabilités de chacun405
6.2 Fragments407
6.3 Mettre en cache les éléments410
6.4 Liens avec la programmation orientée composant415
6.5 Comparaison avec les littéraux de gabarits419
6.6 Mettre en cache un élément avec HyperScript421
6.7 Mettre en cache l'état425
7. Optimiser pour la répétition426
7.1 Optimiser la mise en cache des éléments avec cloneNode()427
7.2 Utiliser innerHTML pour améliorer la lisibilité431
7.3 Construire sa propre solution433
7.4 Performances442
8. Conclusion443
9. Références444
Chapitre 7
Définir une architecture cohérente
1. Comment faire « le bon choix » ?449
1.1 Déterminer l'approche optimale en fonction du contexte450
1.2 Trouver le bon équilibre entre abstraction
et dette technique452
2. Vanilla Web et les microbibliothèques455
2.1 De Vanilla JS au modem Web455
2.2 Complexité et poids d'un code JavaScript456
2.3 Evolution d'une bibliothèque dans le temps458
2.4 Quand et pourquoi utiliser des microbibliothèques459
2.5 Aides à la manipulation du DOM460
2.6 Réalité du « Vanilla »464
2.7 RE : DOM466
3. Bibliothèques de rendering476
3.1 Principe des étiquettes de gabarits477
3.2 Bibliothèques de rendering utilisant les étiquettes de gabarits480
3.3 Naissance et évolution de lit-html484
3.4 Fonctionnement de lit-html485
3.5 Exemple d'application487
3.6 Ms directives lit-html492
3.7 JSX face aux littéraux de gabarits494
3.8 React est-il vraiment une bibliothèque de rendering ?502
4. Modularité et programmation orientée composant504
4.1 Principes de lit-element506
4.2 Démarrer un projet avec lit-element510
4.3 web component par compilation avec Stencil514
5. Programmation réactive516
5.1 Notions fondamentales516
5.2 RxJS519
5.3 Observables et opérateurs520
5.4 Combiner des observables524
5.5 hot et cold observables525
5.6 Alternatives à RxJS527
5.7 Forces et faiblesses de la programmation réactive528
6. Gestion d'état529
6.1 Créer un conteneur d'état avec Redux530
6.2 Permettre à des composants de partager un état533
6.3 Rendre les composants indépendants de l'état global536
7. Routeurs541
7.1 Page.js541
7.2 Universal-router543
8. Frameworks545
8.1 Définition545
8.2 Microframeworks547
8.3 React, Vue et Angular : frameworks ou écosystèmes ?548
8.4 Metaframeworks552
9. Synthèse553
9.1 Vanilla JS et Vanilla Web : comment développer sans assistance ?555
9.2 Le modem Web face aux compilateurs et aux frameworks556
10. Références557
Conclusion569
Postface575
Annexes
1. Les bibliothèques, les frameworks et les outils583
1.1 Le rendering584
1.1.1 Les manipulations du DOM584
1.1.2 Les tagged template literals585
1.1.3 JSX et React585
1.2 La programmation orientée composant586
1.3 Le routage et la navigation586
1.4 La programmation réactive et les gestionnaires d'état587
1.5 Les frameworks587
1.6 Les outils de développement587
1.7 Les polyfills et les shims588
2. Groupes de travail du W3C589
2.1 Note à propos des abréviations589
2.2 Fondamentaux front-end590
2.3 Accessibilité (WAI)591
2.4 Web API592
2.5 Sémantique et données593
2.6 Divers593
2.7 Références595
3. Glossaire597
4. Principes fondamentaux de Chrome603
4.1 Multiprocessing603
4.2 V8, l'interpréteur JavaScript604
4.3 Expérience utilisateur605
4.4 Sécurité605
4.5 Gears, standards et open source606