Intervenire contro document.write()

Di recente hai visto un avviso come il seguente nella Console per gli sviluppatori in Chrome e hai chiesto che cos'era.

(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 componibilità è uno dei grandi poteri del web, che ci consente di semplificare si integrano con servizi creati da terze parti per creare nuovi prodotti eccezionali. Uno. degli svantaggi della componibilità è che implica una responsabilità condivisa sull'esperienza utente. Se l'integrazione non è ottimale, l'esperienza utente ne risentiranno.

Una delle cause note dello scarso rendimento è l'utilizzo di document.write() all'interno delle pagine, in particolare per usi che inseriscono gli script. Per quanto innocuo come sembra quanto segue, può causare problemi reali agli utenti.

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

Prima che il browser possa eseguire il rendering di una pagina, deve creare la struttura DOM analizzando il markup HTML. Ogni volta che l'analizzatore sintattico rileva uno script, deve arrestarsi ed eseguirlo prima di poter continuare durante l'analisi del codice HTML. Se lo script inserisce dinamicamente un altro script, l'analizzatore sintattico è costretto ad attendere maggiore per il download della risorsa, il che può comportare uno o più roundtrip di rete ritarda il tempo per la prima visualizzazione della pagina

Per gli utenti con connessioni lente, ad esempio 2G, script esterni in modo dinamico inserito tramite document.write() può ritardare la visualizzazione dei contenuti della pagina principale per decine di secondi o causare un mancato caricamento delle pagine o un tempo così lungo da l'utente si arrende. Basandoci sulla strumentazione di Chrome, abbiamo imparato che le pagine con script di terze parti inseriti tramite document.write() vengono è in genere due volte più lento rispetto ad altre pagine con tecnologia 2G.

Abbiamo raccolto dati da una prova sul campo di 28 giorni sull'1% di Chrome utenti stabili, riservati agli utenti con connessioni 2G. Abbiamo notato che il 7,6% di tutti i caricamenti pagina su 2G includeva almeno uno script di blocco dell'analizzatore sintattico tra siti che veniva inserita tramite document.write() nel documento di primo livello. In seguito al blocco di questi script, abbiamo riscontrato i seguenti miglioramenti:

  • Il 10% in più di caricamenti pagine raggiungono la copertura First Contentful Paint (una conferma visiva per l'effettivo caricamento della pagina) 25% in più di caricamenti pagina che raggiungono lo stato completamente analizzato e 10% di ricaricamenti in meno suggerendo una diminuzione della frustrazione degli utenti.
  • 21% di riduzione del tempo medio (oltre un secondo più veloce) fino alla First Contentful Paint
  • 38% di riduzione del tempo medio necessario per analizzare una pagina, che rappresenta una di quasi sei secondi, riducendo drasticamente il tempo necessario per mostrare ciò che conta per l'utente.

Tenendo presenti questi dati, Chrome, a partire dalla versione 55, interviene a nome di tutti utenti quando rileviamo questo pattern di errore noto modificando il modo in cui document.write() gestiti in Chrome (vedi Stato di Chrome). Nello specifico, Chrome non eseguirà gli elementi <script> inseriti tramite document.write() quando vengono soddisfatte tutte le seguenti condizioni:

  1. L'utente ha una connessione lenta, in particolare quando utilizza una rete 2G. (tra in futuro, il cambiamento potrebbe essere esteso ad altri utenti con connessioni lente, come 3G o Wi-Fi lento).
  2. document.write() si trova in un documento di primo livello. L'intervento non si applicano agli script document.write all'interno di iframe, in quanto non bloccano rendering della pagina principale.
  3. Lo script nell'document.write() sta bloccando l'analizzatore sintattico. Script con "async" o "defer" verranno comunque eseguiti.
  4. Lo script non è ospitato sullo stesso sito. In altre parole, Chrome non intervenire per script con un eTLD+1 corrispondente (ad es. uno script ospitato su js.example.org inserito su www.example.org).
  5. Lo script non si trova già nella cache HTTP del browser. Script nella cache non subiranno ritardi di rete e continueranno a essere eseguiti.
  6. La richiesta per la pagina non viene ricaricata. Chrome non interverrà se l'utente ha attivato un ricaricamento e la pagina verrà visualizzata normalmente.

A volte gli snippet di terze parti utilizzano document.write() per caricare gli script. Fortunatamente, la maggior parte delle terze parti fornisce alternative di caricamento asincrono, che consentire il caricamento di script di terze parti senza bloccare la visualizzazione del resto dei i contenuti della pagina.

Come faccio a risolvere il problema?

Questa semplice risposta è non inserire script utilizzando document.write(). Me Gestire una serie di servizi noti per il supporto del caricatore asincrono che ti invitiamo a continuare a controllare.

Se il tuo provider non è nell'elenco e supporta il caricamento asincrono di script quindi comunicacelo in modo che possiamo aggiornare la pagina per aiutare tutti gli utenti.

Se il tuo provider non supporta la possibilità di caricare script in modo asincrono nella tua pagina, ti invitiamo a contattarli e facci sapere quali saranno le conseguenze.

Se il tuo fornitore ti fornisce uno snippet che include document.write(), potresti aggiungere un attributo async all'elemento script oppure per aggiungere gli elementi dello script con API DOM, ad esempio document.appendChild() o parentNode.insertBefore().

Come rilevare quando il sito è interessato

Esistono numerosi criteri che determinano se la restrizione viene applicata, Come fai a sapere se il problema ti riguarda?

Rilevare quando un utente è connesso a una rete 2G

Per comprendere il potenziale impatto di questa modifica, è necessario innanzitutto comprendere quanti dei tuoi utenti useranno il 2G. Puoi rilevare il tipo di rete attuale dell'utente e velocità utilizzando l'API Network Information, è disponibile in Chrome e invia un avviso sulle metriche di analisi o utente reale (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.
}

Rilevare gli avvisi in Chrome DevTools

A partire da Chrome 53, DevTools invia avvisi per i problemi relativi a document.write() istruzioni. In particolare, se una richiesta document.write() soddisfa i criteri da 2 a 5 (Chrome ignora i criteri di connessione quando invia questo avviso), l'avviso verrà potrebbe avere il seguente aspetto:

Avviso di scrittura documenti.

Visualizzare avvisi in Chrome DevTools è molto utile, ma come puoi rilevarli all'indirizzo di grandi dimensioni? Puoi verificare le intestazioni HTTP inviate al tuo server quando l'intervento.

Controlla le intestazioni HTTP sulla risorsa script

Quando uno script inserito tramite document.write viene bloccato, Chrome invia lo script la seguente intestazione alla risorsa richiesta:

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

Quando viene trovato uno script inserito tramite document.write che potrebbe essere bloccato in circostanze diverse, Chrome potrebbe inviare:

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

L'intestazione dell'intervento verrà inviata come parte della richiesta GET per lo script (in modo asincrono nel caso di un intervento effettivo).

Che cosa ci riserva il futuro?

Il piano iniziale consiste nell'eseguire l'intervento quando rileviamo i criteri vengono soddisfatte. Abbiamo iniziato mostrando solo un avviso nella Developer Console in Chrome 53. La versione beta era a luglio 2016. Ci aspettiamo che il canale stabile sia disponibile per tutti gli utenti in settembre 2016).

Interverremo per bloccare gli script inseriti per gli utenti 2G inizialmente Chrome 54, che si prevede sia in una versione stabile per tutti gli utenti in metà ottobre 2016. Consulta le Voce dello stato di Chrome per altri aggiornamenti.

Con il tempo, stiamo cercando di intervenire quando un utente ha una connessione lenta (ovvero connessione 3G o Wi-Fi lenta). Segui questa voce sullo stato di Chrome.

Vuoi saperne di più?

Per saperne di più, consulta queste risorse aggiuntive: