konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Ten dział jest na prawdę martwy :P No to zacznę nową dyskusję chociaż nie na nowy temat. Dopisałem sobie do biblioteczki mechanizm do lazy loading. Wersja pierwsza jest tutaj:

https://github.com/dariuszp/dp/blob/master/js/dp.js (sekcja require)

Mechanizm działa w IE, Operze, FF, Chrome itp. Jak na razie wygląda na to że działa OK. Póki co mam 3 parametry. Ścieżkę do pliku, callback po załadowaniu (opcjonalnie) oraz "useWindowLoad".
Pierwsze 2 opcje są jasne, trzecia wymaga wyjaśnień.

Zauważyłem że nawet dodając pliki za pomocą JavaScript, wydłużam ładowanie się strony (a przynajmniej tak mi się wydaje). Rozwiązaniem jest wykorzystanie eventu "load".

Więc jeżeli "useWindowLoad" mamy ustawiony na false, pliki są dodawane w chwili wykonania skryptu. Jeżeli wykonamy go na dole strony, zwyczajnie zostaną załadowane i wydłużą całkowite ładowanie strony.

Jeżeli "useWindowLoad" ustawimy na true, wszystkie próby załadowania pliku js zostaną wykonane dopiero po załadowaniu się strony. Jeżeli ten parametr będzie miał wartość true w kodzie który wykonuje się po załadowaniu strony, zostanie on kompletnie zignorowany (na podstawie document.readystate).

Używanie tego jest dość proste, wystarczy wykonać taki kod:


dp.require.script('jQuery.js'); // lub
dp.require.script('jQuery.js', function(){ $('body').text('Hello world'); }); // lub dla "onload"
dp.require.script('jQuery.js', function(){ $('body').text('Hello world'); }, true);


przy czym skrypt obecnie nie pozwala na dołączanie tego samego pliku wielokrotnie.

O co chodzi ? Chętnie usłyszę propozycje, pomysły itp jak ów mechanizm ulepszyć. Obecnie mam w planach dodać jeden mechanizm extra. Mianowicie coś takiego:


dp.require.script([ 'jQuery.js', 'tree.jQuery.js', 'plugin.jQuery.js' ], function(){ $('body').text('Hello world'); });


czyli ładowanie zestawu plików, przy czym będą one ładowane w zadanej kolejności a callback odpali się tylko jeżeli wszystkie będą obecne. Myślę też o tym by dodać funkcje timeout. Ale prawdopodobnie żeby nie wydłużać listy parametrów zrobię to w ten sposób że przesunę onload i inne opcje do trzeciego parametru:


dp.require.script(
[ 'jQuery.js', 'tree.jQuery.js', 'plugin.jQuery.js' ],
function(){ $('body').text('Hello world'); },
{
onload: true,
timeout: function(){ console.error('Nie moge zaladowac plikow'); }
delay: 5000
}
);

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

pomysły:
- asynchroniczne wczytywanie,

- możliwość wywołania plików do wczytania przy deklaracji skryptu

<script src="dp.js?foo,bar,yaa"></script>


- możliwość podpinania callbacków do "DOM się wgrał" i "cała strona z obrazkami nawet się wgrała".

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

1. Wczytywanie jest z natury asynchroniczne. To raczej synchroniczność mnie martwi nad czym pracuje jak wspominałem. Głównie po to by można było wczytywać takie zabawki jak jQuery i pluginy od niego zależne.

2. Na dzień dzisiejszy nie mam pojęcia jak odczytać parametry z SRC bez żadnych sztuczek więc tutaj nie pomogę. Nadal trzeba dołączyć skrypt i wykonać odpowiednie instrukcje. Do tego taki zapis nie był by do zaakceptowania z uwagi na to że require to tylko część głównego dp (sam dp z czasem będzie się rozrastał).

3.Zdecydowałem się na onload z uwagi na to że wczytywanie plików js nawet poprzez skrypt opóźnia "onload". Będę to jeszcze szerzej testował żeby być pewnym ale tak mi się wydaje. Dlatego zamiast domReady wybrałem onLoad.
Chyba zrobię tak jak planowałem, ograniczę się d 3 argumentów z czego trzeci to będzie obiekt z konfiguracją. A tam będzie możliwość podpięcia zarówno pod domReady jak i onLoad + parę innych opcji.

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

