Cum se configurează smartphone-uri și PC-uri. Portal informativ
  • Acasă
  • In contact cu
  • Încărcare JavaScript asincronă. Încărcare JavaScript (fără a bloca redarea documentului, încărcare asincronă)

Încărcare JavaScript asincronă. Încărcare JavaScript (fără a bloca redarea documentului, încărcare asincronă)

Motivul pentru care scriu această postare a fost că de mai multe ori a trebuit să observ că inserarea codului pentru butoanele diferitelor servicii (de exemplu: VKontakte, Facebook, Twitter, Odnoklassniki) într-o pagină a dus la o încetinire vizibilă a încărcării și afișării pagină. Acesta este cazul când se utilizează conexiunea javascriptului extern a acestor servicii sociale.
Dacă folosim butoane grafice statice simple, nu există probleme, deoarece... Acesta este un minim de grafice și scripturi care sunt localizate local (puteți vedea un exemplu de implementare aici http://pervushin.com/social-button-for-blog.html). Dar vedem doar icoane sociale. servicii, nu există statistici (câți oameni au „apreciat” pagina noastră). Acestea. dacă vrem să vedem statistici, va trebui să conectăm scripturi externe. Și aici merită să rețineți că la câte dintre aceste butoane ne-am conectat, browserul este obligat să descarce atât de multe scripturi externe, adică. acestea sunt conexiuni suplimentare la servere externe.

Pentru a arăta ce se întâmplă dacă există scripturi în secțiunea de pe pagină, îmi propun să luăm în considerare o serie de exemple de testare. Voi folosi FireFox 3.6 și FireBug.

Asa de:
1) Cea mai simplă pagină cu un fișier de stil, două scripturi și trei imagini:













Și iată diagrama de încărcare a acestuia:

Vă rugăm să rețineți că toate imaginile sunt încărcate numai după ce a fost încărcat cel mai lung fișier javascript.
Am făcut în mod deliberat încărcarea dummy_css.css și dummy_js.js destul de lungă. Sunt doar două fișiere:

dummy_css.php

html,body(
marja:0;
umplutura:0;
}
.img_container(
margine:0 auto;lățime:500px;
}

dummy_js.php


var param=1;

Deci, puteți vedea că fișierul js blochează încărcarea tuturor celorlalte elemente grafice.

2) Totul este aproape la fel, dar dummy_ js. js este încărcat de pe o gazdă externă:

Situația este similară cu cea anterioară:

3) Să încercăm să schimbăm fișierele css și js din secțiunea head (css vine acum după js):







Să ne uităm la diagrama de încărcare:

Js încă blochează încărcarea imaginilor, indiferent de ce gazdă este încărcată.

4) Să creștem timpul de încărcare css la 4 secunde (cod html ca în cazul lui N3):

5) Un alt caz interesant: css este situat înainte de js, dar css durează mai mult să se încarce















Aici css-ul blochează deja încărcarea imaginilor...

6) Mutați un js înăuntru< body>
















Se vede că dummy_ js. js blochează încărcarea doar a celei de-a treia imagini, care se află în codul html după ea. Dar dacă CSS durează mai mult să se încarce, atunci va bloca încărcarea graficelor. Nu este greu de imaginat că scripturile externe conectate pot încetini foarte mult încărcarea și redarea paginii, mai ales dacă serverul de la distanță durează mult timp să răspundă dintr-un anumit motiv.

Plasarea scripturilor externe înainte

Ceea ce sugerează imediat... Toate scripturile a căror încărcare nu este critică pentru pagină ar trebui plasate chiar înaintea etichetei de închidere. Dar acest lucru se poate face pentru acele scripturi în care toată logica este internă și nu există apeluri externe din codul html. Dacă, din codul html, unele funcții sunt apelate din scripturi care nu au fost încă încărcate, atunci astfel de situații trebuie tratate într-un mod special, deoarece trebuie să urmăriți descărcarea.

Dar mai este o problemă, permiteți-mi să vă explic cu un exemplu:




$("img").click(function() (
alert($(this).attr("src");
});
});






Dacă js înainte durează mult timp să se încarce, atunci făcând clic pe imagini până când acest script este încărcat complet nu va duce la nimic, deoarece $(document).ready() va funcționa numai după ce js este încărcat complet. Deci, dacă există o logică pe pagini care implică procesarea evenimentelor, atunci această metodă nu este potrivită.

Deci, ceea ce este necesar este o modalitate de a încărca scripturile fără blocare...

Creați async.js:



script.src = "dummy_js.js";


si conecteaza-l:











$(document).ready(funcție() (
$("img").click(function() (
alert($(this).attr("src");
});
});






Dacă apelul async.js este plasat în , și nu înainte de , atunci diagrama va arăta astfel:

Dar dacă este încă mai convenabil să plasați async.js în cod, atunci ar trebui să modificați ușor conținutul async.js:

$(document).ready(funcție() (
var script = document.createElement("script");
script.src = "dummy_js.js";
document.getElementsByTagName(„cap”) .appendChild(script);
}
);

Deci, problema încărcării asincrone a fost rezolvată, dar problema sincronizării încărcării scripturilor externe și a codului care le folosește rămâne deschisă. Să luăm în considerare acest lucru în practică, conectarea butoanelor rețelelor sociale.

) 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.

