Uno sguardo all'interno del browser web moderno (parte 2)

Mariko Kosaka

Cosa succede nella navigazione

Questa è la seconda parte di una serie di blog in 4 parti che esamina il funzionamento interno di Chrome. Nel post precedente abbiamo visto in che modo sono diverse e i thread gestiscono parti diverse di un browser. In questo post, spiegheremo più nel dettaglio ogni processo e ogni thread comunicano per mostrare un sito web.

Vediamo un semplice caso d'uso della navigazione sul web: digiti un URL in un browser, quindi il browser recupera i dati da internet e visualizza una pagina. In questo post, ci concentreremo sulla parte in cui l'utente richiede un sito e il browser si prepara a visualizzare una pagina (operazione nota anche come navigazione).

Inizia con un processo del browser

Processi del browser
. Figura 1: UI del browser in alto, diagramma del processo del browser con UI, rete e spazio di archiviazione thread all'interno in basso

Come abbiamo visto parte 1: CPU, GPU, memoria e architettura multiprocesso, tutto ciò al di fuori di una scheda è gestito dal processo del browser. Il processo del browser include thread come il thread dell'interfaccia utente che disegna pulsanti e campi di immissione del browser, il thread di rete che si occupa dello stack di rete per ricevere dati da internet, il thread di archiviazione che controlla l'accesso ai file e altro ancora. Quando digiti un URL nell'indirizzo l'input è gestito dal thread dell'interfaccia utente del processo del browser.

Una navigazione semplice

Passaggio 1: gestione dell'input

Quando un utente inizia a digitare nella barra degli indirizzi, la prima cosa che il thread dell'interfaccia utente chiede è: "Is this a query di ricerca o URL?". In Chrome, la barra degli indirizzi è anche un campo di immissione di ricerca, quindi il thread dell'interfaccia utente deve analizzare e decidere se indirizzarti a un motore di ricerca o al sito che hai richiesto.

Gestione dell'input dell'utente
. Figura 1: UI Thread che chiede se l'input è una query di ricerca o un URL

Passaggio 2: avvia la navigazione

Quando un utente preme Invio, il thread dell'interfaccia utente avvia una chiamata di rete per ottenere i contenuti del sito. Rotellina di caricamento viene visualizzato nell'angolo di una scheda e il thread di rete utilizza protocolli appropriati come Ricerca DNS e connessione TLS in corso per la richiesta.

Inizio navigazione
. Figura 2: il thread dell'interfaccia utente che comunica con il thread di rete per passare a mysite.com

A questo punto, il thread di rete potrebbe ricevere un'intestazione di reindirizzamento del server come HTTP 301. In questo caso, il thread di rete comunica con il thread UI che il server richiede il reindirizzamento. Quindi, verrà avviata un'altra richiesta di URL.

Passaggio 3: leggi la risposta

Risposta HTTP
. Figura 3: intestazione della risposta che contiene Content-Type e il payload, ovvero i dati effettivi

Quando inizia a ricevere il corpo della risposta (payload), il thread di rete esamina i primi byte dello stream, se necessario. L'intestazione Content-Type della risposta dovrebbe indicare il tipo di dati, ma poiché potrebbe mancare o essere errato, Sniffing del tipo MIME qui. Si tratta di un'attività "difficile" come commentato nel codice sorgente. Puoi leggere il commento per vedere in che modo i diversi browser trattano le coppie tipo di contenuti/payload.

Se la risposta è un file HTML, il passaggio successivo consiste nel passare i dati al renderer se si tratta di un file ZIP o di un altro file, allora si tratta di una richiesta di download devono passare i dati a Gestione dei download.

Sniffing del tipo MIME
. Figura 4: thread di rete in cui viene chiesto se i dati di risposta provengono da HTML di un sito sicuro

È qui che viene eseguito il controllo SafeBrowsing. Se il dominio e i dati di risposta sembrano corrispondere a un sito dannoso noto, il thread di rete avvisi per visualizzare una pagina di avviso. Inoltre, Crossorigin cead cresione (CORB) viene eseguito un controllo per verificare che i dati non arrivano al processo del renderer.

