Maison > interface Web > js tutoriel > Compagnon de notes de mise à jour React

Compagnon de notes de mise à jour React

Linda Hamilton
Libérer: 2025-01-12 16:39:44
original
894 Les gens l'ont consulté

React Update Notes Companion

Les notes de mise à jour pour les nouvelles versions majeures de React sont toujours incroyablement denses en informations, et le cadre lui-même est si large que je me retrouve toujours à prendre des notes et à comparer la documentation de référence pour essayer non seulement découvrez ce qui a changé et comment l'utiliser, mais aussi comment les différents concepts majeurs dont parlent les notes de mise à jour ont réellement fonctionné sous le capot. Bien que React soit extrêmement bien documenté, les notes de mise à jour ne sont pas toujours « suffisantes » pour comprendre les concepts - par exemple, dans les notes de mise à jour de React 19, j'ai trouvé l'exemple de useOptimistic déroutant et en fait un peu inexact quant au fonctionnement réel du hook.

J'ai décidé d'écrire les notes que j'ai prises en passant en revue les modifications de React 19 pour en faire un compagnon pour tous ceux qui redoutent de parcourir les notes et de comprendre ce qu'elles signifient toutes - alors commençons.

Actions et gestion des formulaires/useActionState

La première amélioration majeure a été d'énormes améliorations dans la gestion des formulaires. React a progressivement évolué pour supprimer le passe-partout et mieux s'intégrer aux formulaires HTML natifs, et son nouveau useActionState fait partie de cette poussée. Il est destiné à aider à améliorer la gestion des erreurs (car il est désormais intégré), il suit automatiquement les états de chargement afin que vous n'ayez pas à coder manuellement en permanence les états en attente et améliore la prise en charge de l'amélioration progressive.

Maintenant, j'ai trouvé l'exemple de code fourni pour useActionState assez déroutant, et en fait, cet exemple de code est la seule raison pour laquelle j'ai commencé à écrire cet article - il y a, en fait, deux parties à useActionState, qu'ils ont combinées dans le exemple pour économiser de l'espace, mais a fini par réduire considérablement la clarté. useActionState renvoie un tuple qui suit le moment où l'action asynchrone dans la soumission du formulaire est terminée, tandis qu'une version modifiée de l'action que vous lui transmettez est directement transmise au formulaire. useActionState lui-même prend deux entrées - une formAction asynchrone (qui reçoit à la fois l'état précédent et les données du formulaire comme arguments lorsqu'il est appelé) et l'état initial - qui peut être nul, zéro ou une variable.

Si votre formulaire n'a pas encore été soumis, l'état précédent est l'état initial. Si le formulaire a déjà été soumis, il s'agit de ce qui a été soumis - dans une fonction serveur, vous pouvez en fait afficher la réponse du serveur avant même que l'hydratation ne se produise. useActionState peut enfin accepter une chaîne avec une URL de page unique que le formulaire est destiné à modifier. En d'autres termes, il peut également accepter un paramètre de permalien facultatif, particulièrement utile pour une amélioration progressive : il indique au navigateur où naviguer si un utilisateur soumet le formulaire avant le chargement de JavaScript.

Enfin, le tuple renvoyé par useActionState est un tableau composé de l'état actuel (lors de votre rendu initial, c'est votre valeur initialState), du formAction modifié par réaction que vous pouvez transmettre à un formulaire en tant qu'action ou d'un bouton en tant qu'accessoire, et un indicateur isPending/variable avec état. J'ai hâte de voir quels autres nouveaux développements l'équipe React proposera, car celui-ci semble particulièrement utile.

Mises à jour de React-DOM

actions

Cet ajout de Reac sera familier à tous ceux qui ont utilisé NextJS et les actions de formulaire, et il semble que l'équipe Reac ait décidé que les actions de formulaire étaient prêtes à être diffusées aux heures de grande écoute. Pour tous ceux qui ne les ont pas utilisés dans NextJS ou dans un autre framework en plus de React, ils constituent essentiellement un moyen d'améliorer les performances de React en utilisant la soumission de formulaires natifs. Au lieu de onClick, vous pouvez transmettre des soumissions de formulaires natifs via la prop action - toute fonction passée à action ou formAction verra sa soumission gérée automatiquement. React réinitialisera également automatiquement tous les champs de formulaire non contrôlés. Vous disposez également d'options manuelles pour le réinitialiser via l'API. L'équipe React a également intégré la gestion des erreurs avec des limites d'erreur. Je n'en parlerai pas trop car je suppose que la plupart des gens s'en souviennent depuis NextJS, mais je peux écrire un suivi si quelqu'un a des questions.

hook useFormStatus

C'est un excellent ajout pour vous aider à voir ce qui se passe dans votre formulaire sans perçage d'accessoires ni utilisation de contexte - si vous demandez pourquoi ne pas percer d'accessoires, il s'agit de garder le code maintenable et facile à modifier. En ce qui concerne le contexte, une utilisation excessive du contexte entraînera des problèmes de performances, car chaque composant abonné à un contexte particulier sera restitué chaque fois que quelque chose dans le contexte change. Ainsi, cela désencombre le code, réduit les risques d’erreurs et vous empêche de gâcher les performances de votre application.

Le hook renvoie un objet avec quatre propriétés : ending - un booléen qui indique s'il y a une soumission en attente, data - un objet formData avec les données soumises par le formulaire parent (cela est nul s'il n'y a pas de soumission active ou de formulaire parent ), la méthode (get ou post) et l'action - qui est l'action transmise via le accessoire d'action.

utiliser le crochet optimiste

La nouvelle façon plus simple de gérer les mises à jour optimistes. Si vous n'êtes pas familier avec les mises à jour optimistes, cela signifie mettre à jour l'affichage côté client avant que les mises à jour côté serveur n'aient lieu. Si vous avez déjà aimé quelque chose, vu l'animation jouer et l'avoir enregistrée sur votre écran comme vous l'aviez aimé, puis reçu une erreur de toast indiquant « comme un échec », cela est dû à un rendu optimiste.

Le hook useOptimistic accepte une variable avec état dont vous souhaitez un rendu optimiste et une fonction de mise à jour, qui doit être une fonction pure - en d'autres termes, une fonction déterministe sans effets secondaires. Fondamentalement, la fonction de mise à jour récupère la source de la mise à jour vers l'état - donc généralement quelque chose comme formData.get('name'). useOptimistic renvoie alors deux valeurs : l'état optimiste et une fonction addOptimistic.

J'ai trouvé la documentation à ce sujet un peu faible, en particulier en ce qui concerne le flux d'utilisation - en gros, vous appelez useOptimistic et lui transmettez l'état initial pour lequel vous souhaitez afficher les mises à jour optimistes et une fonction de mise à jour. Vous recevez deux fonctions : la nouvelle valeur avec état améliorée et optimiste (optimisticState) et une fonction permettant de changer d'état de manière optimiste. Lorsque vous avez une nouvelle valeur soumise par l'utilisateur, vous appelez la deuxième fonction, appelée addOptimistic dans la documentation, et lui transmettez la valeur soumise par l'utilisateur. Dans votre composant, vous lui transmettez ensuite la valeur avec état améliorée et optimiste chaque fois que vous souhaitez restituer la variable avec état de manière optimiste.

Dans l'ensemble, j'aime vraiment cette manière plus standardisée d'effectuer des mises à jour optimistes - j'ai déjà eu des problèmes avec la mise en cache dans NextJS et la réalisation de mises à jour optimistes, donc une manière standardisée de créer des mises à jour optimistes est excellente, et je suis sûr que ce sera le cas. passez à NextJS, si ce n'est pas déjà fait.

L'API d'utilisation

Il s'agit d'une API super dense, et c'est une toute nouvelle façon d'accéder aux ressources pendant que React rend une page - l'expression exacte utilisée est « lire les ressources lors du rendu ». Alors à quoi ça sert concrètement ? Cette nouvelle API peut être utilisée pour accéder aux informations sur les composants à l'intérieur de conditions ou de boucles. Si vous ne savez pas pourquoi cela est utile, cela a à voir avec le fonctionnement du processus de rendu de React. React/react-fiber repose sur le rendu de tout dans le même ordre à chaque fois, c'est pourquoi vous ne pouvez généralement pas accéder à la plupart des hooks pendant le processus de rendu. Pour le dire plus clairement, l'état est en fait suivi en fonction de l'ordre dans lequel les hooks sont appelés, donc si les hooks sont appelés dans un ordre imprévisible, vous vous retrouvez avec des bugs de rendu. Un bon exemple est l'accès à un contexte de thème selon que l'utilisateur est connecté ou non.

Alors pourquoi est-ce une évolution importante ? Cela signifie que vous pouvez charger des informations/données uniquement lorsque cela est réellement nécessaire, par ex. ce n'est que si un utilisateur est réellement connecté que vous chargerez du CSS pour un thème spécial. Les données doivent être sérialisables, ce qui signifie que vous pouvez envoyer une promesse du composant serveur à un composant client alors qu'il est en fait déjà en cours - cela signifie qu'il y a moins de requêtes en cascade et qu'elles sont automatiquement mises en parallèle. Il convient de noter que lorsque vous travaillez dans des composants serveur, vous devriez en fait préférer utiliser async/await plutôt que l'utilisation pour la récupération de données - en effet, async/await reprendra le rendu exactement là où il s'était arrêté, tandis que l'utilisation déclenchera un nouveau rendu complet de le composant après la résolution des données. Bien sûr, je tiens également à noter que ce changement signifie également que vous disposez d'une nouvelle source potentielle de requêtes en cascade si vous configurez l'utilisation de manière incorrecte.

Une chose très importante à noter est que vous ne pouvez pas utiliser l'API « use » dans un bloc try/catch - en effet, « use » utilise automatiquement les limites de suspense de réaction lorsqu'il est appelé avec une promesse. Un bloc try/catch vous empêche d'atteindre le niveau de réaction, car toute erreur arrêterait en fait l'exécution au niveau JS avant que vous n'atteigniez React, brisant ainsi la fonctionnalité. Comme les autres hooks, ils doivent se trouver au niveau supérieur de portée d'un composant ou d'une fonction particulière (encore une fois, en raison de l'ordre de rendu).

Donc, quel est le véritable objectif de « utilisation » est de vous aider à accéder au contexte pour rendre les choses de manière conditionnelle et à récupérer les données uniquement lorsque cela est réellement nécessaire. C'est encore une autre étape vers une réaction un peu moins mystérieuse, en simplifiant la récupération de données conditionnelles, en améliorant l'expérience de développement et en améliorant les performances d'un seul coup. Cela nécessite des développeurs React plus expérimentés pour réapprendre à faire des choses comme la création de thèmes, mais je pense que cela rend le framework beaucoup plus accessible aux nouveaux utilisateurs, ce qui est toujours génial.

Nouvelles API statiques React Dom

Ces deux nouvelles API statiques, prerender et prerenderToNodeStream sont toutes deux des améliorations de renderToString, qui est utilisé pour le rendu côté serveur (SSR). Ces nouvelles améliorations concernent la génération de sites statiques (SSG) à l'aide de renderToString. Contrairement au streaming SSR traditionnel qui peut envoyer des morceaux de contenu dès qu'ils deviennent disponibles, ces nouvelles API attendent spécifiquement que TOUTES les données soient chargées avant de générer le HTML final. Ils sont conçus pour fonctionner de manière transparente avec les environnements de streaming modernes tels que Node.js Streams et Web Streams, mais ils ne prennent pas intentionnellement en charge le streaming de contenu partiel. Au lieu de cela, ils garantissent que vous obtenez des pages complètes et entièrement chargées au moment de la construction. Elles diffèrent des méthodes traditionnelles de streaming SSR, qui envoient des sites pré-rendus dès que les données deviennent disponibles.

Nous avions déjà des frameworks compatibles SSG construits sur React, comme NextJS, mais il s'agit de la fonctionnalité native de React pour SSG. Les frameworks dans lesquels SSG utilisait renderToString, puis construisaient leurs propres coordinations complexes de récupération de données autour de celui-ci. Il était extrêmement difficile pour les utilisateurs de le créer eux-mêmes, et pour ce faire, ces frameworks utilisaient des pipelines extrêmement complexes. Ces nouvelles méthodes permettent essentiellement de charger les données pendant la génération HTML statique. Si vous n'êtes pas familier avec SSG, il s'agit essentiellement de tout restituer au moment de la construction et constitue sans aucun doute la méthode la plus rapide de rendu des pages, car elle n'a pas pour rendre les pages à la demande de l'utilisateur, c'est donc formidable d'avoir ce type de fonctionnalité pour les personnes qui ne veulent pas utiliser quelque chose comme Next, qui nécessite soit un déploiement sur Vercel, soit un processus de déploiement extrêmement complexe.

Composants du serveur

Le concept de composants serveur React ne sera pas nouveau pour quiconque a utilisé une version récente de NextJS, mais pour tous ceux qui ne l'ont pas encore fait, les composants serveur constituent un nouveau paradigme autour de la récupération de données. Franchement, le concept de composants serveur (et d'actions serveur) mérite à lui seul un article entier, mais pour résumer brièvement le concept, les composants serveur sont toujours rendus sur le serveur avant d'être envoyés au client, même après le chargement de javascript. Cela signifie que les rendus suivants sont effectués côté serveur.

Le principal avantage de ces composants est la sécurité et la récupération de données : si vous demandez des données à l'intérieur d'un composant serveur, les informations de la demande n'apparaissent jamais côté client, uniquement la réponse, ce qui la rend beaucoup plus sécurisée. Les API, les points de terminaison, etc. ne sont tout simplement pas accessibles côté client. Cela réduit également la taille du bundle puisque le javascript pour ces actions n'est jamais envoyé au client. Il vous permet en outre d'exécuter des opérations gourmandes en mémoire ou en calcul sur le serveur afin de réduire la charge de rendu sur des machines moins puissantes. Ils réduisent également les cascades côté client puisque la récupération séquentielle des données peut être effectuée sur des machines plus proches de vos bases de données, mais bien sûr, cela ouvre également la possibilité de toutes nouvelles cascades côté serveur puisque vos développeurs perdent l'accès aux demandes d'informations faciles auprès du développeur du navigateur de test. outils et doivent utiliser quelque chose comme un collecteur et une visionneuse OpenTelemetry pour les examiner. Enfin, les composants du serveur sont également parfaits pour une amélioration progressive.

Les composants du serveur sont également accompagnés d'une liste de limitations : vous ne pouvez pas utiliser les API du navigateur local (stockage local, fenêtre, etc.), les hooks de réaction fonctionneront différemment, vous ne pouvez pas compter sur ou utiliser l'état, et vous pouvez ' Je n'utilise pas de gestionnaires d'événements, l'interactivité des utilisateurs pour les composants est donc décidément mince. Fondamentalement, considérez ce paradigme comme la récupération de données dans les composants serveur, l'interactivité sur les composants clients.

La mise en garde la plus importante pour toute personne qui découvre les composants serveur est que vous ne pouvez pas les importer dans un composant client - si vous le faites, cela entraînera une erreur (en supposant que vous ayez ajouté une récupération de données) car cela amènera le compilateur à traiter ledit composant serveur en tant que composant client. Si vous souhaitez transmettre un composant serveur à un composant client, vous devez le transmettre via la prop {children}.