Acum o să vă povestesc despre o metodă interesantă care vă va ajuta să vă accelerați site-ul WordPress încărcând scripturi în paralel.

Pentru ce este?

Totul este foarte simplu. Un site web modern este o colecție de o mare varietate de scripturi, etichete, fragmente, stiluri, fonturi și orice altceva. După cum înțelegeți, cu cât sunt mai multe „bunătăți”, cu atât este nevoie de mai mult timp pentru ca site-ul dvs. să se încarce. În ceea ce privește JavaScript, aceasta este o altă chestiune. Ați observat vreodată un astfel de bloc când pagina pare să fi încărcat, dar fila arată că pagina se încărcă în continuare? Acest lucru se întâmplă atunci când un anumit script nu s-a încărcat până la sfârșit. Ar fi bine, uneori pagina este complet inactivă până când se încarcă același script, aparent nu foarte important. Și utilizatorii dvs. pur și simplu nu au suficientă răbdare.

Acest concept este complet opus încărcării sincrone, care este un script obișnuit precum:

Un apel de script asincron arată astfel:

Acum scripturile nu vor obliga utilizatorii să aștepte încărcarea lor completă, totul se va întâmpla în paralel.

Cum să automatizez procesul?

Este clar că dacă conectați manual scripturile și nu sunt multe dintre ele, atunci puteți face acest lucru manual, pur și simplu adăugând atributul corespunzător la codul de apel. Dar cum poți automatiza asta dacă, de exemplu, ai WordPress cu o grămadă de scripturi care, în plus, sunt numite automat?

Găsiți fișierul functions.php deja familiar al temei și introduceți următorul cod acolo (de exemplu, la sfârșit):

// funcția javascript asincronă wcs_defer_javascripts ($url) ( if (FALSE === strpos($url, ".js")) return $url; if (strpos($url, "jquery.js")) return $url; return "$url" async="async"; ) add_filter("clean_url", "wcs_defer_javascripts", 11, 1);

Concluzie

Ce pot sa adaug in concluzie? Este posibil ca acest script să nu fie potrivit pentru toată lumea, pentru că cine știe ce scripturi ai conectat, așa că instalează-l și experimentează. Nu poate exista niciun dezavantaj la un astfel de script, cu excepția poate incompatibilității cu un anumit site din cauza specificului său. Acesta a fost un alt pas mic spre optimizarea mare a site-ului dvs.

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. display = "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.

Asincronia în javascript este o regulă conform căreia blocurile de cod JS sunt procesate de browser în paralel cu încărcarea DOM - i.e. structura paginii web sau după ce DOM-ul s-a încărcat.

Codul JS, după cum știți, este plasat între . În acest caz, codul poate fi conținut atât în ​​CAPUL documentului, cât și în CORP - în orice parte a documentului. JavaScript poate fi încărcat și din alte domenii.

De obicei, JS este plasat la sfârșitul paginii tocmai din motivul că procesarea codului durează un anumit timp - încărcarea paginii este suspendată - DOM-ul nu se poate încărca deoarece așteaptă finalizarea execuției scriptului javascript.

Dacă scriptul este scris cu erori sau este încărcat de pe un server extern care se dovedește a fi indisponibil, pagina nu se va încărca niciodată. Dacă codul JS este pur și simplu prost optimizat și durează mult timp pentru a se executa, pagina se va încărca până la punctul în care scriptul este conectat - apoi încărcarea se va opri până la finalizarea scriptului. Acest lucru poate fi observat de vizitatorul site-ului, mai ales dacă folosește o conexiune lentă la Internet.

Cel mai adesea, un vizitator al unui site a cărui pagină a încetat să se încarce la jumătatea drumului va pleca fără să aștepte ca scriptul să termine de funcționare. Prin urmare, întârzierile sunt extrem de nedorite.

Pentru a remedia această situație, este furnizată opțiunea asincronă, care vă permite să încărcați JS asincron. Structura documentului atunci când se utilizează documentul și toate elementele paginii nu vor aștepta ca scriptul să se finalizeze execuția.

Scriptul este inițiat, pagina va continua să se încarce chiar dacă scriptul nu și-a încheiat activitatea. Este posibil ca unele funcționalități ale paginii să nu funcționeze corect (dacă există erori în javascript), dar în general pagina se încarcă și vizitatorul site-ului poate lucra cu ea.

Este de remarcat faptul că asincronul nu este acceptat de unele versiuni de Internet Explorer, dar deoarece un număr foarte mic de utilizatori îl folosesc, de obicei are sens să ignorăm acest lucru și să folosiți asincronia în javascript.

O alternativă la asincron ar putea fi amânarea. Când utilizați acest atribut, scriptul va fi executat numai după ce DOM-ul este încărcat. Directiva este acceptată de toate browserele; particularitatea sa este că procesează scripturile JS în ordinea în care sunt conectate.

Acest lucru poate fi atât un plus, cât și un minus. Dacă ordinea în care sunt executate scripturile este importantă, defer este cea mai bună soluție.async poate fi dezactivat forțat: script.async=false;

Dezavantajul este că, dacă un script este conectat de la o resursă externă care este inaccesibilă, scripturile rămase nu vor fi procesate. Ei îl vor aștepta pe acesta, indiferent cât de important este în general.

Cele mai bune articole pe această temă