Passaggio 4: trova un processo del renderer

Dopo aver completato tutti i controlli e aver verificato che il browser debba passare alla richiesto, il thread di rete indica al thread dell'interfaccia utente che i dati sono pronti. un thread dell'interfaccia utente trova quindi processo di rendering per continuare il rendering della pagina web.

Trova il processo del renderer
. Figura 5: thread di rete che indica al thread dell'interfaccia utente di trovare il processo del renderer

Poiché la richiesta di rete potrebbe impiegare diverse centinaia di millisecondi per ricevere una risposta, l'ottimizzazione per velocizzare il processo. Quando il thread della UI invia una richiesta di URL a al thread di rete al passaggio 2, sa già a quale sito accede. Thread UI tenta di trovare o avviare in modo proattivo un processo di rendering in parallelo alla richiesta di rete. In questo modo se tutto funziona come previsto, un processo del renderer è già in posizione standby quando il thread di rete i dati ricevuti. Questo processo di standby potrebbe non essere utilizzato se la navigazione reindirizza tra siti, in nel qual caso potrebbe essere necessario un processo diverso.

Passaggio 5: esegui il commit della navigazione

Ora che i dati e il processo del renderer sono pronti, il processo del browser invia un IPC al per eseguire il commit della navigazione. Trasmette inoltre lo stream di dati in modo che il renderer di elaborazione può continuare a ricevere dati HTML. Quando il processo del browser riceve una conferma che il commit avvenuta nel processo del renderer, la navigazione è completa e la fase di caricamento del documento inizia.

A questo punto, la barra degli indirizzi viene aggiornata e l'indicatore di sicurezza e l'interfaccia utente delle impostazioni del sito riflettono le informazioni sul sito della nuova pagina. La cronologia delle sessioni della scheda verrà aggiornata in modo da andare avanti/indietro per spostarsi sul sito appena visitato. Per facilitare il ripristino di schede/sessioni quando chiudi una scheda o una finestra, la cronologia delle sessioni viene archiviata su disco.

Esegui il commit della navigazione
. Figura 6: IPC tra il browser e i processi del renderer, richiesta del rendering della pagina

Passaggio aggiuntivo: caricamento iniziale completato

