Intervenir contre document.write()

Avez-vous récemment vu un avertissement semblable au suivant dans votre console développeur dans Chrome et vous vous demandez ce que c'est ?

(index):34 A Parser-blocking, cross-origin script,
https://paul.kinlan.me/ad-inject.js, is invoked via document.write().
This may be blocked by the browser if the device has poor network connectivity.

La composabilité, l'un des grands pouvoirs du Web, nous permet intégrer des services conçus par des tiers pour concevoir de nouveaux produits remarquables ! Un des inconvénients de la composabilité est qu'elle implique une responsabilité partagée sur l'expérience utilisateur. Si l'intégration n'est pas optimale, l'expérience utilisateur seront affectés de manière négative.

L'une des causes connues de mauvaises performances est l'utilisation de document.write() à l'intérieur des pages, en particulier celles qui injectent des scripts. Aussi inoffensif que l'apparence suivante, il peut causer de vrais problèmes aux utilisateurs.

document.write('<script src="https://example.com/ad-inject.js"></script>');

Avant de pouvoir afficher une page, le navigateur doit créer l'arborescence DOM en analysant le balisage HTML. Chaque fois que l'analyseur rencontre un script, il doit s'arrêter et l'exécuter avant de pouvoir continuer. analyser le code HTML. Si le script injecte un autre script de manière dynamique, l'analyseur est obligé d'attendre le téléchargement de la ressource, ce qui peut entraîner un ou plusieurs allers-retours réseau retarder le premier affichage de la page

Pour les utilisateurs dont la connexion est lente (2G, par exemple), les scripts externes sont exécutés de manière dynamique. injecté via document.write() peut retarder l'affichage du contenu de la page principale pour de quelques dizaines de secondes, ou qui empêchent le chargement des pages ou prennent trop de temps l’utilisateur abandonne simplement. L'instrumentation dans Chrome nous a permis d'apprendre des pages contenant des scripts tiers insérés via document.write() sont généralement deux fois plus lent à charger que les autres pages en 2G.

Nous avons collecté des données lors d'un test en conditions réelles de 28 jours sur 1% de Chrome stables et limités aux utilisateurs connectés en 2G. Nous avons constaté que 7,6% des chargements de page sur 2G incluaient au moins un script intersites bloquant les analyseurs inséré via document.write() dans le document de premier niveau. Suite au blocage charge de ces scripts, nous avons constaté les améliorations suivantes concernant ces chargements:

  • 10% de chargements de pages en plus First Contentful Paint (une confirmation visuelle pour l'utilisateur que la page se charge efficacement), 25% de chargements de pages supplémentaires atteignant l'état "entièrement analysé", et 10% d'actualisations en moins ce qui suggère une diminution de la frustration des utilisateurs.
  • Diminution de 21% du temps moyen (plus d'une seconde plus rapide) jusqu'au First Contentful Paint
  • 38% de réduction du temps moyen d'analyse d'une page, ce qui représente un de près de six secondes, ce qui réduit considérablement le temps nécessaire pour afficher ce qui compte pour l'utilisateur.

Avec ces données à l'esprit, Chrome, à partir de la version 55, intervient au nom de toutes les utilisateurs lorsque nous détectons ce schéma malveillant connu en modifiant la façon dont document.write() est gérées dans Chrome (voir État de Chrome). Plus précisément, Chrome n'exécutera pas les éléments <script> injectés via document.write() lorsque toutes les conditions suivantes sont remplies:

  1. La connexion de l'utilisateur est lente, en particulier lorsqu'il est en 2G. (Dans à l'avenir, le changement pourrait être étendu à d'autres utilisateurs ayant une connexion lente, comme une connexion 3G ou Wi-Fi lente.
  2. Le document.write() se trouve dans un document de premier niveau. L'intervention n'a pas ne s'appliquent pas aux scripts document.écrit dans les iFrames, car ils ne bloquent pas de la page principale.
  3. Le script de document.write() bloque les analyseurs. Scripts avec "async" ou "defer" s'exécuteront toujours.
  4. Le script n'est pas hébergé sur le même site. En d'autres termes, Chrome n'intervient pas pour les scripts dont l'eTLD+1 correspond (par exemple, un script hébergé sur js.example.org insérée dans www.example.org).
  5. Le script ne se trouve pas déjà dans le cache HTTP du navigateur. Scripts dans le cache n'engendrera pas de retard sur le réseau et s'exécutera tout de même.
  6. La demande de page n'est pas une actualisation. Chrome n'intervient pas si le a déclenché une actualisation et exécutera la page normalement.

Les extraits tiers utilisent parfois document.write() pour charger des scripts. Heureusement, la plupart des tiers fournissent les alternatives de chargement asynchrone, qui permettre aux scripts tiers de se charger sans bloquer l'affichage du reste des le contenu de la page.

Comment résoudre ce problème ?

Par exemple, n'injectez pas de scripts à l'aide de document.write(). Mer Gérer un ensemble de services connus pour la compatibilité des chargeurs asynchrones que nous vous encourageons à vérifier.

Si votre fournisseur ne figure pas dans la liste et qu'il accepte le chargement de script asynchrone veuillez nous contacter afin que nous puissions mettre à jour la page afin d'aider tous les utilisateurs.

Si votre fournisseur ne permet pas de charger des scripts de manière asynchrone sur votre page, nous vous encourageons à les contacter et faites-le nous savoir comment ils seront affectés.

Si votre fournisseur vous fournit un extrait qui inclut le document.write(), il vous pouvez peut-être ajouter un attribut async à l'élément de script ; ou pour ajouter les éléments de script avec des API DOM telles que document.appendChild() ou parentNode.insertBefore().

Comment détecter quand votre site est affecté ?

De nombreux critères déterminent si la restriction est appliquée, Alors, comment savoir si vous êtes concerné ?

Détecter les connexions 2G d'un utilisateur

Pour comprendre l'impact potentiel de ce changement, vous devez d'abord le nombre d'utilisateurs qui passeront en 2G. Vous pouvez détecter le type de réseau actuel de l'utilisateur. et de la vitesse à l'aide de l'API Network Information, est disponible dans Chrome, puis envoyez un avertissement à vos métriques utilisateur ou analytiques (RUM).

if(navigator.connection &&
    navigator.connection.type === 'cellular' &&
    navigator.connection.downlinkMax <= 0.115) {
    // Notify your service to indicate that you might be affected by this restriction.
}

Détecter les avertissements dans les outils pour les développeurs Chrome

Depuis Chrome 53, les outils de développement génèrent des avertissements pour les document.write() problématiques. . Plus précisément, si une demande document.write() répond aux critères 2 à 5 (Chrome ignore les critères de connexion lors de l'envoi de cet avertissement), l'avertissement ressemble à ceci:

Avertissement d&#39;écriture de document.

Les avertissements dans les outils pour les développeurs Chrome sont très utiles, à grande échelle ? Vous pouvez vérifier les en-têtes HTTP envoyés à votre serveur lorsque et l'intervention de l'utilisateur.

Vérifier vos en-têtes HTTP sur la ressource de script

Lorsqu'un script inséré via document.write a été bloqué, Chrome envoie le l'en-tête suivant à la ressource demandée:

Intervention: <https://shorturl/relevant/spec>;

Lorsqu'un script inséré via document.write est détecté et peut être bloqué dans dans différents cas, Chrome peut envoyer:

Intervention: <https://shorturl/relevant/spec>; level="warning"

L'en-tête d'intervention sera envoyé avec la requête GET pour le script. (de manière asynchrone dans le cas d'une intervention réelle).

Que nous réserve l'avenir ?

Le plan initial est d'exécuter cette intervention lorsque nous détectons les critères d’être satisfaite. Nous avons commencé par afficher un simple avertissement dans la Play Console dans Chrome 53. (version bêta en juillet 2016. La version stable devrait être disponible pour tous les utilisateurs dans septembre 2016).

Nous allons intervenir pour bloquer provisoirement les scripts injectés pour les utilisateurs 2G Chrome 54, qui devrait être en version stable pour tous les utilisateurs de mi-octobre 2016. Consultez le Informations sur l'état de Chrome pour en savoir plus.

Au fil du temps, nous cherchons à intervenir lorsque la connexion d'un utilisateur est lente une connexion 3G ou Wi-Fi lente). Suivez cette entrée "État de Chrome".

Vous voulez en savoir plus ?

Pour en savoir plus, consultez ces ressources supplémentaires: