Încărcare JavaScript asincronă - accelerează încărcarea paginii. JavaScript asincron vs. Leneș

Salutări, prieteni! Știați că încărcarea JavaScript este unul dintre cele mai mari blocaje în performanța site-ului? Astăzi sarcina mea principală este să explic ce este un script și cum afectează acesta viteza și performanța site-ului.

Un browser care încarcă o etichetă de script oprește redarea paginii până când scriptul este încărcat și executat. Pagina este blocată, iar browserul nu răspunde la acțiunile utilizatorului timp de câteva secunde. Timpul de întârziere depinde de mai mulți factori:

  • configuratii,
  • viteza conexiunii la internet,
  • dimensiunea fișierului și altele...

Din acest motiv, analizatorul de viteză a site-ului web Google PageSpeed ​​​​Insights recomandă eliminarea codului JavaScript care blochează randarea din partea de sus a paginii. O bună practică este să plasați scripturi în partea de jos a site-ului, de exemplu înainte de eticheta de închidere sau să configurați încărcarea asincronă.

Dacă codul de script afectează afișarea părții superioare a site-ului, nu îl puneți într-un fișier separat, ci încorporați-l direct în HTML.

JS poate modifica conținutul site-ului și chiar poate redirecționa către o adresă URL diferită. În acest caz, conectarea scriptului de la sfârșitul documentului va duce la efectul de „smucire” a paginii, de încărcare noi sau de modificare a elementelor existente în partea de sus.

Aplicarea atributelor async și defer la eticheta de script

Să ne dăm seama ce este munca asincronă și amânată în JavaScript și care este diferența fundamentală între atributele asincrone și defer. Dar mai întâi, să ne uităm la secvența procesării unui document folosind o etichetă de script normală.

1 < src = "example.js" >

Pentru acest exemplu ilustrativ, voi folosi următoarele convenții:

- prelucrarea paginii
— încărcarea scriptului
- execuția scriptului

Astfel, secvența de procesare are loc conform următoarei scheme:

Analiza codului HTML este întreruptă în timp ce scriptul se încarcă și se execută, după care continuă. Există o întârziere în afișarea paginii web.

defer atribut

Atributul defer permite browserului să înceapă descărcarea fișierelor js în paralel fără a opri procesarea ulterioară a paginii. Execuția lor are loc după o analiză completă a modelului obiect document (din engleză Document Object Model, prescurtat DOM), în timp ce browserul garantează consistența în funcție de ordinea în care sunt conectate fișierele.

1 < defer src = "example.js" >

atribut asincron

Suportul pentru atributul async a apărut în HTML5, permite browserului să descarce fișiere js în paralel și să le execute imediat după descărcare, fără a aștepta ca restul paginii să fie procesat.

1 < async src = "example.js" >

Diagrama secvenței de procesare:

Aceasta este o descărcare asincronă. Acest atribut este recomandat pentru utilizare în scripturi care nu au un impact semnificativ asupra afișajului documentului. Acestea includ contoare de colectare a statisticilor (Google Analytics, Yandex Metrica), coduri de rețea de publicitate (Yandex Advertising Network, Google AdSense), butoane de rețele sociale și așa mai departe.

Viteza de încărcare a site-ului este unul dintre factorii de clasare în Google.

Conectivitatea JavaScript asincronă reduce timpii de încărcare a paginii prin eliminarea latenței. Împreună cu aceasta, recomand comprimarea și îmbinarea fișierelor js într-unul singur, de exemplu, folosind fișierul . Utilizatorilor le plac site-urile rapide 😎

Paginile web moderne sunt foarte încărcate cu fișiere javascript. Acest lucru duce la o încărcare mai lentă și la afișarea ulterioară a paginii. În cele mai proaste condiții, vizitatorul site-ului trebuie să aștepte până la 30 de secunde.

Accelerează încărcarea paginilor html

Utilizarea modernă a JavaScript

Paginile web moderne sunt foarte încărcate cu fișiere javascript. Acest lucru duce la o încărcare mai lentă și la afișarea ulterioară a paginii. În cele mai rele condiții (conexiune lentă la Internet, multe fișiere javascript), vizitatorul site-ului trebuie să aștepte până la 30 de secunde.

HTML este conceput în așa fel încât o pagină web se încarcă sincron (linie cu linie) încărcând pe rând toate elementele incluse în codul HTML.

Există o cale de ieșire: plasați liniile Javascript la sfârșitul documentului html (prin urmare, acestea vor fi încărcate după desenarea întregii pagini) și numai după aceea conținutul blocurilor va fi afișat în locurile potrivite. Se numeste .

Toate proiectele serioase de astăzi încearcă să treacă la o nouă tehnologie de încărcare cât mai repede posibil. În plus, este absolut ușor.