Una volta eseguito il commit della navigazione, il processo del renderer continua il caricamento delle risorse ed esegue il rendering della . Esamineremo i dettagli di ciò che accade in questa fase nel prossimo post. Dopo aver creato processo "finisce" per il rendering, invia un IPC al processo del browser (dopodiché onload eventi sono stati attivati su tutti i frame della pagina e hanno terminato l'esecuzione. A questo punto, il thread UI interrompe la rotellina di caricamento sulla scheda.

Dico "finisce" perché JavaScript lato client potrebbe comunque essere caricato risorse aggiuntive ed eseguire il rendering di nuove visualizzazioni dopo questo punto.

Completamento del caricamento della pagina
. Figura 7: IPC dal renderer al processo del browser per notificare il caricamento della pagina

La navigazione è stata semplice e completa. Ma cosa succede se un utente inserisce un URL diverso nella barra degli indirizzi di nuovo? Il processo del browser segue gli stessi passaggi per passare al sito diverso. Prima di farlo, però, deve verificare se il sito attualmente visualizzato Evento beforeunload.

beforeunload può creare "Lasciare questo sito?" quando provi a uscire dalla pagina o a chiudere la scheda. Tutto ciò che si trova all'interno di una scheda, incluso il codice JavaScript, viene gestito dal processo del renderer, il processo del browser deve verificare il processo del renderer corrente quando arriva una nuova richiesta di navigazione.

gestore di eventi beforeunload
. Figura 8: IPC dal processo del browser a un processo del renderer che indica che sta per vai a un altro sito

Se la navigazione è stata avviata dal processo del renderer (ad esempio, l'utente ha fatto clic su un link o JavaScript lato client ha eseguito window.location = "https://newsite.com") il processo del renderer controlla innanzitutto beforeunload gestori. Poi segue la stessa procedura del browser la navigazione avviata. L'unica differenza è che la richiesta di navigazione viene avviata dal processo del renderer al processo del browser.

Quando la nuova navigazione viene indirizzata verso un sito diverso da quello attualmente visualizzato, viene eseguito un rendering separato viene chiamato il processo per gestire la nuova navigazione, mentre il processo di rendering corrente è mantenuto gestire eventi come unload. Per saperne di più, consulta una panoramica degli stati del ciclo di vita delle pagine e come agganciarti agli eventi con l'API Page Lifecycle.

nuova navigazione e unload
. Figura 9: due IPC da un processo del browser a un nuovo processo del renderer che indicano di eseguire il rendering della pagina e dicendo al vecchio processo del renderer di eseguire l'unload

Nel caso di un service worker

Una modifica recente a questo processo di navigazione è l'introduzione Service worker. Il Service worker è un modo per scrivere proxy di rete nel codice dell'applicazione; consentendo agli sviluppatori web di avere maggiore controllo su cosa cache in locale e quando recuperare nuovi dati dalla rete. Se il service worker è impostato per caricare la pagina dalla cache, non c'è bisogno di richiedere i dati alla rete.

La parte importante da ricordare è che il service worker è il codice JavaScript eseguito in un renderer e il processo di sviluppo. Ma quando arriva la richiesta di navigazione, come fa un processo del browser a sapere che il sito ha una service worker?

Ricerca ambito del service worker
. Figura 10: il thread di rete nel processo del browser che cerca l'ambito del service worker

Quando un service worker è registrato, l'ambito del service worker viene mantenuto come riferimento. (puoi leggere ulteriori informazioni sull'ambito nel Ciclo di vita dei service worker). Quando viene effettuata una navigazione, il thread di rete controlla se il dominio viene confrontato con il service worker registrato Ambiti, se un service worker è registrato per quell'URL, il thread dell'interfaccia utente trova un processo del renderer in per eseguire il codice del service worker. Il service worker può caricare i dati dalla cache, eliminando dalla necessità di richiedere dati alla rete, o potrebbe richiedere nuove risorse alla rete.

navigazione serviceworker
. Figura 11: il thread dell'interfaccia utente in un processo del browser che avvia un processo del renderer per gestire il servizio worker; un thread worker in un processo di rendering richiede quindi i dati alla rete

Puoi notare che questo round trip tra il processo del browser e il processo del renderer potrebbe causare ritardi se il service worker alla fine decide di richiedere i dati alla rete. Navigazione precaricata è un meccanismo per velocizzare l'operazione caricando le risorse in parallelo all'avvio del service worker. Contrassegna queste richieste con un'intestazione, consentendo ai server di decidere di inviare contenuti diversi per queste richieste; Ad esempio, aggiorna solo i dati invece di un documento completo.

Precaricamento navigazione
. Figura 12: il thread dell'interfaccia utente in un processo del browser che avvia un processo del renderer per gestire il servizio worker durante l'avvio di una richiesta di rete in parallelo

Conclusione

In questo post, abbiamo visto cosa succede durante una navigazione e come il codice della tua applicazione web poiché le intestazioni delle risposte e JavaScript lato client interagiscono con il browser. Conoscere il browser dei passi passa attraverso per ottenere dati dalla rete rende più facile capire perché API come la navigazione è stato sviluppato preload. Nel prossimo post vedremo in che modo il browser valuta le nostre HTML/CSS/JavaScript per il rendering delle pagine.

Ti è piaciuto il post? Se hai domande o suggerimenti per il prossimo post, mi piacerebbe ascolta la tua opinione nella sezione dei commenti qui sotto o @kosamari su Twitter.

Successivo: I meccanismi interni di un processo del renderer