I browser analizzano javascript su ogni pagina caricata?


190

I browser (IE e Firefox) analizzano i file javascript collegati ogni volta che la pagina si aggiorna?

Possono memorizzare nella cache i file, quindi immagino che non proveranno a scaricarli ogni volta, ma poiché ogni pagina è essenzialmente separata, mi aspetto che abbattano qualsiasi vecchio codice e lo riesaminino.

Questo è inefficiente, sebbene perfettamente comprensibile, ma mi chiedo se i browser moderni siano abbastanza intelligenti da evitare il passaggio di analisi all'interno dei siti. Sto pensando ai casi in cui un sito utilizza una libreria javascript, come ExtJS o jQuery, ecc.


4
Mio 2c: Sento che i vantaggi in termini di prestazioni della memorizzazione nella cache dei file Javascript analizzati sono troppo piccoli per essere un'ottimizzazione significativa.
Itay Maman,

2
Dai miei parametri di riferimento, potrebbe effettivamente importare. Ad esempio il tempo di caricamento di jQuery è di circa 30msecs (su una macchina desktop veloce), di cui il 20% sta solo analizzando il codice in una rappresentazione eseguibile, e il resto lo sta eseguendo, ovvero inizializzando l'oggetto jQuery in questo caso. Se sei su un dispositivo mobile e utilizzi due o tre librerie, questo ritardo potrebbe essere rilevante, poiché l'esecuzione di JavaScript è bloccata e la pagina è essenzialmente vuota fino a quando ogni script JS non viene caricato in memoria.
Djjeck,

Risposte:


338

Questi sono i dettagli che sono stato in grado di scavare. Vale la pena notare innanzitutto che sebbene JavaScript sia generalmente interpretato ed eseguito su una macchina virtuale, questo non è il caso degli interpreti moderni, che tendono a compilare il sorgente direttamente nel codice macchina (ad eccezione di IE).


Chrome: motore V8

V8 ha una cache di compilazione. Questo memorizza JavaScript compilato utilizzando un hash dell'origine per un massimo di 5 garbage collection. Ciò significa che due parti identiche di codice sorgente condivideranno una voce di cache in memoria indipendentemente dal modo in cui sono state incluse. Questa cache non viene cancellata quando le pagine vengono ricaricate.

fonte


Aggiornamento - 19/03/2015

Il team di Chrome ha rilasciato dettagli sulle loro nuove tecniche per lo streaming e la memorizzazione nella cache di JavaScript .

  1. Streaming degli script

Lo streaming di script ottimizza l'analisi dei file JavaScript. [...]

A partire dalla versione 41, Chrome analizza gli script asincroni e posticipati su un thread separato non appena il download è iniziato. Ciò significa che l'analisi può essere completata in pochi millisecondi al termine del download e il caricamento delle pagine è del 10% più veloce.

  1. Memorizzazione nella cache del codice

Normalmente, il motore V8 compila il JavaScript della pagina ad ogni visita, trasformandolo in istruzioni comprensibili per un processore. Questo codice compilato viene quindi scartato una volta che l'utente si allontana dalla pagina poiché il codice compilato dipende fortemente dallo stato e dal contesto della macchina al momento della compilazione.

Chrome 42 introduce una tecnica avanzata di archiviazione di una copia locale del codice compilato, in modo che quando l'utente ritorna alla pagina, tutti i passaggi di download, analisi e compilazione possano essere saltati. Attraverso tutti i carichi di pagina, ciò consente a Chrome di evitare circa il 40% dei tempi di compilazione e di risparmiare preziosa batteria sui dispositivi mobili.


Opera: Carakan Engine

In pratica ciò significa che ogni volta che un programma di script sta per essere compilato, il cui codice sorgente è identico a quello di qualche altro programma che è stato recentemente compilato, riutilizziamo l'output precedente dal compilatore e saltiamo completamente il passaggio di compilazione. Questa cache è abbastanza efficace negli scenari di navigazione tipici in cui si carica una pagina dopo l'altra dallo stesso sito, ad esempio articoli di notizie diversi da un servizio di notizie, poiché ogni pagina carica spesso la stessa libreria di script, talvolta molto grande.

