Importations HTML

Inclure pour le Web

Pourquoi importer des données ?

Pensez à la façon dont vous chargez les différents types de ressources sur le Web. Pour JavaScript, il y a <script src>. En ce qui concerne le CSS, votre référence est probablement <link rel="stylesheet">. Pour les images, il s'agit de <img>. La vidéo a <video>. Audio, <audio>... Allez droit au but ! La plupart des contenus Web se chargent de manière simple et déclarative. Ce n'est pas le cas pour HTML. Voici les possibilités qui s'offrent à vous:

  1. <iframe> : éprouvée, mais lourde. Le contenu d'un iFrame se trouve entièrement dans un contexte distinct de votre page. Bien qu'il s'agisse généralement d'une fonctionnalité intéressante, elle pose des problèmes supplémentaires (il est difficile d'encapsuler la taille du cadre dans son contenu, extrêmement frustrant d'insérer/de supprimer un script, et de créer un style presque impossible).
  2. AJAX : J'adore xhr.responseType="document", mais vous dites que j'ai besoin de JavaScript pour charger du code HTML ? Il semble y avoir un problème.
  3. CrazyHacksTM : intégré dans des chaînes et masqué comme commentaire (par exemple, <script type="text/html">). Zut !

Vous voyez l'ironie ? Le contenu le plus élémentaire du Web, le langage HTML, est plus facile à utiliser. Heureusement, les Web Components sont là pour nous aider à nous remettre sur les rails.

Premiers pas

Les importations HTML, qui font partie de la fonctionnalité Web Components, permettent d'inclure des documents HTML dans d'autres documents HTML. Vous n'êtes pas non plus limité au balisage. Une importation peut également inclure du code CSS, JavaScript ou tout autre élément qu'un fichier .html peut contenir. En d'autres termes, les importations sont ainsi un outil fantastique pour charger le code HTML/CSS/JS associé.

Principes de base

Incluez une importation sur votre page en déclarant un <link rel="import">:

<head>
    <link rel="import" href="/path/to/imports/stuff.html">
</head>

L'URL d'une importation est appelée emplacement d'importation. Pour charger du contenu à partir d'un autre domaine, l'emplacement d'importation doit être compatible avec CORS:

<!-- Resources on other origins must be CORS-enabled. -->
<link rel="import" href="http://example.com/elements.html">

Détection de fonctionnalités et compatibilité

Pour détecter la prise en charge, vérifiez si .import existe dans l'élément <link>:

function supportsImports() {
    return 'import' in document.createElement('link');
}

if (supportsImports()) {
    // Good to go!
} else {
    // Use other libraries/require systems to load files.
}

La compatibilité du navigateur n'en est encore qu'à ses débuts. Chrome 31 a été le premier navigateur à voir une implémentation, mais d'autres fournisseurs de navigateurs attendent de voir comment se dérouleront les modules ES. Toutefois, pour d'autres navigateurs, le polyfill webcomponents.js fonctionne parfaitement jusqu'à ce qu'il soit largement accepté.

Regroupement des ressources