Actions du serveur

Il s'agit d'un autre sujet complexe avec de nombreuses implications sur la façon dont vous créez vos produits et fonctionnalités, et ceux-ci sont également présents dans NextJS depuis environ un an. Les actions du serveur sont déclarées en tapant « utiliser le serveur » en haut d'un fichier et transmettent une référence directe à ladite fonction serveur qui peut ensuite être appelée depuis l'intérieur d'un composant client.

À un certain niveau, ceux-ci sont conceptuellement similaires aux appels de procédure à distance (RPC) : ils vous permettent tous deux d'appeler des fonctions côté serveur à partir du client, tous deux résument la complexité des interactions client-serveur et gèrent tous deux la sérialisation et la désérialisation, mais il y a quelques différences clés à prendre en compte. Le principal avantage des actions de serveur est qu'elles fonctionnent avec l'amélioration progressive de React, aident à appliquer la sécurité des types au-delà des limites client/serveur, ont des optimisations de performances intégrées (liées à l'amélioration progressive) et ont une intégration plus transparente avec l'écosystème React. en ce sens qu'ils fournissent des états en attente intégrés et sont automatiquement intégrés aux soumissions de formulaires natifs.

Lorsque vous parlez de RPC moderne, quelque chose comme gRPC qui dispose déjà d'une sécurité de type et de certaines optimisations de performances, le principal avantage des actions du serveur se résume généralement à la gestion intégrée des formulaires et à l'amélioration progressive, mais surtout, cela fonctionne également. avec des limites de suspense et d'erreur de réaction. Plus important encore, le déploiement est beaucoup plus simple puisque vous n'avez pas nécessairement besoin de configurer un serveur séparé pour gRPC, ils sont donc absolument plus idéaux pour les petits projets, bien que lorsqu'il s'agit de projets plus importants, je peux voir que gRPC est beaucoup plus souhaitable puisque cela vous donne plus de flexibilité en termes de langage backend, etc.

Contexte en tant que fournisseur

Il s'agit essentiellement d'une simplification de la syntaxe, aidant React en général à avoir une syntaxe déclarative beaucoup plus propre. Pour être honnête, je n’ai pas grand-chose à dire à ce sujet à part « j’aime ça ».

Réf comme fonction d'accessoire et de nettoyage pour les références

Auparavant, pour nettoyer les références, vous deviez effectuer une vérification nulle à l'intérieur de votre composant, et la référence était nettoyée à un moment quelque peu indéterminé. React appellerait votre rappel ref avec null lorsque le composant serait démonté, ce qui vous obligerait à gérer explicitement les cas d'attachement et de détachement. L'avantage de la nouvelle syntaxe ref est le nettoyage déterministe - ce qui signifie qu'il est désormais beaucoup plus facile de travailler avec des ressources externes et des bibliothèques tierces car vous saurez exactement quand le nettoyage des références aura lieu (au démontage). Avec la nouvelle approche, vous pouvez renvoyer directement une fonction de nettoyage. L'intégration TypeScript nécessite des instructions de retour explicites pour éviter toute ambiguïté sur les fonctions de nettoyage.

J'aime vraiment la façon dont cela a été implémenté car c'est le même modèle que useEffect - maintenir la cohérence à travers le framework est génial. Je pense que ce nouveau nettoyage de référence sera spécifiquement très utile pour les contextes WebGL et autres ressources lourdes, mais aussi pour gérer les écouteurs d'événements DOM ajoutés à l'aide de méthodes JS natives. En effet, auparavant, réagir supprimait la référence à l'élément dom lors du nettoyage… Mais si vous avez fait cela, il devient beaucoup plus complexe de supprimer les écouteurs d'événements puisque vous avez perdu la référence au composant auquel ils sont attachés. . En conséquence, vous deviez stocker vos références en dehors de l'élément, ce qui ajoutait une couche de complexité. Vous pouvez désormais simplement supprimer les écouteurs d'événements dans la fonction de retour de votre composant, car vous conservez l'accès à la référence dans ladite fonction de retour. Cela signifie également que nous n'avons plus à nous soucier du cas nul dans la plupart des situations, car React n'appellera plus la référence avec null lors de l'utilisation des fonctions de nettoyage. La fonction de nettoyage elle-même remplace cette fonctionnalité, rendant notre code plus propre et plus prévisible.

useDeferredValue

Le but du hook useDeferredValue est de gérer des opérations coûteuses en termes de calcul tout en conservant une interface utilisateur réactive. Il y parvient en permettant aux composants d'afficher une valeur « périmée » précédente lors du calcul ou de la récupération de nouvelles données en arrière-plan. Un cas d'utilisation courant est la fonctionnalité de recherche qui affiche les résultats au fur et à mesure que les utilisateurs tapent - sans différer, chaque frappe pourrait déclencher une opération de recherche coûteuse qui rendrait la saisie lente. Grâce à useDeferredValue, l'interface peut rester réactive en affichant les résultats de recherche précédents tout en en calculant de nouveaux.