Există mai multe abordări. Voi începe în ordine.

< script src= "//www.site.ru/script.js" type= "text/javascript" >

Standardul HTML5 acceptă capacitatea de a încărca scripturi în mod asincron, ceea ce poate accelera semnificativ timpul general de recuperare a paginii. Doar adăugați asincron sau amânați.

< script async src= "//www.site.ru/script.js" type= "text/javascript" >

< script defer src= "//www.site.ru/script.js" type= "text/javascript" >

Care este diferența dintre atributele async și defer?

În ambele cazuri, obținem încărcare asincronă a scripturilor. Singura diferență este momentul în care începe executarea scriptului. Un script cu atributul async va fi executat cât mai curând posibil după ce este încărcat complet, dar înainte ca obiectul fereastră să fie încărcat. Dacă se folosește atributul defer, scriptul nu va încălca ordinea de execuție a acestuia în raport cu alte scripturi și execuția sa va avea loc după ce pagina este complet încărcată și analizată, dar înainte de evenimentul DOMContentLoaded al obiectului document.

Din păcate, acest mecanism nu funcționează în prezent în toate browserele (în special IE). De asemenea, nu va funcționa dacă există linii document.write în fișierul script.js.

După cum știu toți experții, Google acordă o atenție deosebită vitezei de încărcare a site-urilor și le reduce pe cele lente în rezultatele căutării. Pentru a ajuta, Google a dezvoltat un script special cu care puteți face încărcare asincronă a javascriptului.

Pentru utilizare, pur și simplu înlocuiți

pe

Și conectați fișierul script extsrc.js

Se va dovedi astfel:

< script src= "//extsrcjs.googlecode.com/svn/trunk/extsrc.js" > < script extsrc= "...." >

Din păcate, această metodă nu funcționează nici pentru fișierele cu document.write

O metodă universală pentru toate browserele. Funcționează chiar și cu document.write

În locul din pagină în care trebuie să afișăm de fapt elementul nostru, creați un bloc div gol:

< div id= "script_block" class = "script_block" >

La sfârșitul paginii, înainte de a introduce un script pentru încărcarea asincronă a fișierelor:

< div id= "script_ad" class = "script_ad" style= "display:none;" >Iată orice fișier sau script care trebuie încărcat.< script type= "text/javascript" >// mutați-l în documentul de poziție de afișare reală. getElementById("script_block" ) . appendChild(document. getElementById("script_ad" ) ); // arată documentul. getElementById("script_ad" ) . stil. afișare = „blocare” ;

În cele mai vechi versiuni de IE (6 și mai jos), încărcarea asincronă nu funcționează, din păcate, dar practic nu mai există astfel de utilizatori. Toate celelalte browsere și servicii folosesc cu succes încărcarea accelerată modernă a paginilor web.

Există o cale de ieșire: plasați liniile Javascript la sfârșitul documentului html (prin urmare, acestea vor fi încărcate după desenarea întregii pagini) și numai după aceea conținutul blocurilor va fi afișat în locurile potrivite. Se numeste . Toate proiectele serioase de astăzi încearcă să treacă la o nouă tehnologie de încărcare cât mai repede posibil. În plus, este absolut ușor.

Există mai multe abordări. Voi începe în ordine.

script src= type= "text/javascript" >

Încărcarea asincronă a scriptului HTML5

Standardul HTML5 acceptă capacitatea de a încărca scripturi în mod asincron, ceea ce poate accelera semnificativ timpul general de recuperare a paginii. Doar adăugați asincron sau amânați.

< script async src= "http://www.site.ru/script.js" type= "text/javascript" >

< script defer src= "http://www.site.ru/script.js" type= "text/javascript" >

Care este diferența dintre atributele async și defer?

În ambele cazuri, obținem încărcare asincronă a scripturilor. Singura diferență este momentul în care începe executarea scriptului. Un script cu atributul async va fi executat cât mai curând posibil după ce este încărcat complet, dar înainte ca obiectul fereastră să fie încărcat. Dacă se folosește atributul defer, scriptul nu va încălca ordinea de execuție a acestuia în raport cu alte scripturi și execuția sa va avea loc după ce pagina este complet încărcată și analizată, dar înainte de evenimentul DOMContentLoaded al obiectului document.

Din păcate, acest mecanism nu funcționează în prezent în toate browserele (în special IE). De asemenea, nu va funcționa dacă există linii document.write în fișierul script.js.

Se încarcă javascript asincron cu script Google

După cum știu toți experții, Google acordă o atenție deosebită vitezei de încărcare a site-urilor și le reduce pe cele lente în rezultatele căutării. Pentru a ajuta, Google a dezvoltat un script special cu care puteți face încărcare asincronă a javascriptului.