Pertanto JavaScript viene memorizzato nella cache tra i ricarichi di pagina, due richieste allo stesso script non comporteranno la ricompilazione.

fonte


Firefox: SpiderMonkey Engine

SpiderMonkey utilizza Nanojitcome back-end nativo un compilatore JIT. Il processo di compilazione del codice macchina può essere visto qui . In breve, sembra ricompilare gli script mentre vengono caricati. Tuttavia, se osserviamo più da vicino gli interni Nanojit, vediamo che il monitor di livello superiore jstracer, che viene utilizzato per tracciare la compilazione, può passare attraverso tre fasi durante la compilazione, fornendo un vantaggio a Nanojit:

Lo stato iniziale del monitor di traccia è il monitoraggio. Ciò significa che spidermonkey sta interpretando il bytecode. Ogni volta che spidermonkey interpreta un bytecode di salto all'indietro, il monitor prende nota del numero di volte in cui è stato saltato il valore del PC (counter-target program-counter). Questo numero è chiamato conteggio dei risultati per il PC. Se il conteggio dei colpi di un determinato PC raggiunge un valore di soglia, l'obiettivo viene considerato caldo.

Quando il monitor decide che un PC di destinazione è caldo, viene visualizzato in una tabella di frammenti per vedere se esiste un frammento che contiene il codice nativo per quel PC di destinazione. Se trova un tale frammento, passa alla modalità di esecuzione. Altrimenti passa alla modalità di registrazione.

Ciò significa che per hotframmenti di codice il codice nativo viene memorizzato nella cache. Significa che non sarà necessario ricompilare. Non è chiaro se queste sezioni native con hash vengono mantenute tra gli aggiornamenti di pagina. Ma suppongo che lo siano. Se qualcuno può trovare prove a sostegno di questo, allora eccellente.

EDIT : E 'stato sottolineato che Mozilla sviluppatore Boris Zbarsky ha dichiarato che Gecko non di cache compilato script ancora . Tratto da questa risposta SO .


Safari: JavaScriptCore / SquirelFish Engine

Penso che la migliore risposta per questa implementazione sia già stata data da qualcun altro .

Al momento non memorizziamo nella cache il bytecode (o il codice nativo). È
un'opzione che abbiamo considerato, tuttavia, attualmente, la generazione di codice è una
porzione banale del tempo di esecuzione di JS (<2%), quindi
al momento non lo stiamo perseguendo .

Questo è stato scritto da Maciej Stachowiak , lo sviluppatore principale di Safari. Quindi penso che possiamo ritenerlo vero.

Non sono stato in grado di trovare altre informazioni, ma puoi leggere di più sui miglioramenti di velocità dell'ultimo SquirrelFish Extrememotore qui o sfogliare il codice sorgente qui se ti senti avventuroso.


IE: Chakra Engine

In questo campo non sono disponibili informazioni relative al motore JavaScript (Chakra) di IE9. Se qualcuno sa qualcosa, si prega di commentare.

Questo è abbastanza non ufficiale, ma per le precedenti implementazioni del motore di IE, Eric Lippert ( uno sviluppatore MS di JScript ) afferma in un blog di rispondere qui che:

JScript Classic si comporta come un linguaggio compilato, nel senso che prima dell'esecuzione di qualsiasi programma JScript Classic, controlliamo completamente la sintassi del codice, generiamo un albero di analisi completo e generiamo un bytecode. Quindi eseguiamo il bytecode attraverso un interprete bytecode. In tal senso, JScript è "compilato" come Java. La differenza è che JScript non ti consente di persistere o esaminare il nostro bytecode proprietario . Inoltre, il bytecode è di livello molto più elevato rispetto al bytecode JVM: il linguaggio bytecode JScript Classic è poco più di una linearizzazione dell'albero di analisi, mentre il bytecode JVM è chiaramente concepito per funzionare su una macchina stack di basso livello.

Ciò suggerisce che il bytecode non persiste in alcun modo e quindi il bytecode non viene memorizzato nella cache.