Les importations permettent de regrouper les fichiers HTML/CSS/JS (même d'autres importations HTML) en un seul livrable. C'est une fonctionnalité intrinsèque, mais elle est extrêmement efficace. Si vous créez un thème ou une bibliothèque, ou si vous souhaitez simplement segmenter votre application en éléments logiques, fournir aux utilisateurs une seule URL est séduisant. Vous pouvez même envoyer une application complète via une importation. Réfléchissez-y un instant.

Voici un exemple concret : l'amorçage. Bootstrap est constitué de fichiers individuels (bootstrap.css, bootstrap.js, polices), nécessite JQuery pour ses plug-ins et fournit des exemples de balisage. Les développeurs apprécient la flexibilité à la carte. Cela leur permet d'adhérer aux parties du framework qu'ils souhaitent utiliser. Cela dit, je parie que votre JoeDeveloperTM standard adopte la méthode la plus simple et télécharge Bootstrap.

Les importations sont très logiques pour Bootstrap, par exemple. Je vous présente l'avenir du chargement de Bootstrap:

<head>
    <link rel="import" href="bootstrap.html">
</head>

Les utilisateurs chargent simplement un lien d'importation HTML. Ils n'ont pas besoin de s'attarder sur le côté dispersé des fichiers. L'intégralité de Bootstrap est gérée et incluse dans une importation, bootstrap.html:

<link rel="stylesheet" href="bootstrap.css">
<link rel="stylesheet" href="fonts.css">
<script src="jquery.js"></script>
<script src="bootstrap.js"></script>
<script src="bootstrap-tooltip.js"></script>
<script src="bootstrap-dropdown.js"></script>
...

<!-- scaffolding markup -->
<template>
    ...
</template>

Laisse-moi reposer. C'est génial.

Événements de chargement/d'erreur

L'élément <link> déclenche un événement load lorsqu'une importation est correctement chargée et onerror lorsque la tentative échoue (par exemple, si la ressource renvoie une erreur 404).

Le chargement des importations est immédiat. Pour éviter facilement des problèmes, utilisez les attributs onload/onerror:

<script>
    function handleLoad(e) {
    console.log('Loaded import: ' + e.target.href);
    }
    function handleError(e) {
    console.log('Error loading import: ' + e.target.href);
    }
</script>

<link rel="import" href="file.html"
        onload="handleLoad(event)" onerror="handleError(event)">

Si vous créez l'importation de façon dynamique:

var link = document.createElement('link');
link.rel = 'import';
// link.setAttribute('async', ''); // make it async!
link.href = 'file.html';
link.onload = function(e) {...};
link.onerror = function(e) {...};
document.head.appendChild(link);

Utiliser le contenu

Inclure une importation sur une page ne signifie pas "placer le contenu de ce fichier ici". Cela signifie "analyseur, allez récupérer ce document pour que je puisse l'utiliser". Pour utiliser réellement le contenu, vous devez prendre des mesures et écrire un script.

L'étape aha! essentielle consiste à réaliser qu'une importation n'est qu'un document. En fait, le contenu d'une importation est appelé un document d'importation. Vous êtes capable de manipuler une importation à l'aide des API DOM standards.

link.import

Pour accéder au contenu d'une importation, utilisez la propriété .import de l'élément link:

var content = document.querySelector('link[rel="import"]').import;

link.import est défini sur null dans les conditions suivantes:

  • Le navigateur ne prend pas en charge les importations HTML.
  • <link> ne comporte pas de rel="import".
  • Le <link> n'a pas été ajouté au DOM.
  • <link> a été supprimé du DOM.
  • La ressource n'est pas compatible avec CORS.

Exemple complet

Imaginons que warnings.html contienne:

<div class="warning">
    <style>
    h3 {
        color: red !important;
    }
    </style>
    <h3>Warning!
    <p>This page is under construction
</div>

<div class="outdated">
    <h3>Heads up!
    <p>This content may be out of date
</div>

Les importateurs peuvent récupérer une partie spécifique de ce document et la cloner sur leur page:

<head>
    <link rel="import" href="warnings.html">
</head>
<body>
    ...
    <script>
    var link = document.querySelector('link[rel="import"]');
    var content = link.import;

    // Grab DOM from warning.html's document.
    var el = content.querySelector('.warning');

    document.body.appendChild(el.cloneNode(true));
    </script>
</body>

Rédiger des scripts dans les importations

Les importations ne figurent pas dans le document principal. Il s'agit d'une connexion satellite. Toutefois, votre importation peut toujours agir sur la page principale, même si le document principal est prioritaire. Une importation peut accéder à son propre DOM et/ou au DOM de la page qui l'importe:

Exemple : fichier import.html qui ajoute l'une de ses feuilles de style à la page principale

<link rel="stylesheet" href="http://www.example.com/styles.css">
<link rel="stylesheet" href="http://www.example.com/styles2.css">

<style>
/* Note: <style> in an import apply to the main
    document by default. That is, style tags don't need to be
    explicitly added to the main document. */
#somecontainer {
color: blue;
}
</style>
...

<script>
// importDoc references this import's document
var importDoc = document.currentScript.ownerDocument;

// mainDoc references the main document (the page that's importing us)
var mainDoc = document;

// Grab the first stylesheet from this import, clone it,
// and append it to the importing document.
    var styles = importDoc.querySelector('link[rel="stylesheet"]');
    mainDoc.head.appendChild(styles.cloneNode(true));
</script>

Notez ce qui se passe ici. Le script à l'intérieur de l'importation fait référence au document importé (document.currentScript.ownerDocument) et ajoute une partie de ce document à la page d'importation (mainDoc.head.appendChild(...)). Ce n'est pas un problème si vous le demandez.

Règles JavaScript dans une importation:

  • Le script de l'importation est exécuté dans le contexte de la fenêtre contenant le document d'importation. window.document fait donc référence au document de la page principale. Cette approche présente deux corollaires utiles :
    • les fonctions définies dans une importation se terminent par window.
    • vous n'avez rien de difficile, comme ajouter les blocs <script> de l'importation à la page principale. Là encore, le script est exécuté.
  • Les importations ne bloquent pas l'analyse de la page principale. Cependant, les scripts qu'ils contiennent sont traités dans l'ordre. Cela signifie que vous obtenez un comportement différé tout en conservant un ordre de script approprié. Vous trouverez plus d'informations à ce sujet ci-dessous.

Fournir des composants Web

La conception des importations HTML se prête bien au chargement de contenu réutilisable sur le Web. Il s'agit en particulier d'un moyen idéal de distribuer des composants Web. Tout, des <template> HTML simplifiés aux éléments personnalisés complets avec Shadow DOM [1, 2, 3]. Lorsque ces technologies sont utilisées conjointement, les importations deviennent un #include pour les composants Web.

Inclure des modèles

L'élément de modèle HTML convient parfaitement aux importations HTML. <template> est idéal pour échafauder des sections de balisage afin que l'application d'importation puisse les utiliser comme bon leur semble. L'encapsulation du contenu dans un <template> vous permet également de le rendre inerte jusqu'à son utilisation. Autrement dit, les scripts ne s'exécutent pas tant que le modèle n'a pas été ajouté au DOM). Magnifique !

import.html

<template>
    <h1>Hello World!</h1>
    <!-- Img is not requested until the <template> goes live. -->
    <img src="world.png">
    <script>alert("Executed when the template is activated.");</script>
</template>
index.html

<head>
    <link rel="import" href="import.html">
</head>
<body>
    <div id="container"></div>
    <script>
    var link = document.querySelector('link[rel="import"]');

    // Clone the <template> in the import.
    var template = link.import.querySelector('template');
    var clone = document.importNode(template.content, true);

    document.querySelector('#container').appendChild(clone);
    </script>
</body>

Enregistrer des éléments personnalisés

Les éléments personnalisés sont une autre technologie de composant Web qui fonctionne de manière absurde avec les importations HTML. Les importations permettent d'exécuter des scripts. Nous vous conseillons donc de ne pas définir et enregistrer vos éléments personnalisés afin que les utilisateurs n'aient pas à le faire. Appelez-le..."-enregistrement automatique".

elements.html

<script>
    // Define and register <say-hi>.
    var proto = Object.create(HTMLElement.prototype);

    proto.createdCallback = function() {
    this.innerHTML = 'Hello, <b>' +
                        (this.getAttribute('name') || '?') + '</b>';
    };

    document.registerElement('say-hi', {prototype: proto});
</script>

<template id="t">
    <style>
    ::content > * {
        color: red;
    }
    </style>
    <span>I'm a shadow-element using Shadow DOM!</span>
    <content></content>
</template>

<script>
    (function() {
    var importDoc = document.currentScript.ownerDocument; // importee

    // Define and register <shadow-element>
    // that uses Shadow DOM and a template.
    var proto2 = Object.create(HTMLElement.prototype);

    proto2.createdCallback = function() {
        // get template in import
        var template = importDoc.querySelector('#t');

        // import template into
        var clone = document.importNode(template.content, true);

        var root = this.createShadowRoot();
        root.appendChild(clone);
    };

    document.registerElement('shadow-element', {prototype: proto2});
    })();
</script>

Cette importation définit (et enregistre) deux éléments : <say-hi> et <shadow-element>. Le premier présente un élément personnalisé de base qui s'enregistre dans l'importation. Le deuxième exemple montre comment implémenter un élément personnalisé qui crée un Shadow DOM à partir d'un <template>, puis s'enregistre.

Le principal avantage de l'enregistrement d'éléments personnalisés dans une importation HTML est que l'outil d'importation les déclare simplement sur sa page. Aucun câblage n'est nécessaire.

index.html

<head>
    <link rel="import" href="elements.html">
</head>
<body>
    <say-hi name="Eric"></say-hi>
    <shadow-element>
    <div>( I'm in the light dom )</div>
    </shadow-element>
</body>

Selon moi, ce workflow à lui seul fait de l'importation HTML un moyen idéal de partager des composants Web.

Gérer les dépendances et les sous-importations

Sous-importations

Il peut être utile qu'une importation en inclue une autre. Par exemple, si vous souhaitez réutiliser ou étendre un autre composant, utilisez une importation pour charger les autres éléments.

Vous trouverez ci-dessous un exemple réel tiré de Polymer. Il s'agit d'un nouveau composant d'onglet (<paper-tabs>) qui réutilise une mise en page et un sélecteur. Les dépendances sont gérées à l'aide d'importations HTML.

papier-tabs.html (simplifié):

<link rel="import" href="iron-selector.html">
<link rel="import" href="classes/iron-flex-layout.html">

<dom-module id="paper-tabs">
    <template>
    <style>...</style>
    <iron-selector class="layout horizonta center">
        <content select="*"></content>
    </iron-selector>
    </template>
    <script>...</script>
</dom-module>

Les développeurs d'applications peuvent importer ce nouvel élément à l'aide des éléments suivants:

<link rel="import" href="paper-tabs.html">
<paper-tabs></paper-tabs>

Lorsqu'une nouvelle <iron-selector2> plus performante sera disponible à l'avenir, vous pourrez remplacer <iron-selector> et commencer à l'utiliser immédiatement. Grâce aux importations et aux composants Web, vous n'altérerez pas vos utilisateurs.

Gestion des dépendances

Nous savons tous que le chargement de JQuery plus d'une fois par page provoque des erreurs. Lorsque plusieurs composants utilisent la même bibliothèque, ne va-t-il pas s'agir d'un important problème pour les composants Web ? Pas si nous utilisons les importations HTML ! Ils peuvent être utilisés pour gérer les dépendances.

En encapsulant les bibliothèques dans une importation HTML, vous dédupliquez automatiquement les ressources. Le document n'est analysé qu'une seule fois. Les scripts ne sont exécutés qu'une seule fois. Par exemple, supposons que vous définissiez une importation, jquery.html, qui charge une copie de JQuery.

jquery.html

<script src="http://cdn.com/jquery.js"></script>

Cette importation peut être réutilisée dans d'autres importations comme suit:

import2.html

<link rel="import" href="jquery.html">
<div>Hello, I'm import 2</div>
ajax-element.html

<link rel="import" href="jquery.html">
<link rel="import" href="import2.html">

<script>
    var proto = Object.create(HTMLElement.prototype);

    proto.makeRequest = function(url, done) {
    return $.ajax(url).done(function() {
        done();
    });
    };

    document.registerElement('ajax-element', {prototype: proto});
</script>

Même la page principale elle-même peut inclure jquery.html si elle a besoin de la bibliothèque:

<head>
    <link rel="import" href="jquery.html">
    <link rel="import" href="ajax-element.html">
</head>
<body>

...

<script>
    $(document).ready(function() {
    var el = document.createElement('ajax-element');
    el.makeRequest('http://example.com');
    });
</script>
</body>

Bien que le fichier jquery.html soit inclus dans de nombreuses arborescences d'importation différentes, son document n'est récupéré et traité qu'une seule fois par le navigateur. L'examen du panneau "Network" prouve que:

Le fichier jquery.html est demandé une fois
Le fichier jquery.html est demandé une fois

Considérations sur les performances

Les importations HTML sont vraiment géniales, mais comme pour toute nouvelle technologie Web, vous devez les utiliser à bon escient. Les bonnes pratiques de développement Web sont toujours valables. Voici quelques points à retenir.

Concaténer les importations

Il est toujours important de réduire le nombre de requêtes réseau. Si vous disposez de nombreux liens d'importation de premier niveau, envisagez de les regrouper en une seule ressource et d'importer ce fichier.

Vulcanize est un outil de compilation npm créé par l'équipe Polymer qui aplatit de manière récursive un ensemble d'importations HTML en un seul fichier. Considérez cela comme une étape de compilation de concaténation pour les composants Web.

Les importations exploitent la mise en cache du navigateur

Beaucoup oublient que la pile réseau du navigateur a été optimisée au fil des années. Les importations (et les sous-importations) tirent également parti de cette logique. L'importation http://cdn.com/bootstrap.html peut comporter des sous-ressources, mais celles-ci seront mises en cache.

Le contenu n'est utile que lorsque vous l'ajoutez

Considérez le contenu comme inerte jusqu'à ce que vous faisiez appel à ses services. Prenons une feuille de style normale créée dynamiquement:

var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'styles.css';

Le navigateur ne demande pas le fichier styles.css tant que link n'a pas été ajouté au DOM:

document.head.appendChild(link); // browser requests styles.css

Autre exemple : le balisage créé dynamiquement :

var h2 = document.createElement('h2');
h2.textContent = 'Booyah!';

Le h2 est relativement dénué de sens tant que vous ne l'ajoutez pas au DOM.

Le même concept s'applique au document d'importation. Si vous n'ajoutez pas son contenu au DOM, il s'agit d'une opération no-op. En fait, la seule chose qui "s'exécute" directement dans le document d'importation est <script>. Consultez la section Créer des scripts dans les importations.

Optimiser le chargement asynchrone

Affichage du blocage des importations

Les importations bloquent l'affichage de la page principale. Cette méthode est semblable à celle de <link rel="stylesheet">. Le navigateur bloque l'affichage dans les feuilles de style pour minimiser le code FOUC. Les importations se comportent de la même manière, car elles peuvent contenir des feuilles de style.

Pour être complètement asynchrone et ne pas bloquer l'analyseur ni l'affichage, utilisez l'attribut async:

<link rel="import" href="/path/to/import_that_takes_5secs.html" async>

async n'est pas l'option par défaut pour les importations HTML, car elle nécessite que les développeurs effectuent plus de travail. L'option synchrone par défaut signifie que le chargement et la mise à niveau des importations HTML contenant des définitions d'éléments personnalisés sont garantis, dans l'ordre. Dans un monde totalement asynchrone, les développeurs devraient gérer eux-mêmes cette danse et les mises à jour.

Vous pouvez également créer une importation asynchrone de manière dynamique:

var l = document.createElement('link');
l.rel = 'import';
l.href = 'elements.html';
l.setAttribute('async', '');
l.onload = function(e) { ... };

Les importations ne bloquent pas l'analyse.

Les importations ne bloquent pas l'analyse de la page principale. Les scripts des importations sont traités dans l'ordre, mais ne bloquent pas la page d'importation. Cela signifie que vous obtenez un comportement différé tout en conservant un ordre de script approprié. Le fait de placer vos importations dans <head> présente l'avantage de permettre à l'analyseur de commencer à travailler sur le contenu dès que possible. Cela dit, il est essentiel de garder à l'esprit que <script> dans le document principal continue de bloquer toujours la page. La première <script> après une importation bloque l'affichage de la page. En effet, une importation peut contenir un script qui doit être exécuté avant le script figurant sur la page principale.

<head>
    <link rel="import" href="/path/to/import_that_takes_5secs.html">
    <script>console.log('I block page rendering');</script>
</head>

En fonction de la structure de votre application et de votre cas d'utilisation, il existe plusieurs façons d'optimiser le comportement asynchrone. Les techniques ci-dessous limitent le blocage de l'affichage de la page principale.

Scénario 1 (recommandé): vous n'avez pas de script dans <head> ni intégré dans <body>

Je vous recommande d'éviter de suivre immédiatement vos importations pour <script>. Déplacez les scripts le plus tard possible dans le jeu... mais vous appliquez déjà cette bonne pratique, N'ÊTES-VOUS PAS ? ;)