Ce nouvel ajout est une amélioration importante du comportement de chargement initial de ce crochet. Auparavant, le premier rendu utilisait immédiatement la valeur transmise à useDeferredValue, déclenchant potentiellement un calcul coûteux dès le début. La nouvelle version vous permet de fournir une valeur initiale légère (telle qu'une chaîne vide) qui s'affiche immédiatement, tout en traitant la valeur la plus coûteuse en arrière-plan. Cela signifie que vous pouvez montrer aux utilisateurs un retour immédiat avec une valeur par défaut sûre, puis le mettre à jour avec des données réelles une fois le calcul coûteux terminé. Essentiellement, cela rend useDeferredValue encore meilleur pour l’amélioration des performances.

Ajouts de métadonnées de documents

Ces nouvelles modifications concernent l'ajout de diverses balises de métadonnées à l'intérieur des composants réels. Ils examinent trois options : , et <meta>. Il est important de noter que <title> n'a pas de déduplication - vous n'êtes censé l'utiliser qu'une seule fois par dépôt. Les deux autres, <link> et <meta>, ont des interactions assez complexes concernant la déduplication qui, après apprentissage, je pense qu'elles ne seront pas particulièrement pertinentes pour 90 % des utilisateurs. </p> <p>Le principal avantage de ces changements est qu'ils permettent aux composants d'être véritablement autonomes : ils peuvent désormais gérer leurs propres métadonnées ainsi que leurs styles et scripts. Vous n’avez plus besoin de comprendre comment élever les métadonnées au niveau supérieur ou d’utiliser une bibliothèque pour le faire, ce qui rend le référencement beaucoup plus facile à réaliser. Différentes pages d'un SPA peuvent avoir différentes métadonnées plus facilement sans risquer de désynchroniser les métadonnées avec le contenu affiché sur la page, ce qui était auparavant un risque lorsqu'il y avait différentes métadonnées pour différentes pages.</p> <p><strong>Support des feuilles de style</strong></p> <p>Les gens utilisent peut-être Tailwind depuis si longtemps qu'ils l'ont oublié, mais l'exécution de CSS non encapsulés peut créer des problèmes en raison de la façon dont les feuilles de style sont chargées, à savoir les règles de priorité de l'ordre de chargement. Premièrement, vous pouvez vous retrouver avec des flashs de contenu sans style : chaque fois que le code HTML se charge et s'affiche avant la fin du téléchargement du CSS, il s'affiche sous la forme d'une page entièrement blanche, généralement dans une seule colonne avec des tailles de police massives et des tailles d'image natives, ce qui est souvent le cas. le rend illisible.</p> <p>De plus, les règles d'ordre de chargement CSS peuvent créer d'autres problèmes : par exemple, si vous avez des règles avec la même spécificité mais que vous vous attendez à ce qu'elles se chargent dans un certain ordre. Ceci est pertinent, par exemple, lorsque vous disposez de différentes options pour les thèmes (par exemple le mode sombre). Si le CSS du mode sombre est destiné à être chargé en dernier, mais que votre fichier CSS pour le mode sombre se charge en premier, vous pouvez vous retrouver avec le mode sombre étant clair, ou certaines parties de l'application où les règles sont respectées et d'autres parties où elles le sont. t respecté. </p> <p>Il existait de nombreuses solutions pour éviter cela, comme CSS dans JS, charger tous les CSS dans le répertoire <head> balise, temps de construction regroupant les CSS, etc. Cependant, ces nouvelles modifications CSS sont destinées à aider à gérer ces problèmes en définissant la priorité de manière déclarative - elles garantissent également que toutes les feuilles de style placées dans un composant sont chargées avant le rendu du composant lui-même. Il est également intégré à la déduplication, de sorte que vous n'avez pas à charger la même feuille de style plusieurs fois lorsque vous réutilisez des composants avec des liens de feuille de style inclus. </p> <p>La façon dont vous accédez à cette nouvelle fonctionnalité (attendre que le CSS se charge avant de restituer un composant, hisser automatiquement le CSS en tête, etc.) est également assez simple - il vous suffit d'inclure une priorité dans un <lien> particulier. ; composant. Dans l’ensemble, j’aime la dactylographie, donc cela ne résout pas exactement de problèmes particuliers pour moi, mais je suis sûr que ce seront de grands projets hérités extrêmement utiles. </p> <p><strong>Prise en charge des scripts asynchrones</strong></p> <p>Cela répond à un cas limite, par opposition à la création d'une nouvelle fonctionnalité de base dont les gens doivent s'inquiéter : ajouter manuellement/gérer directement des scripts avec un <script> la balise est assez rare dans React moderne d'après mon expérience. La plupart des développeurs utilisent des bundles comme webpack ou vite, des gestionnaires de packages, des instructions d'importation, et si les scripts doivent être chargés dynamiquement, ils utilisent quelque chose comme useEffect. Cependant, cela est pertinent pour SSR et une meilleure UX afin d'éviter les problèmes susmentionnés avec l'ordre de chargement du contenu dans <head>. </p> <p>Étant donné que les scripts peuvent être chargés de manière asynchrone, cela signifie qu'il y a beaucoup moins de chances que les applications de réaction se chargent sans les styles appropriés. Le changement est également pertinent pour les développeurs gérant des systèmes existants qui nécessitent des balises de script directes ou pour les développeurs chargés de gérer des scripts tiers qui ne peuvent pas être regroupés (par exemple, des analyses, des widgets, etc.), ou pour empêcher un script particulièrement lourd (par exemple, une vidéo). player) se chargeant avant qu'il soit nécessaire d'améliorer les performances, mais comme je n'ai pas d'expérience avec ceux-ci, je ne peux pas vraiment en dire plus. </p> <p><strong>Prise en charge des ressources de préchargement</strong></p> <p>Les nouvelles API de gestion du préchargement des ressources sont très intéressantes, en particulier pour les grandes entreprises qui doivent garantir des expériences de chargement transparentes pour des publics mondiaux avec des conditions de réseau très variables, pour les applications particulièrement riches en contenu qui s'appuient sur de lourdes ressources tierces provenant de différentes sources. , et pour toute application où les performances perçues sont importantes pour la fidélisation des utilisateurs (ce qui, pour être honnête, est presque tout) </p> <p>Cependant, la plupart des frameworks qui reposent sur React (par exemple Next, Remix, etc.) ont déjà tendance à gérer cela - je ne suis pas vraiment sûr de la façon dont ces nouvelles API interagiront avec lesdits frameworks, mais il semble que ce soit le cas. Ce sera une nouvelle source de conflits et quelque chose d'important à garder à l'esprit lors de l'utilisation de ces frameworks et de la tentative d'optimisation des performances à l'aide de ces nouvelles API. </p> <p>Bien que le préchargement soit certainement l'API avec le cas d'utilisation le plus large (chargement de feuilles de style, etc.), grâce au problème ci-dessus, celle qui, à mon avis, est la plus pertinente est preinit - c'est un chargement difficile qui démarre immédiatement et est destiné à être chargé avec impatience. scripts. L'utilisation la plus évidente à laquelle je puisse penser est quelque chose comme le chargement immédiat de Stripe lors de l'examen du panier - cela devrait accélérer considérablement le processus de paiement, ce qui est une étape du commerce électronique où vous ne voulez absolument pas perdre de clients en raison de problèmes de performances. . </p> <p><strong>Compatibilité des scripts tiers</strong></p> <p>Il s'agit d'un changement plutôt bienvenu étant donné que les modules complémentaires de navigateur sont de plus en plus courants. Je peux penser à quelques exemples de modifications de la structure DOM qui bénéficient probablement de ce changement : les bloqueurs de publicités, les outils de comparaison de prix, les modules complémentaires d'assistant de grammaire/IA et les extensions de traduction. . Il n'y a pas grand chose d'autre à dire à ce sujet sans lire comment fonctionne l'hydratation maintenant, même s'il semble que le principal changement soit que le compilateur ignore les balises inattendues. </p> <p><strong>Meilleur rapport d'erreurs</strong></p> <p>J'ai trouvé cette section assez explicite. Les modifications apportées à la gestion des erreurs sont toujours les bienvenues : le spam d'erreurs qui existait auparavant rendait toujours un peu plus difficile la recherche d'erreurs spécifiques. Ceci est particulièrement pertinent si vous utilisez des solutions tierces moins bien entretenues qui ont tendance à générer une tonne d'erreurs.<br> Prise en charge des éléments personnalisés</p> <p>Cette section m'a été particulièrement intéressante puisque je n'avais jamais entendu parler des éléments personnalisés auparavant. En résumé, les éléments personnalisés sont un nouveau standard Web permettant aux développeurs de créer leurs propres éléments HTML. Grâce au respect des standards Web mentionnés, ils sont destinés à fonctionner sur n'importe quelle page et à être indépendants du framework - par exemple, vous pouvez écrire un composant que vous utilisez couramment dans tous vos projets personnels, ce que vous avez tendance à faire de manière svelte, puis l'utiliser pour des projets plus petits. travail contractuel que vous effectuez pour des startups ou des contrats à court terme en vue, etc. </p> <p>React était utilisé pour traiter les accessoires non reconnus comme des attributs plutôt que comme des propriétés réelles - la nouvelle mise à jour a ajouté un système qui permet d'utiliser correctement les accessoires pour créer des éléments personnalisés. Il semble qu'avec ce changement, l'utilisation des éléments personnalisés dans React soit désormais entièrement prise en charge. Par ailleurs, en plus du problème des accessoires, il y avait également des incompatibilités (maintenant résolues) avec le système d'événements synthétiques de React - Les éléments personnalisés ne pouvaient pas s'intégrer proprement au système, il y avait donc des cas où vous deviez le faire manuellement. ajoutez des écouteurs d'événements avec ref, entre autres solutions de contournement. </p> <p>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!</p> </div> </div> <div style="height: 25px;"> <div style="display: inline-flex;float: right; color:#333333;">source:dev.to</div> </div> <div class="wzconOtherwz"> <a href="https://www.php.cn/fr/faq/1796752021.html" title="Créer un outil de suppression d'arrière-plan alimenté par l'IA avec React et Transformers.js"> <span>Article précédent:Créer un outil de suppression d'arrière-plan alimenté par l'IA avec React et Transformers.js</span> </a> <a href="https://www.php.cn/fr/faq/1796752027.html" title="Levage Javascript"> <span>Article suivant:Levage Javascript</span> </a> </div> <div class="wzconShengming"> <div class="bzsmdiv">Déclaration de ce site Web</div> <div>Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn</div> </div> <ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-5902227090019525" data-ad-slot="2507867629"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> <div class="wzconZzwz"> <div class="wzconZzwztitle">Derniers articles par auteur</div> <ul> </ul> </div> <div class="wzconZzwz"> <div class="wzconZzwztitle">Derniers numéros</div> <div class="wdsyContent"> <div class="wdsyConDiv flexRow wdsyConDiv1"> <div class="wdcdContent flexColumn"> <a href="https://www.php.cn/fr/wenda/176411.html" target="_blank" title="function_exists() ne peut pas déterminer la fonction personnalisée" class="wdcdcTitle">function_exists() ne peut pas déterminer la fonction personnalisée</a> <a href="https://www.php.cn/fr/wenda/176411.html" class="wdcdcCons">Function test () {return true;} if (function_exists ('test')) {echo "le test est une ...</a> <div class="wdcdcInfo flexRow"> <div class="wdcdcileft"> <span class="wdcdciSpan"> Depuis 2024-04-29 11:01:01</span> </div> <div class="wdcdciright flexRow"> <div class="wdcdcirdz flexRow ira"> <b class="wdcdcirdzi"></b>0 </div> <div class="wdcdcirpl flexRow ira"><b class="wdcdcirpli"></b>3</div> <div class="wdcdcirwatch flexRow ira"><b class="wdcdcirwatchi"></b>2452</div> </div> </div> </div> </div> <div class="wdsyConLine wdsyConLine2"></div> <div class="wdsyConDiv flexRow wdsyConDiv1"> <div class="wdcdContent flexColumn"> <a href="https://www.php.cn/fr/wenda/176410.html" target="_blank" title="Comment afficher la version mobile de Google Chrome" class="wdcdcTitle">Comment afficher la version mobile de Google Chrome</a> <a href="https://www.php.cn/fr/wenda/176410.html" class="wdcdcCons">Bonjour professeur, comment puis-je changer Google Chrome en version mobile ?</a> <div class="wdcdcInfo flexRow"> <div class="wdcdcileft"> <span class="wdcdciSpan"> Depuis 2024-04-23 00:22:19</span> </div> <div class="wdcdciright flexRow"> <div class="wdcdcirdz flexRow ira"> <b class="wdcdcirdzi"></b>0 </div> <div class="wdcdcirpl flexRow ira"><b class="wdcdcirpli"></b>11</div> <div class="wdcdcirwatch flexRow ira"><b class="wdcdcirwatchi"></b>2598</div> </div> </div> </div> </div> <div class="wdsyConLine wdsyConLine2"></div> <div class="wdsyConDiv flexRow wdsyConDiv1"> <div class="wdcdContent flexColumn"> <a href="https://www.php.cn/fr/wenda/176407.html" target="_blank" title="La fenêtre enfant exploite la fenêtre parent, mais la sortie ne répond pas." class="wdcdcTitle">La fenêtre enfant exploite la fenêtre parent, mais la sortie ne répond pas.</a> <a href="https://www.php.cn/fr/wenda/176407.html" class="wdcdcCons">Les deux premières phrases sont exécutables, mais la dernière ne peut pas être implémentée...</a> <div class="wdcdcInfo flexRow"> <div class="wdcdcileft"> <span class="wdcdciSpan"> Depuis 2024-04-19 15:37:47</span> </div> <div class="wdcdciright flexRow"> <div class="wdcdcirdz flexRow ira"> <b class="wdcdcirdzi"></b>0 </div> <div class="wdcdcirpl flexRow ira"><b class="wdcdcirpli"></b>1</div> <div class="wdcdcirwatch flexRow ira"><b class="wdcdcirwatchi"></b>2187</div> </div> </div> </div> </div> <div class="wdsyConLine wdsyConLine2"></div> <div class="wdsyConDiv flexRow wdsyConDiv1"> <div class="wdcdContent flexColumn"> <a href="https://www.php.cn/fr/wenda/176406.html" target="_blank" title="Il n'y a aucune sortie dans la fenêtre parent" class="wdcdcTitle">Il n'y a aucune sortie dans la fenêtre parent</a> <a href="https://www.php.cn/fr/wenda/176406.html" class="wdcdcCons">document.onclick = function(){ window.opener.document.write('Je suis la sortie de la fenêt...</a> <div class="wdcdcInfo flexRow"> <div class="wdcdcileft"> <span class="wdcdciSpan"> Depuis 2024-04-18 23:52:34</span> </div> <div class="wdcdciright flexRow"> <div class="wdcdcirdz flexRow ira"> <b class="wdcdcirdzi"></b>0 </div> <div class="wdcdcirpl flexRow ira"><b class="wdcdcirpli"></b>1</div> <div class="wdcdcirwatch flexRow ira"><b class="wdcdcirwatchi"></b>2063</div> </div> </div> </div> </div> <div class="wdsyConLine wdsyConLine2"></div> <div class="wdsyConDiv flexRow wdsyConDiv1"> <div class="wdcdContent flexColumn"> <a href="https://www.php.cn/fr/wenda/176405.html" target="_blank" title="Où sont les didacticiels sur la cartographie mentale CSS ?" class="wdcdcTitle">Où sont les didacticiels sur la cartographie mentale CSS ?</a> <a href="https://www.php.cn/fr/wenda/176405.html" class="wdcdcCons">Didacticiel</a> <div class="wdcdcInfo flexRow"> <div class="wdcdcileft"> <span class="wdcdciSpan"> Depuis 2024-04-16 10:10:18</span> </div> <div class="wdcdciright flexRow"> <div class="wdcdcirdz flexRow ira"> <b class="wdcdcirdzi"></b>0 </div> <div class="wdcdcirpl flexRow ira"><b class="wdcdcirpli"></b>0</div> <div class="wdcdcirwatch flexRow ira"><b class="wdcdcirwatchi"></b>2165</div> </div> </div> </div> </div> <div class="wdsyConLine wdsyConLine2"></div> </div> </div> <div class="wzconZt" > <div class="wzczt-title"> <div>Rubriques connexes</div> <a href="https://www.php.cn/fr/faq/zt" target="_blank">Plus> </a> </div> <div class="wzcttlist"> <ul> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/fr/faq/lightningjkjs"><img src="https://img.php.cn/upload/subject/202407/22/2024072212133364310.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="présentation de l'interface Lightning" /> </a> <a target="_blank" href="https://www.php.cn/fr/faq/lightningjkjs" class="title-a-spanl" title="présentation de l'interface Lightning"><span>présentation de l'interface Lightning</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/fr/faq/sswzynx"><img src="https://img.php.cn/upload/subject/202407/22/2024072214371290681.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="Quels sont les sites de recherche ?" /> </a> <a target="_blank" href="https://www.php.cn/fr/faq/sswzynx" class="title-a-spanl" title="Quels sont les sites de recherche ?"><span>Quels sont les sites de recherche ?</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/fr/faq/syff"><img src="https://img.php.cn/upload/subject/202407/22/2024072214084851317.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="Comment utiliser NSTimeInterval" /> </a> <a target="_blank" href="https://www.php.cn/fr/faq/syff" class="title-a-spanl" title="Comment utiliser NSTimeInterval"><span>Comment utiliser NSTimeInterval</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/fr/faq/zmdkapkwj"><img src="https://img.php.cn/upload/subject/202407/22/2024072212241787363.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="Comment ouvrir le fichier apk" /> </a> <a target="_blank" href="https://www.php.cn/fr/faq/zmdkapkwj" class="title-a-spanl" title="Comment ouvrir le fichier apk"><span>Comment ouvrir le fichier apk</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/fr/faq/sslxybknx"><img src="https://img.php.cn/upload/subject/202407/22/2024072213475894254.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="Quels protocoles le protocole SSL inclut-il ?" /> </a> <a target="_blank" href="https://www.php.cn/fr/faq/sslxybknx" class="title-a-spanl" title="Quels protocoles le protocole SSL inclut-il ?"><span>Quels protocoles le protocole SSL inclut-il ?</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/fr/faq/labelbqdyf"><img src="https://img.php.cn/upload/subject/202407/22/2024072213435438431.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="Comment utiliser l'étiquette d'étiquette" /> </a> <a target="_blank" href="https://www.php.cn/fr/faq/labelbqdyf" class="title-a-spanl" title="Comment utiliser l'étiquette d'étiquette"><span>Comment utiliser l'étiquette d'étiquette</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/fr/faq/vscode"><img src="https://img.php.cn/upload/subject/202407/22/2024072214372738907.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="vscode" /> </a> <a target="_blank" href="https://www.php.cn/fr/faq/vscode" class="title-a-spanl" title="vscode"><span>vscode</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/fr/faq/vuexssm"><img src="https://img.php.cn/upload/subject/202407/22/2024072214205345280.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="qu'est-ce que vuex" /> </a> <a target="_blank" href="https://www.php.cn/fr/faq/vuexssm" class="title-a-spanl" title="qu'est-ce que vuex"><span>qu'est-ce que vuex</span> </a> </li> </ul> </div> </div> </div> </div> <div class="phpwzright"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-5902227090019525" data-ad-slot="3653428331" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> <div class="wzrOne"> <div class="wzroTitle">Recommandations populaires</div> <div class="wzroList"> <ul> <li> <div class="wzczzwzli"> <span class="layui-badge-dots wzrolr"></span> <a style="height: auto;" title="que signifie js" href="https://www.php.cn/fr/faq/482163.html">que signifie js</a> </div> </li> <li> <div class="wzczzwzli"> <span class="layui-badge-dots wzrolr"></span> <a style="height: auto;" title="Comment convertir une chaîne en tableau en js ?" href="https://www.php.cn/fr/faq/461802.html">Comment convertir une chaîne en tableau en js ?</a> </div> </li> <li> <div class="wzczzwzli"> <span class="layui-badge-dots wzrolr"></span> <a style="height: auto;" title="Comment actualiser la page en utilisant javascript" href="https://www.php.cn/fr/faq/473330.html">Comment actualiser la page en utilisant javascript</a> </div> </li> <li> <div class="wzczzwzli"> <span class="layui-badge-dots wzrolr"></span> <a style="height: auto;" title="Comment supprimer un élément dans le tableau js" href="https://www.php.cn/fr/faq/475790.html">Comment supprimer un élément dans le tableau js</a> </div> </li> <li> <div class="wzczzwzli"> <span class="layui-badge-dots wzrolr"></span> <a style="height: auto;" title="Comment utiliser la fonction sqrt" href="https://www.php.cn/fr/faq/415276.html">Comment utiliser la fonction sqrt</a> </div> </li> </ul> </div> </div> <script src="https://sw.php.cn/hezuo/cac1399ab368127f9b113b14eb3316d0.js" type="text/javascript"></script> <div class="wzrThree"> <div class="wzrthree-title"> <div>Tutoriels populaires</div> <a target="_blank" href="https://www.php.cn/fr/course.html">Plus> </a> </div> <div class="wzrthreelist swiper2"> <div class="wzrthreeTab swiper-wrapper"> <div class="check tabdiv swiper-slide" data-id="one">Tutoriels associés <div></div></div> <div class="tabdiv swiper-slide" data-id="two">Recommandations populaires<div></div></div> <div class="tabdiv swiper-slide" data-id="three">Derniers cours<div></div></div> </div> <ul class="one"> <li> <a target="_blank" href="https://www.php.cn/fr/course/812.html" title="Le dernier didacticiel vidéo ThinkPHP 5.1 en première mondiale (60 jours pour devenir un expert PHP en ligne)" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/041/620debc3eab3f377.jpg" alt="Le dernier didacticiel vidéo ThinkPHP 5.1 en première mondiale (60 jours pour devenir un expert PHP en ligne)"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Le dernier didacticiel vidéo ThinkPHP 5.1 en première mondiale (60 jours pour devenir un expert PHP en ligne)" href="https://www.php.cn/fr/course/812.html">Le dernier didacticiel vidéo ThinkPHP 5.1 en première mondiale (60 jours pour devenir un expert PHP en ligne)</a> <div class="wzrthreerb"> <div>1427594 <b class="kclbcollectb"></b></div> <div class="courseICollection" data-id="812"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/74.html" title="Premier tutoriel d'introduction à PHP : Apprenez PHP en une semaine" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/068/6253d1e28ef5c345.png" alt="Premier tutoriel d'introduction à PHP : Apprenez PHP en une semaine"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Premier tutoriel d'introduction à PHP : Apprenez PHP en une semaine" href="https://www.php.cn/fr/course/74.html">Premier tutoriel d'introduction à PHP : Apprenez PHP en une semaine</a> <div class="wzrthreerb"> <div>4278047 <b class="kclbcollectb"></b></div> <div class="courseICollection" data-id="74"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/286.html" title="Tutoriel vidéo JAVA pour débutants" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/068/62590a2bacfd9379.png" alt="Tutoriel vidéo JAVA pour débutants"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Tutoriel vidéo JAVA pour débutants" href="https://www.php.cn/fr/course/286.html">Tutoriel vidéo JAVA pour débutants</a> <div class="wzrthreerb"> <div>2578777 <b class="kclbcollectb"></b></div> <div class="courseICollection" data-id="286"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/504.html" title="Tutoriel vidéo d'introduction base zéro à l'apprentissage de Python de Little Turtle" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/068/62590a67ce3a6655.png" alt="Tutoriel vidéo d'introduction base zéro à l'apprentissage de Python de Little Turtle"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Tutoriel vidéo d'introduction base zéro à l'apprentissage de Python de Little Turtle" href="https://www.php.cn/fr/course/504.html">Tutoriel vidéo d'introduction base zéro à l'apprentissage de Python de Little Turtle</a> <div class="wzrthreerb"> <div>510453 <b class="kclbcollectb"></b></div> <div class="courseICollection" data-id="504"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/2.html" title="Tutoriel d'introduction PHP base zéro" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/068/6253de27bc161468.png" alt="Tutoriel d'introduction PHP base zéro"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Tutoriel d'introduction PHP base zéro" href="https://www.php.cn/fr/course/2.html">Tutoriel d'introduction PHP base zéro</a> <div class="wzrthreerb"> <div>867590 <b class="kclbcollectb"></b></div> <div class="courseICollection" data-id="2"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> </ul> <ul class="two" style="display: none;"> <li> <a target="_blank" href="https://www.php.cn/fr/course/812.html" title="Le dernier didacticiel vidéo ThinkPHP 5.1 en première mondiale (60 jours pour devenir un expert PHP en ligne)" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/041/620debc3eab3f377.jpg" alt="Le dernier didacticiel vidéo ThinkPHP 5.1 en première mondiale (60 jours pour devenir un expert PHP en ligne)"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Le dernier didacticiel vidéo ThinkPHP 5.1 en première mondiale (60 jours pour devenir un expert PHP en ligne)" href="https://www.php.cn/fr/course/812.html">Le dernier didacticiel vidéo ThinkPHP 5.1 en première mondiale (60 jours pour devenir un expert PHP en ligne)</a> <div class="wzrthreerb"> <div >1427594 temps d'étude</div> <div class="courseICollection" data-id="812"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/286.html" title="Tutoriel vidéo JAVA pour débutants" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/068/62590a2bacfd9379.png" alt="Tutoriel vidéo JAVA pour débutants"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Tutoriel vidéo JAVA pour débutants" href="https://www.php.cn/fr/course/286.html">Tutoriel vidéo JAVA pour débutants</a> <div class="wzrthreerb"> <div >2578777 temps d'étude</div> <div class="courseICollection" data-id="286"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/504.html" title="Tutoriel vidéo d'introduction base zéro à l'apprentissage de Python de Little Turtle" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/068/62590a67ce3a6655.png" alt="Tutoriel vidéo d'introduction base zéro à l'apprentissage de Python de Little Turtle"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Tutoriel vidéo d'introduction base zéro à l'apprentissage de Python de Little Turtle" href="https://www.php.cn/fr/course/504.html">Tutoriel vidéo d'introduction base zéro à l'apprentissage de Python de Little Turtle</a> <div class="wzrthreerb"> <div >510453 temps d'étude</div> <div class="courseICollection" data-id="504"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/901.html" title="Introduction rapide au développement web front-end" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/067/64be28a53a4f6310.png" alt="Introduction rapide au développement web front-end"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Introduction rapide au développement web front-end" href="https://www.php.cn/fr/course/901.html">Introduction rapide au développement web front-end</a> <div class="wzrthreerb"> <div >216287 temps d'étude</div> <div class="courseICollection" data-id="901"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/234.html" title="Maîtrisez les didacticiels vidéo PS à partir de zéro" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/068/62611f57ed0d4840.jpg" alt="Maîtrisez les didacticiels vidéo PS à partir de zéro"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Maîtrisez les didacticiels vidéo PS à partir de zéro" href="https://www.php.cn/fr/course/234.html">Maîtrisez les didacticiels vidéo PS à partir de zéro</a> <div class="wzrthreerb"> <div >899643 temps d'étude</div> <div class="courseICollection" data-id="234"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> </ul> <ul class="three" style="display: none;"> <li> <a target="_blank" href="https://www.php.cn/fr/course/1648.html" title="[Web front-end] Démarrage rapide de Node.js" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/067/662b5d34ba7c0227.png" alt="[Web front-end] Démarrage rapide de Node.js"/> </a> <div class="wzrthree-right"> <a target="_blank" title="[Web front-end] Démarrage rapide de Node.js" href="https://www.php.cn/fr/course/1648.html">[Web front-end] Démarrage rapide de Node.js</a> <div class="wzrthreerb"> <div >8233 temps d'étude</div> <div class="courseICollection" data-id="1648"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/1647.html" title="Collection complète de cours full-stack de développement Web étranger" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/067/6628cc96e310c937.png" alt="Collection complète de cours full-stack de développement Web étranger"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Collection complète de cours full-stack de développement Web étranger" href="https://www.php.cn/fr/course/1647.html">Collection complète de cours full-stack de développement Web étranger</a> <div class="wzrthreerb"> <div >6562 temps d'étude</div> <div class="courseICollection" data-id="1647"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/1646.html" title="Aller au langage pratique GraphQL" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/067/662221173504a436.png" alt="Aller au langage pratique GraphQL"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Aller au langage pratique GraphQL" href="https://www.php.cn/fr/course/1646.html">Aller au langage pratique GraphQL</a> <div class="wzrthreerb"> <div >5415 temps d'étude</div> <div class="courseICollection" data-id="1646"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/1645.html" title="Le maître du ventilateur de 550 W apprend JavaScript à partir de zéro, étape par étape" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/067/662077e163124646.png" alt="Le maître du ventilateur de 550 W apprend JavaScript à partir de zéro, étape par étape"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Le maître du ventilateur de 550 W apprend JavaScript à partir de zéro, étape par étape" href="https://www.php.cn/fr/course/1645.html">Le maître du ventilateur de 550 W apprend JavaScript à partir de zéro, étape par étape</a> <div class="wzrthreerb"> <div >746 temps d'étude</div> <div class="courseICollection" data-id="1645"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/fr/course/1644.html" title="Le maître Python Mosh, un débutant sans aucune connaissance de base peut commencer en 6 heures" class="wzrthreelaimg"> <img src="https://img.php.cn/upload/course/000/000/067/6616418ca80b8916.png" alt="Le maître Python Mosh, un débutant sans aucune connaissance de base peut commencer en 6 heures"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Le maître Python Mosh, un débutant sans aucune connaissance de base peut commencer en 6 heures" href="https://www.php.cn/fr/course/1644.html">Le maître Python Mosh, un débutant sans aucune connaissance de base peut commencer en 6 heures</a> <div class="wzrthreerb"> <div >27685 temps d'étude</div> <div class="courseICollection" data-id="1644"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> </ul> </div> <script> var mySwiper = new Swiper('.swiper2', { autoplay: false,//可选选项,自动滑动 slidesPerView : 'auto', }) $('.wzrthreeTab>div').click(function(e){ $('.wzrthreeTab>div').removeClass('check') $(this).addClass('check') $('.wzrthreelist>ul').css('display','none') $('.'+e.currentTarget.dataset.id).show() }) </script> </div> <div class="wzrFour"> <div class="wzrfour-title"> <div>Derniers téléchargements</div> <a href="https://www.php.cn/fr/xiazai">Plus> </a> </div> <script> $(document).ready(function(){ var sjyx_banSwiper = new Swiper(".sjyx_banSwiperwz",{ speed:1000, autoplay:{ delay:3500, disableOnInteraction: false, }, pagination:{ el:'.sjyx_banSwiperwz .swiper-pagination', clickable :false, }, loop:true }) }) </script> <div class="wzrfourList swiper3"> <div class="wzrfourlTab swiper-wrapper"> <div class="check swiper-slide" data-id="onef">effets Web <div></div></div> <div class="swiper-slide" data-id="twof">Code source du site Web<div></div></div> <div class="swiper-slide" data-id="threef">Matériel du site Web<div></div></div> <div class="swiper-slide" data-id="fourf">Modèle frontal<div></div></div> </div> <ul class="onef"> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="Code de contact du formulaire de message d'entreprise jQuery" href="https://www.php.cn/fr/toolset/js-special-effects/8071">[bouton de formulaire] Code de contact du formulaire de message d'entreprise jQuery</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="Effets de lecture de boîte à musique HTML5 MP3" href="https://www.php.cn/fr/toolset/js-special-effects/8070">[Effets spéciaux du joueur] Effets de lecture de boîte à musique HTML5 MP3</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="Effets spéciaux du menu de navigation d'animation de particules cool HTML5" href="https://www.php.cn/fr/toolset/js-special-effects/8069">[Navigation dans les menus] Effets spéciaux du menu de navigation d'animation de particules cool HTML5</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="Code d'édition par glisser-déposer du formulaire visuel jQuery" href="https://www.php.cn/fr/toolset/js-special-effects/8068">[bouton de formulaire] Code d'édition par glisser-déposer du formulaire visuel jQuery</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="Code du lecteur de musique Kugou imitation VUE.JS" href="https://www.php.cn/fr/toolset/js-special-effects/8067">[Effets spéciaux du joueur] Code du lecteur de musique Kugou imitation VUE.JS</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="Jeu de boîte de poussée HTML5 classique" href="https://www.php.cn/fr/toolset/js-special-effects/8066">[effets spéciaux HTML5] Jeu de boîte de poussée HTML5 classique</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="défilement jQuery pour ajouter ou réduire des effets d'image" href="https://www.php.cn/fr/toolset/js-special-effects/8065">[Effets spéciaux d'image] défilement jQuery pour ajouter ou réduire des effets d'image</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="Effet de zoom de survol de la couverture de l'album personnel CSS3" href="https://www.php.cn/fr/toolset/js-special-effects/8064">[Effets d'album photo] Effet de zoom de survol de la couverture de l'album personnel CSS3</a> </div> </li> </ul> <ul class="twof" style="display:none"> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8328" title="Modèle de site Web d'entreprise de services de nettoyage et de réparation de décoration intérieure" target="_blank">[Modèle frontal] Modèle de site Web d'entreprise de services de nettoyage et de réparation de décoration intérieure</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8327" title="Modèle de page de guide de CV personnel aux couleurs fraîches" target="_blank">[Modèle frontal] Modèle de page de guide de CV personnel aux couleurs fraîches</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8326" title="Modèle Web de CV de travail créatif de concepteur" target="_blank">[Modèle frontal] Modèle Web de CV de travail créatif de concepteur</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8325" title="Modèle de site Web d'entreprise de construction d'ingénierie moderne" target="_blank">[Modèle frontal] Modèle de site Web d'entreprise de construction d'ingénierie moderne</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8324" title="Modèle HTML5 réactif pour les établissements de services éducatifs" target="_blank">[Modèle frontal] Modèle HTML5 réactif pour les établissements de services éducatifs</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8323" title="Modèle de site Web de centre commercial de boutique de livres électroniques en ligne" target="_blank">[Modèle frontal] Modèle de site Web de centre commercial de boutique de livres électroniques en ligne</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8322" title="La technologie informatique résout le modèle de site Web d'entreprise Internet" target="_blank">[Modèle frontal] La technologie informatique résout le modèle de site Web d'entreprise Internet</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8321" title="Modèle de site Web de service de trading de devises de style violet" target="_blank">[Modèle frontal] Modèle de site Web de service de trading de devises de style violet</a> </div> </li> </ul> <ul class="threef" style="display:none"> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-materials/3078" target="_blank" title="Matériau vectoriel d'éléments d'été mignons (EPS+PNG)">[Matériau PNG] Matériau vectoriel d'éléments d'été mignons (EPS+PNG)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-materials/3077" target="_blank" title="Matériel vectoriel de quatre badges de graduation rouges 2023 (AI+EPS+PNG)">[Matériau PNG] Matériel vectoriel de quatre badges de graduation rouges 2023 (AI+EPS+PNG)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-materials/3076" target="_blank" title="Oiseau chantant et chariot rempli de fleurs design matériel vectoriel de bannière de printemps (AI + EPS)">[image de bannière] Oiseau chantant et chariot rempli de fleurs design matériel vectoriel de bannière de printemps (AI + EPS)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-materials/3075" target="_blank" title="Matériau vectoriel de chapeau de graduation doré (EPS+PNG)">[Matériau PNG] Matériau vectoriel de chapeau de graduation doré (EPS+PNG)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-materials/3074" target="_blank" title="Matériel vectoriel d'icône de montagne de style noir et blanc (EPS+PNG)">[Matériau PNG] Matériel vectoriel d'icône de montagne de style noir et blanc (EPS+PNG)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-materials/3073" target="_blank" title="Matériel vectoriel de silhouette de super-héros (EPS+PNG) avec des capes de couleurs différentes et des poses différentes">[Matériau PNG] Matériel vectoriel de silhouette de super-héros (EPS+PNG) avec des capes de couleurs différentes et des poses différentes</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-materials/3072" target="_blank" title="Matériel vectoriel de bannière Arbor Day de style plat (AI + EPS)">[image de bannière] Matériel vectoriel de bannière Arbor Day de style plat (AI + EPS)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-materials/3071" target="_blank" title="Matériel vectoriel de neuf bulles de discussion explosives de style bande dessinée (EPS+PNG)">[Matériau PNG] Matériel vectoriel de neuf bulles de discussion explosives de style bande dessinée (EPS+PNG)</a> </div> </li> </ul> <ul class="fourf" style="display:none"> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8328" target="_blank" title="Modèle de site Web d'entreprise de services de nettoyage et de réparation de décoration intérieure">[Modèle frontal] Modèle de site Web d'entreprise de services de nettoyage et de réparation de décoration intérieure</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8327" target="_blank" title="Modèle de page de guide de CV personnel aux couleurs fraîches">[Modèle frontal] Modèle de page de guide de CV personnel aux couleurs fraîches</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8326" target="_blank" title="Modèle Web de CV de travail créatif de concepteur">[Modèle frontal] Modèle Web de CV de travail créatif de concepteur</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8325" target="_blank" title="Modèle de site Web d'entreprise de construction d'ingénierie moderne">[Modèle frontal] Modèle de site Web d'entreprise de construction d'ingénierie moderne</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8324" target="_blank" title="Modèle HTML5 réactif pour les établissements de services éducatifs">[Modèle frontal] Modèle HTML5 réactif pour les établissements de services éducatifs</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8323" target="_blank" title="Modèle de site Web de centre commercial de boutique de livres électroniques en ligne">[Modèle frontal] Modèle de site Web de centre commercial de boutique de livres électroniques en ligne</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8322" target="_blank" title="La technologie informatique résout le modèle de site Web d'entreprise Internet">[Modèle frontal] La technologie informatique résout le modèle de site Web d'entreprise Internet</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/fr/toolset/website-source-code/8321" target="_blank" title="Modèle de site Web de service de trading de devises de style violet">[Modèle frontal] Modèle de site Web de service de trading de devises de style violet</a> </div> </li> </ul> </div> <script> var mySwiper = new Swiper('.swiper3', { autoplay: false,//可选选项,自动滑动 slidesPerView : 'auto', }) $('.wzrfourlTab>div').click(function(e){ $('.wzrfourlTab>div').removeClass('check') $(this).addClass('check') $('.wzrfourList>ul').css('display','none') $('.'+e.currentTarget.dataset.id).show() }) </script> </div> </div> </div> <footer> <div class="footer"> <div class="footertop"> <img src="/static/imghw/logo.png" alt=""> <p>Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!</p> </div> <div class="footermid"> <a href="https://www.php.cn/fr/about/us.html">À propos de nous</a> <a href="https://www.php.cn/fr/about/disclaimer.html">Clause de non-responsabilité</a> <a href="https://www.php.cn/fr/update/article_0_1.html">Sitemap</a> </div> <div class="footerbottom"> <p> © php.cn All rights reserved </p> </div> </div> </footer> <input type="hidden" id="verifycode" value="/captcha.html"> <script>layui.use(['element', 'carousel'], function () {var element = layui.element;$ = layui.jquery;var carousel = layui.carousel;carousel.render({elem: '#test1', width: '100%', height: '330px', arrow: 'always'});$.getScript('/static/js/jquery.lazyload.min.js', function () {$("img").lazyload({placeholder: "/static/images/load.jpg", effect: "fadeIn", threshold: 200, skip_invisible: false});});});</script> <script src="/static/js/common_new.js"></script> <script type="text/javascript" src="/static/js/jquery.cookie.js?1736727040"></script> <script src="https://vdse.bdstatic.com//search-video.v1.min.js"></script> <link rel='stylesheet' id='_main-css' href='/static/css/viewer.min.css?2' type='text/css' media='all'/> <script type='text/javascript' src='/static/js/viewer.min.js?1'></script> <script type='text/javascript' src='/static/js/jquery-viewer.min.js'></script> <script type="text/javascript" src="/static/js/global.min.js?5.5.53"></script> <!-- Matomo --> <script> var _paq = window._paq = window._paq || []; /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() { var u="https://tongji.php.cn/"; _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '9']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); })(); </script> <!-- End Matomo Code --> </body> </html>