1. Jest limit wczytywanych jednocześnie JS dodatkowo wczytywanie JS blokuje wczytywanie innych elementów - spróbuj to obejść, są na to sposoby (a przynajmniej tak było jakiś czas temu)

2. Masz wiedzę i umiejętności by to zrobić - po prostu jeszcze nie wpadłeś na to jak :)
Cały kod do takiej czynności to zaledwie kilka (mniej niż 10) linii włącznie z liniami gdzie jest tylko klamra :)

3. W zależności od sytuacji, używam domReady lub onLoad - dla mnie nie są wymienne

(Jak się pewnie domyślasz, mam podobne rozwiązanie)

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

O co chodzi ? Chętnie usłyszę propozycje, pomysły itp jak ów mechanizm ulepszyć.


if(this.loadedScripts[i] == path) { return false; }


Celowo wstrzymujesz callback dla zaciągniętego wcześniej skryptu? Załóżmy, że ktoś używa Twojej biblioteczki do czegoś a'la zarządzanie dependencjami:


dp.require.script('foo.js', bar);

[...]

dp.require.script('foo.js', baz);


Pewnie oczekiwałby, że 'baz' wykona się od razu. Zdziwiłby się :)

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Ad 1. Sprawdzałem zaledwie do 10 plików. Rzucę okiem jak to wygląda przy większej ilości. W NodeGame (obecnej wersji) wykorzystuje znacznie więcej plików ale są wczytywane na żądanie w większości. Opóźnianie ładowania strony mnie nie obchodzi zbytnio. Dlatego można oddelegować niektóre pliki do onLoad lub po poprawkach również do domReady.

Ad 2. Najprostsza metoda jaką znam to zapisanie gdzieś wewnątrz nazwę pliku i wg niego wyłapać odpowiedni <script> tag i parsować src. Wyjątek stanowi Firefox który ma document.currentScript() dostępne ale raz że jest to niestandardowe a dwa - niedostępne w innych przeglądarkach. A nie chcę fixować nazwy pliku bo ktoś sobie ją zmieni z jakiegoś powodu i będzie się zastanawiał czemu przestało działać...

3. DomReady i onLoad oczywiście że nie są zamienne. Po prostu na dzień dzisiejszy obsłużyłem tylko onLoad z uwagi na to że chciałem by ładowanie skryptów opóźniało lub nie ładowanie całej strony. Dodatkowe opcje pojawią się jak wprowadzę zmiany o których mówiłem.Dariusz Półtorak edytował(a) ten post dnia 11.10.12 o godzinie 08:38

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Rafał Krupiński:
O co chodzi ? Chętnie usłyszę propozycje, pomysły itp jak ów mechanizm ulepszyć.


if(this.loadedScripts[i] == path) { return false; }


Celowo wstrzymujesz callback dla zaciągniętego wcześniej skryptu? Załóżmy, że ktoś używa Twojej biblioteczki do czegoś a'la zarządzanie dependencjami:


dp.require.script('foo.js', bar);

[...]

dp.require.script('foo.js', baz);


Pewnie oczekiwałby, że 'baz' wykona się od razu. Zdziwiłby się :)

Widzę skąd przyszedłeś. Fakt, mogę przed wyjściem wywołać callback. Dzięki.

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Nie rozumiem w jakim celu używać czegoś takiego. Używam requireJS, a jak chce żeby strona się szybciej ładowała to kompiluje wszystkie pliki js do jednego. Czas ładowania na dobrych łączach to zazwyczaj ping(zapytanie->odpowiedź) więc jak cały kod jest w jednym pliku to ładuje się najszybciej.

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Michał Łaszczewski:
Nie rozumiem w jakim celu używać czegoś takiego. Używam requireJS, a jak chce żeby strona się szybciej ładowała to kompiluje wszystkie pliki js do jednego. Czas ładowania na dobrych łączach to zazwyczaj ping(zapytanie->odpowiedź) więc jak cały kod jest w jednym pliku to ładuje się najszybciej.

Piszę coś takiego bo chcę i mam na to czas :) Niektórzy korzystają z narzędzi - ja lubię wiedzieć jak działają.

Całości nie załaduję do jednego JS bo jest tego zwyczajnie za dużo. Jak skończę pracę z grą nad którą pracuję, ilość plików .js będzie liczona w dziesiątkach a później pewnie i w setkach. I raczej wolę ładować tylko to co na prawdę potrzebuję.

Dzięki temu mam bardzo krótki czas ładowania witryny kosztem tego że ktoś od czasu do czasu zobaczy przez chwilkę pasek "Ładuję..." gdzieś u góry.
Grzegorz K.

Grzegorz K. Angular, JavaScript,
Frontend, UI

Temat: Lazy loading w JavaScript - pomysły ?

Polecam jeszcze zapoznać się z Closure Compiler i jego API.

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Ciekawe czy twórcom Prototype i Mootoolsa radzono "zapoznać się" z jQuery. To samo z dziesiątkami frameworków mvc, które są ostatnio takie modne. Chopak ma czas i ochotę to niech pisze. Jaki jest cel strzelania do siebie w tym wątku nazwami bibliotek?

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Rafał Krupiński:
Ciekawe czy twórcom Prototype i Mootoolsa radzono "zapoznać się" z jQuery. To samo z dziesiątkami frameworków mvc, które są ostatnio takie modne. Chopak ma czas i ochotę to niech pisze. Jaki jest cel strzelania do siebie w tym wątku nazwami bibliotek?

Zaszkodzić też nie zaszkodzi...

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Rafał Krupiński:
Ciekawe czy twórcom Prototype i Mootoolsa radzono "zapoznać się" z jQuery. To samo z dziesiątkami frameworków mvc, które są ostatnio takie modne. Chopak ma czas i ochotę to niech pisze. Jaki jest cel strzelania do siebie w tym wątku nazwami bibliotek?
Zdziwił byś się, ale kilka rzeczy w prototype zostało napisane przez autorów jQuery specjalnie dla niego i odwrotnie.
Jakie konkretnie - nie pamiętam.

Jako ciekawostka - kilka rzeczy z prototype przeszło do ECMAScript - np. bind();

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Następnym razem najistotniejszą część wypowiedzi napiszę boldem, żeby ograniczyć swobodną interpretację :)
Grzegorz K.

Grzegorz K. Angular, JavaScript,
Frontend, UI

Temat: Lazy loading w JavaScript - pomysły ?

Rafał Krupiński:
Ciekawe czy twórcom Prototype i Mootoolsa radzono "zapoznać się" z jQuery. To samo z dziesiątkami frameworków mvc, które są ostatnio takie modne. Chopak ma czas i ochotę to niech pisze. Jaki jest cel strzelania do siebie w tym wątku nazwami bibliotek?

Czemu się unosisz ? Czy ja powiedziałem, że pisane własnych rozwiązań jest złe ? Nie ma się co nadymać.

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Cel jest :) Lubię pożyczać z rozwiązań które mi wpadną w oko. Albo pomysł albo implementację. Wprowadziłem odrobinę zmian. Na razie nie wrzuciłem ładowania poprzez podanie tablicy ale zrobiłem troszkę poprawek które mi wyszły podczas implementowania dp.require do gierki.

Więc na obecną chwilę (jeszcze nie przetestowane) wygląda to tak:

1. Jeżeli wszystkie pliki .js mają jeden katalog, możemy użyć:
dp.require.setScriptPath('path/to/scripts/');

co spowoduje że wystarczy podać samą nazwę pliku. Czasami bywa że mamy jakiś wyjątek który trzeba załadować z zupełnie innej lokacji więc na takie wypadki dałem parametr "ignoreScriptPath". Przykład:
dp.require.script('lib/jquery/plugins/tree.jquery.js', false, { ignoreScriptPath: true });