Exemple :

<head>
    <link rel="import" href="/path/to/import.html">
    <link rel="import" href="/path/to/import2.html">
    <!-- avoid including script -->
</head>
<body>
    <!-- avoid including script -->

    <div id="container"></div>

    <!-- avoid including script -->
    ...

    <script>
    // Other scripts n' stuff.

    // Bring in the import content.
    var link = document.querySelector('link[rel="import"]');
    var post = link.import.querySelector('#blog-post');

    var container = document.querySelector('#container');
    container.appendChild(post.cloneNode(true));
    </script>
</body>

Tout se trouve en bas.

Scénario 1.5: l'importation s'ajoute elle-même

Vous pouvez également demander à l'importation d'ajouter son propre contenu. Si l'auteur de l'importation établit un contrat que le développeur de l'application doit suivre, l'importation peut s'ajouter elle-même à une zone de la page principale:

import.html:

<div id="blog-post">...</div>
<script>
    var me = document.currentScript.ownerDocument;
    var post = me.querySelector('#blog-post');

    var container = document.querySelector('#container');
    container.appendChild(post.cloneNode(true));
</script>
index.html

<head>
    <link rel="import" href="/path/to/import.html">
</head>
<body>
    <!-- no need for script. the import takes care of things -->
</body>

Scénario 2: vous avez un script dans <head> ou intégré à <body>

