Szinkron dinamikus script betöltés
Helló guruk!
Egy weboldalra szeretnék JavaScript-ből futásidőben JavaScript fájlokat betölteni (nem AJAX-al) úgy, hogy az oldal, vagy éppen az aktuálisan futó JavaScript kód kiértékelése megálljon addig míg a script be nem töltődött, és az abban deklarált változók, függvények elérhetővé nem válnak!
Valami olyasmit szeretnék hogy:Aki tud nem ajax-os megoldást és segíit annak köszönöm!
Közben ki gondoltam, hogy a require függvényben egy while ciklus pöröghetne addig amíg a typeof module értéke undefined vagy le nem jár egy timeout. Csak ez eléggé kontár munka lenne szerintem.
■ Egy weboldalra szeretnék JavaScript-ből futásidőben JavaScript fájlokat betölteni (nem AJAX-al) úgy, hogy az oldal, vagy éppen az aktuálisan futó JavaScript kód kiértékelése megálljon addig míg a script be nem töltődött, és az abban deklarált változók, függvények elérhetővé nem válnak!
Valami olyasmit szeretnék hogy:
alert(typeof module); // undefined
require('module'); // szinkron betöltés
alert(typeof module); // object
Közben ki gondoltam, hogy a require függvényben egy while ciklus pöröghetne addig amíg a typeof module értéke undefined vagy le nem jár egy timeout. Csak ez eléggé kontár munka lenne szerintem.
mootools assets
http://weblabor.hu/blog/20110209/budapestjs-februar
A működéséről nem igen tudok mit mondani, de, ha mást nem, a google tud segíteni:
mootools assets
Na igen ám, csak a bonyolult
Injektált script src-t
Hát az injektálás nem nyert, idő kell, amíg frissül a dom fa, és végrehajtódik a script.
Aszinkron módon könnyebben megoldható, és nem fagy be a böngésző a betöltés közben.
Betöltés
Mivel JavaScript egy szálon fut, ezért amíg a
while
ciklusod pörög, addig semmi más nem történik. Azaz a kód nem inicializálódik stb. Ez nem megoldás.Mutatok pár megoldást aszinkron kód betöltésre, és hogy azokat hogyan kell használni:
load.js:
load.js
-
Mi a probléma?
Ezen kívül természetesen vannak más különbségek is. Például az oldal betöltődése után a szkriptek már mindenképpen aszinkron töltődnek be, akkor is ha a script elemeket te rakod be a kódba. Hozzá kell szokni, hogy a JavaScript így működik. És előbb utóbb örülni fogsz, hogy így működik, és párhuzamosan tud betölteni több fájlt is.
szinkron betöltés
Aszinkron
Amint látható a szkriptek párhuzamosan töltődnek le, de egymás után futnak. De nem szinkron módon, ugyanis akkor minden loop sor után egy load sor lenne.
A szinkron... :)
Újra
Ma újra neki ültem és AXAJ-al próbáltam meg megoldani az esetet, de a IE valamit nem kamáz!!! Aszt dobja, hogy: A művelet nem hajtható végre a következő hiba miatt: c00c023f. Ez mit jelent? Egy burkoló objektumot hoztam létre az XHR objektumnak és azon keresztül intézem a kérést:
Valószínűleg az a gond, hogy
Szerintem olyan problémára
A HTTP-ben a legdrágább művelet a fájlkérések kiszolgálása, ami az esetek többségében úgy történik, hogy (a Firebug alapján)
- elindítjuk a kérést a szerver felé a megfelelő HTTP fejlécekkel
- a szerver leellenőrzi a fejlécek alapján, hogy volt-e már nálunk a fájl
- ha nem volt, akkor 200-as HTTP kóddal visszaküldi a fájl tartalmát
- ha volt, akkor 304-es kódot küld, azaz a fájl nem változott
A Weblaboron nyomtam pár frissítést, a műveletek átlagos válaszideje:
- kérés indítása: 16ms
- a kérés feldolgozása a szerveren statikus fájlok esetén: 30ms
- amennyiben még nem volt lenn a tartalom, egy kilobájtot nagyjából egy ezredmásodperc alatt töltök le (bár igazából ez nagyobb fájl [150k] esetén igaz, kisebb fájlok jóval lassabban jönnek le).
Ebből a kérés nettó ideje 16+30 = 46 ms, tehát minden egyes plusz fájlkérés felér 46 kilobájtnyi adat letöltésével. Bizonyos böngészők csak akkor kérik le a következő betöltendő scriptet, amennyiben az előzővel már végeztek, ugyanis a feldolgozásuk nem párhuzamusan történik.
A fentiekből következik, hogy nem éri meg az egyes scripteket külön fájlba tenni, hanem jóval célszerűbb őket egy fájlba pakolni, mert jóval gyorsabb lesz a feldolgozásuk.
Emellett Apache alatt érdemes használni a mod_expires kiterjesztést, a nem változó fájlokat berakni egy külön könyvtárba, és például a következő sorokat betenni egy .htaccess-be vagy a konfigurációs fájlba:
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
Ez azt csinálja, hogy egy hónapig a böngésző még kérést sem indít, hanem mindenképp a gyorsítótárból olvas.
Egy példa még: egy 400k-s js fájl (ext js keretrendszer) feldolgozása a böngészőben letöltés után kb. 300ms egy 1600 MHz-es Athlonon.
Disable Cache
Ilyesmi méréseket én is végeztem régebben, tény hogy igazad van sokkal rontja a sebességet ez a ötlet amit ki gondoltam, de egy olyan rendszert szeretnék készíteni ami egyes script-ek függőségét ellenőrzi, és a nagyobb class-okat külön fájlban kezelni.
Valóban a onreadystataechange nem fut le szinkronban, ezt most olvastam én is, ez a újabb böngészőkön nem is baj, csak a régieken, mint a IE 7-8 mert ott arra lettem figyelmes hogy ugyan úgy meghívja, ami ugye a burkoló onreadystatechange függvényét hívja meg, és ezért add hibát mikor le akarsz kérdezni valamit a natív XHR-től a burkolón keresztül, ez persze csak IE-ben van így, ahogy érzékeltem, szóval átírtam:
Itt akad egy újjab probléma:
- IE 9 - függvényen belül elérem a karvaly-t,
globális scope-ból meg nem,
- IE 8 - ugyan az.
- IE 7 - ugyan az.
- FF 3.6 - ugyan az.
2. ha azt írom window.eval(xhr._xmlHttpRequest.responseText):
- IE 9 - elérhető a globális névtérből is.
- IE 8 - nem érhető el csak függvényen belül.
- IE 7 - it is csak a függvényen belül.
- FF 3.6 - elérhető a globális névtérből is.
3. az eval.call(window, xhr._xmlHttpRequest.responseText) ugyan úgy működött mint a 2. forma.
Nos azt nem tudtam, hogy az eval ilyen nehéz eset. Meglehet azt oldani hogy ha egy függvényen belül egy ilyen kód eval-ozva:
A végéhez: marad az, hogy
Egyébként azt hiszem, értem, hogy mit akarsz csinálni, de nem sok értelmét látom. A Javascript nem PHP, meg nem Java, ezért nem kéne ráerőltetni az azokban megszokott programozási stílust, csak azért, mert ez mostanában annyira divatos.
Hali!