Pentru utilizare, pur și simplu înlocuiți

pe

Și conectați fișierul script extsrc.js

Se va dovedi astfel:

< script src= "http://extsrcjs.googlecode.com/svn/trunk/extsrc.js" > < script extsrc= "...." >

Din păcate, această metodă nu funcționează nici pentru fișierele cu document.write

Cea mai bună încărcare javascript asincronă

O metodă universală pentru toate browserele. Funcționează chiar și cu document.write

În locul din pagină în care trebuie să afișăm de fapt elementul nostru, creați un bloc div gol:

< div id= "script_block" class = "script_block" >

La sfârșitul paginii, înainte de a introduce un script pentru încărcarea asincronă a fișierelor:

< div id= "script_ad" class = "script_ad" style= "display:none;" >Iată orice fișier sau script care trebuie încărcat.< script type= "text/javascript" >// mutați-l în documentul de poziție de afișare reală. getElementById("script_block" ) . appendChild(document. getElementById("script_ad" ) ); // arată documentul. getElementById("script_ad" ) . stil. afișare = „blocare” ;

În cele mai vechi versiuni de IE (6 și mai jos), încărcarea asincronă nu funcționează, din păcate, dar practic nu mai există astfel de utilizatori. Toate celelalte browsere și servicii folosesc cu succes încărcarea accelerată modernă a paginilor web.

HTML este conceput astfel încât pagina web să fie încărcată secvenţial linie cu linie, încărcând pe rând toate elementele incluse în codul html. Și dacă unul dintre ele nu este disponibil (de exemplu, JavaScript de pe un site extern nu este citit), atunci încărcarea ulterioară a site-ului se oprește.

Când JS care nu poate fi citit este în partea de sus a paginii, este posibil ca vizitatorul să nu vadă nimic.

Prin urmare, atunci când utilizați JavaScript de pe site-uri terțe pe site-ul dvs., de exemplu pentru a afișa reclame, este foarte recomandabil să le încărcați asincron. În acest caz, JS terță parte nu va întârzia încărcarea și afișarea site-ului dvs.

Din păcate, nu toate rețelele de publicitate oferă posibilitatea de a descărca scripturi în mod asincron. Prin urmare, în acest articol vă voi spune cum să schimbați codul de încărcare sincronă în asincron. Dacă proprietarul acestui script nu oferă această opțiune.

Încărcare JS sincronă standard

De obicei, apelarea unui script de pe un server extern arată astfel:

Încărcarea asincronă a scripturilor, așa cum o face Google/Adsense

Am primit ideea de la Google/Adsense. Pentru ca scriptul să se încarce asincron de restul codului HTML, trebuie să adăugați asincron la codul de apel.

Și acum, pentru ca codul să se încarce asincron, apelul nostru de script de la serverul extern ar trebui să arate astfel:

După cum puteți vedea, totul este simplu. Adevărat, acest lucru va funcționa numai în browserele care acceptă standardul HTML5. La momentul scrierii acestui articol, există o majoritate absolută de astfel de browsere.

Opțiunea propusă nu este 100% universală. Multe scripturi pur și simplu nu mai funcționează după efectuarea acestor modificări. Conform recenziilor de pe Internet, această metodă nu funcționează dacă elementul este utilizat în script document.scrie.

Opțiune fiabilă de încărcare asincronă

Dacă prima opțiune sugerată nu funcționează pentru dvs. Apoi utilizați următoarele recomandări. Aceasta este în esență încărcare leneșă. Deoarece apelul propriu-zis la script are loc chiar la sfârșitul paginii HTML, adică atunci când tot conținutul necesar al paginii este deja pe ecran.

În locul de pe pagină în care doriți să afișați rezultatul JavaScript, trebuie să creați un bloc div gol:

Apoi, la sfârșitul paginii, înainte de eticheta BODY de închidere, inserăm un script pentru încărcare asincronă:

// JavaScript care trebuie să fie încărcat asincron // mutați-l în poziția actuală de afișare document.getElementById("script_block_0").appendChild(document.getElementById("script_ad_0")); // arată document.getElementById("script_ad_0").style.display = "blocare";

Dacă există mai multe blocuri de publicitate, atunci pentru fiecare dintre ele trebuie să repetați totul, creând blocuri DIV individuale unice. Nu uitați să schimbați numele claselor și ID-urile DIV. În exemplul meu, este suficient să schimbați numărul zero, în noul bloc trebuie înlocuit cu 1 și așa mai departe.

Această opțiune este mai complexă, dar funcționează peste tot, cu excepția browserelor foarte vechi precum Internet Explorer 6. Care, din fericire, practic nu se mai găsește pe computerele utilizatorilor.

) Am scris despre efectul pe care fișierele JavaScript îl au asupra căii critice de redare (CRP).


JavaScript este o resursă de blocare pentru parser. Aceasta înseamnă că JavaScript blochează analizarea documentului HTML în sine. Când analizatorul ajunge la eticheta ‹script› (nu contează dacă este intern sau extern), se oprește, preia fișierul (dacă este extern) și îl rulează.

Acest comportament poate fi problematic dacă încărcăm mai multe fișiere JavaScript pe o pagină, deoarece crește timpul de randare pentru prima dată, chiar dacă documentul nu depinde de fapt de acele fișiere.


Din fericire, elementul are două atribute, async și defer, care ne oferă control asupra modului în care sunt încărcate și executate fișierele externe.

Execuție normală

Înainte de a înțelege diferența dintre aceste două atribute, să ne uităm la ce se întâmplă în absența lor. După cum sa menționat mai devreme, în mod implicit, fișierele JavaScript întrerup analizarea documentelor HTML până când sunt primite și executate.
Să luăm un exemplu în care elementul este situat undeva în mijlocul paginii:


... ... ....

Iată ce se va întâmpla atunci când analizatorul procesează documentul:

Analiza HTML este întreruptă până când scriptul este descărcat și executat, crescând astfel timpul până la prima randare.

atribut asincron

Async este folosit pentru a indica browserului că scriptul Pot fi să fie executat asincron.
Analizorul HTML nu trebuie să se oprească când ajunge la etichetă pentru a se încărca și a se executa. Execuția poate avea loc după ce scriptul este primit în paralel cu analizarea documentului.



Atributul este disponibil numai pentru fișierele conectate extern. Dacă un fișier extern are acest atribut, atunci poate fi încărcat în timp ce documentul HTML este încă analizat. Analizorul se va întrerupe pentru a executa scriptul imediat ce fișierul script este încărcat.



defer atribut

Atributul defer spune browserului că scriptul ar trebui să fie executat după ce documentul HTML a fost complet analizat.



Ca și în cazul încărcării asincrone de scripturi, fișierul poate fi încărcat în timp ce documentul HTML este analizat. Cu toate acestea, chiar dacă fișierul script este încărcat complet înainte ca analizatorul să se termine, acesta nu va fi executat până când analizatorul nu va termina de rulat.



Execuție asincronă, întârziată sau normală?

Deci, când ar trebui să utilizați execuția JavaScript asincronă, leneșă sau normală? Ca întotdeauna, depinde de situație și există mai multe întrebări care te pot ajuta să iei decizia corectă.

Unde se află elementul?

Execuția asincronă și leneșă sunt cele mai importante atunci când elementul nu se află la sfârșitul documentului. Documentele HTML sunt analizate în ordine, de la deschidere până la închidere. Dacă fișierul JavaScript extern este plasat imediat înaintea etichetei de închidere, atunci utilizarea asincronă și amânare devine mai puțin adecvată, deoarece analizatorul va fi analizat cea mai mare parte a documentului până atunci și fișierele JavaScript nu vor mai avea efect asupra acestuia.

Este scenariul autosuficient?

Pentru fișierele care nu depind de alte fișiere și/sau nu au nicio dependență, atributul asincron va fi cel mai util. Deoarece nu ne interesează când este executat fișierul, încărcarea asincronă este cea mai potrivită opțiune.

Se bazează scriptul pe un DOM complet analizat?

În multe cazuri, fișierul script conține funcții care interacționează cu DOM. Sau poate că există o dependență de un alt fișier de pe pagină. În astfel de cazuri, DOM-ul trebuie să fie complet analizat înainte ca scriptul să fie executat. De obicei, un astfel de fișier este plasat în partea de jos a paginii pentru a se asigura că totul a fost analizat pentru ca acesta să funcționeze. Cu toate acestea, într-o situație în care din anumite motive fișierul trebuie să fie localizat într-o locație diferită, atributul defer poate fi util.

Scenariul este mic și dependent?

În cele din urmă, dacă scriptul este relativ mic și/sau depinde de alte fișiere, atunci ar putea merita să îl definiți în linie. Deși codul inline blochează analizarea documentului HTML, nu ar trebui să fie o mare problemă dacă documentul este de dimensiuni mici. De asemenea, dacă depinde de alte fișiere, poate fi necesară o blocare minoră.

Suport și motoare de browser moderne

Suportul pentru atributele async și defer este foarte comun:




Este demn de remarcat faptul că comportamentul acestor atribute poate varia ușor între motoarele JavaScript. De exemplu, în V8 (utilizat în Chromium), se încearcă analizarea tuturor scripturilor, indiferent de atributele lor, într-un fir separat dedicat pentru execuția scriptului. Astfel, natura de „blocare a analizatorului” a fișierelor JavaScript ar trebui redusă la minimum în mod implicit.