Si le chargement de l'une de vos importations prend beaucoup de temps, le premier élément <script> qui la suit sur la page bloque son affichage. Google Analytics, par exemple, recommande de placer le code de suivi dans la <head>. Si vous ne pouvez pas éviter de placer <script> dans <head>, l'ajout dynamique de l'importation empêchera le blocage de la page:

<head>
    <script>
    function addImportLink(url) {
        var link = document.createElement('link');
        link.rel = 'import';
        link.href = url;
        link.onload = function(e) {
        var post = this.import.querySelector('#blog-post');

        var container = document.querySelector('#container');
        container.appendChild(post.cloneNode(true));
        };
        document.head.appendChild(link);
    }

    addImportLink('/path/to/import.html'); // Import is added early :)
    </script>
    <script>
    // other scripts
    </script>
</head>
<body>
    <div id="container"></div>
    ...
</body>

Vous pouvez également ajouter l'importation vers la fin de <body>:

<head>
    <script>
    // other scripts
    </script>
</head>
<body>
    <div id="container"></div>
    ...

    <script>
    function addImportLink(url) { ... }

    addImportLink('/path/to/import.html'); // Import is added very late :(
    </script>
</body>

Éléments à retenir

  • Le type MIME d'une importation est text/html.

  • Les ressources d'autres origines doivent être compatibles avec CORS.

  • Les importations provenant de la même URL sont récupérées et analysées une seule fois. Cela signifie que le script d'une importation n'est exécuté que la première fois que l'importation s'affiche.

  • Les scripts d'une importation sont traités dans l'ordre, mais ne bloquent pas l'analyse du document principal.

  • Un lien d'importation ne signifie pas "#inclure le contenu ici". Cela signifie "analyseur, allez récupérer ce document pour pouvoir l'utiliser plus tard". Alors que les scripts s'exécutent au moment de l'importation, les feuilles de style, le balisage et les autres ressources doivent être explicitement ajoutés à la page principale. Notez que <style> n'a pas besoin d'être ajouté explicitement. Il s'agit d'une différence majeure entre les importations HTML et <iframe>, qui indique qu'il faut "charger et afficher ce contenu ici".

Conclusion

Les importations HTML permettent de regrouper les fichiers HTML/CSS/JS en tant que ressource unique. Bien que cette idée soit utile en elle-même, elle devient extrêmement puissante dans le monde des composants Web. Les développeurs peuvent créer des composants réutilisables que d'autres peuvent utiliser et importer dans leur propre application, tous fournis via <link rel="import">.

Le concept d'importation HTML est simple, mais il permet de réaliser un certain nombre de cas d'utilisation intéressants pour la plate-forme.

Cas d'utilisation

  • Distribuez du contenu HTML/CSS/JS en tant que bundle unique. En théorie, vous pouvez importer une application Web entière dans une autre.
  • Organisation du code : segmentez les concepts de manière logique dans différents fichiers, ce qui favorise la modularité et la réutilisation**.
  • Envoyer une ou plusieurs définitions d'élément personnalisé. Une importation peut être utilisée pour register ces éléments et les inclure dans une application. Cette méthode utilise de bons modèles logiciels, en séparant l'interface ou la définition de l'élément de la façon dont il est utilisé.
  • Gérer les dépendances : les ressources sont automatiquement dédupliquées.
  • Scripts fragmentés : avant les importations, le fichier d'une bibliothèque JavaScript de grande taille était entièrement analysé afin de démarrer, ce qui était lent. Avec les importations, la bibliothèque peut commencer à fonctionner dès que le bloc A est analysé. Moins de latence !
// TODO: DevSite - Code sample removed as it used inline event handlers
  • Parallélisme de l'analyse HTML : première fois que le navigateur est en mesure d'exécuter deux analyseurs HTML (ou plus) en parallèle.

  • Permet de basculer entre les modes débogage et non-débogage dans une application, en modifiant simplement la cible d'importation. Votre application n'a pas besoin de savoir si la cible d'importation est une ressource groupée/compilée ou une arborescence d'importation.