Jak widać, trzeci parametr który był od zdarzenia onLoad (ładowanie skryptów po załadowaniu całej strony) zamieniłem na obiekt JSON.

2. Callback zmienił zachowanie wg tego o czym wspomnieliście wcześniej. Tzn coś takiego:

dp.require.script('dp.bezier.js', function(){ alert('Bezier is loaded'); });
dp.require.script('dp.bezier.js', function(){ alert('Bezier is loaded'); });

plik dołączy tylko raz ale callback wykona się za każdym razem.

3. Jako że słusznie ktoś zauważył, zignorowałem event DOMContentLoaded, dorobiłem poprawkę:

dp.require.script('dp.bezier.js', false, { ready: true }); // DOMContentLoaded
dp.require.script('dp.bezier.js', false, { load: true }); // load

przy czym zrobienie czegoś takiego:

dp.require.script('dp.bezier.js', false, {
ready: true,
load: true
});

skończy się załadowaniem pliku przy DOMContentLoaded a load zostanie kompletnie zignorowane.

To by było tymczasowo na tyle. Muszę się zająć resztą elementów. Wieczorem jeszcze to postaram się przetestować. Jak nic nie spartoliłem to na pewno będzie to działać pod każdą współczesną przeglądarką. Jedyna zmiana jaką planuję na obecną chwilę to dorzucenie ładowanie plików poprzez wrzucenie tablicy czyli:
dp.require.script(['dp.bezier.js', 'dp.anim.js', 'dp.sprite.js'], function(){ alert('Bezier is loaded'); });

ale to akurat już drobna poprawka.

Następne 2 biblioteczki w planach to obsługa klawiatury i sprajtów. Wstępna implementacja została użyta w NodeGame.
http://nodegame.dariuszp.pl/js/Controls.js
http://nodegame.dariuszp.pl/js/Sprite.js

Obecna implementacja pozostawia deczko do życzenia ale jak już mam to przerabiać to wolę to zrobić raz a porządnie i wrzucić w dp.*.

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

trochę więcej bibliotek tego typu do inspiracji:
http://blog.kamilbrenk.pl/sposoby-wczytywania-javascript/
(to było 1,5 roku temu, dzisiaj pewnie dużo więcej tego)

ja osobiście robię mix dwóch rozwiązań:

1) po stronie serwera łącze kilka wspólnych plików wykorzystywanych na każdej podstronie - wszystko minifikuje, gzipuje, etc

<script src="scripts.js?files=fw.js,lib.js,plugin1.js" defer></script>


oczywiście scripts.js jest przemielany przez mod_rewrite

2) przy większych stronach gdzie jest dużo javascriptu (i zależności) wczytuję z LABjs, w łatwiejszych z jQuery.getScript(), np.

$(document).on('scroll', function() {
var $this = $(this);
if ($this.scrollTop() > 500) {
$.getScript('social-widgets.js');
$this.off('scroll');
}
});
Kamil Brenk edytował(a) ten post dnia 14.10.12 o godzinie 14:11

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

@Darek:
Chodzi o coś w stylu dość chyba popularnego require.js ?Piotr L. edytował(a) ten post dnia 22.10.12 o godzinie 10:54

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Piotr L.:
@Darek:
Chodzi o coś w stylu dość chyba popularnego require.js ?

Owszem, różnica polega na tym że planuje troszkę poszaleć w tym wypadku. Moduł require to jest tylko część całego dp. Plan jest taki żeby w przyszłości require() ściśle współpracowało z całym dp.

konto usunięte

Temat: Lazy loading w JavaScript - pomysły ?

Dariusz Półtorak:
Piotr L.:
@Darek:
Chodzi o coś w stylu dość chyba popularnego require.js ?

Owszem, różnica polega na tym że planuje troszkę poszaleć w tym wypadku. Moduł require to jest tylko część całego dp. Plan jest taki żeby w przyszłości require() ściśle współpracowało z całym dp.

Ktoś tu ma za dużo wolnego czasu :D

Następna dyskusja:

JavaScript a programowanie ...




Wyślij zaproszenie do