10
+1, eccellente riscrittura. Tuttavia, per quanto riguarda Firefox, consulta questa domanda StackOverflow in cui Borilla Zbarsky, sviluppatore di Mozilla, spiega che Gecko attualmente non lo fa.
cha0site,

Grazie, l'ho visto nei miei viaggi ma non sono riuscito a trovare altre prove a sostegno. Modificherò la risposta con esso.
Jivings,

1
Si noti che ciò che è stato detto su IE è stato detto nel 2003: la prima versione del motore JS di IE9 è stata su IE9 nel 2011.
gsnedders,

Inoltre, Opera memorizza il bytecode JS su più di una semplice ricarica. (Tuttavia, il codice macchina generato non viene memorizzato nella cache).
gsnedders,

2
@Jivings Prendi quanto sopra come fonte. (Sono una delle persone della squadra dei Carakan.)
gsnedders,

12

Opera lo fa, come menzionato nell'altra risposta. ( fonte )

Firefox (motore SpiderMonkey) non memorizza nella cache il bytecode. ( fonte )

WebKit (Safari, Konqueror) non memorizza nella cache il bytecode. ( fonte )

Non sono sicuro di IE [6/7/8] o V8 (Chrome), penso che IE potrebbe fare una sorta di memorizzazione nella cache mentre V8 potrebbe non farlo. IE è un codice chiuso quindi non ne sono sicuro, ma in V8 potrebbe non avere senso memorizzare nella cache il codice "compilato" poiché si compilano direttamente nel codice macchina.


1
IE6–8 quasi certamente non lo farà. IE9 potrebbe, ma non ho alcuna prova in entrambi i modi. JS compilato probabilmente non viene memorizzato nella cache da nessuna parte perché è abbastanza spesso abbastanza grande.
gsnedders,

@gsnedders: non sono sicuro che IE8 non possa tecnicamente farlo, sembra che si compili troppo per bytecode (non ufficiale ma vicino), quindi non c'è motivo tecnico per non memorizzarlo nella cache. IE9 sembra aggiungere un JIT da compilare al codice nativo.
cha0site,

2
Bytecode è stato utilizzato da IE per ... per sempre. Non è una novità in IE8. È solo che, dato che un interprete, l'esecuzione dell'interprete è molto più lenta del tempo di analisi, è del tutto irrilevante. IE9 ha un motore JS completamente nuovo (da zero), quindi non segue nulla tra i due.
gsnedders,

3

Per quanto ne so, solo Opera memorizza nella cache il JavaScript analizzato. Vedere la sezione "Programmi compilati memorizzati nella cache" qui .


grazie, hai ulteriori dettagli anche su altre famiglie di browser?
Ajreal


0

Penso che la risposta corretta sarebbe "non sempre". Da quanto ho capito, sia il browser che il server hanno un ruolo nel determinare ciò che viene memorizzato nella cache. Se hai davvero bisogno di ricaricare i file ogni volta, penso che dovresti essere in grado di configurarlo da Apache (ad esempio). Naturalmente, suppongo che il browser dell'utente potrebbe essere configurato per ignorare quell'impostazione, ma probabilmente è improbabile.

Immagino quindi che nella maggior parte dei casi pratici, i file javascript stessi vengano memorizzati nella cache, ma vengano reinterpretati dinamicamente ogni volta che la pagina viene caricata.


0

Il browser fa sicuramente uso della cache, ma sì, i browser analizzano JavaScript ogni volta che si aggiorna una pagina. Perché ogni volta che una pagina viene caricata dal browser, crea 2 alberi 1.Content tree e 2.render tree.

Questo albero di rendering è costituito dalle informazioni sul layout visivo degli elementi dom. Pertanto, ogni volta che viene caricata una pagina, il javascript viene analizzato e qualsiasi modifica dinamica da parte del javascript gradirà posizionare l'elemento dom, mostrare / nascondere l'elemento, aggiungere / rimuovere l'elemento farà sì che il browser ricrea l'albero di rendering. Ma i moderni broswer come FF e Chrome lo gestiscono in modo leggermente diverso, hanno il concetto di rendering incrementale, quindi ogni volta che ci sono cambiamenti dinamici da js come menzionato sopra, causerà solo il rendering e la riverniciatura di quegli elementi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.