Google chce przyśpieszyć internet

Posted by Piotr Sarnacki Fri, 26 Jun 2009 19:11:00 GMT

Nie od dziś wiadomo, że prędkość ładowania strony ma wpływ na akcje użytkowników. Badania prowadzone miedzy innymi przez Yahoo, Google i Amazon wskazały, że zmniejszenie czasu ładowania strony ma bezpośredni wpływ na ilość akcji wykonanych przez użytkowników (wyszukiwań lub w wypadku Amazona zakupionych przedmiotów).

Google odpalił niedawno stronę, na której zachęca i uczy jak przyśpieszyć działanie naszych stron i serwisów

Dodatkowo Google wypuścił narzędzie Page Speed, które jest rozszerzeniem do Firebuga i podobnie jak YSlow pomaga zbadać stronę pod kątem prędkości ładowania się poszczególnych komponentów. Oba te narzędzia dostarczają od razu praktycznych porad i opisów pomagających zrozumieć jak zoptymalizować stronę. Dla mnie są to niezbędne narzędzia przy pracy z serwisami internetowymi. Do tej pory używałem głównie YSlow, ale przy następnych optymalizacjach na pewno skorzystam z Page Speed.

Jeżeli jeszcze nie znacie tych narzędzi, gorąco polecam zapoznanie się z nimi.

Posted in ,  | Tags , , ,  | no comments | no trackbacks

YUI 3 beta

Posted by Piotr Sarnacki Thu, 25 Jun 2009 14:46:00 GMT

We wczorajszym poście na blogu YUI ogłoszono wersję beta YUI3.

YUI (Yahoo User Interface) jest frameworkiem javascript rozwijanym przez YAHOO, który dostarcza nie tylko niskopoziomowe funkcje pomagające przy pisaniu kodu javascript, ale też zestaw komponentów (takich jak różnego rodzaju okienka dialog, color picker, czy nawet bardzo dobry edytor WYSIWYG). YUI jest dojrzałą biblioteką używaną na stronach YAHOO, co zapewnia bardzo dobrą jakość. Sam team YUI to jedni z najlepszych specjalistów od frontendu – zachęcam do czytania wpisów na ich blogu

To co najbardziej przekonywało mnie do używania YUI, to fakt dostarczenia całego zestawu narzędzi do budowania interfejsów użytkownika w javascripcie. W przypadku np. jQuery lekko może denerwować bardzo duże rozstrzelenie poszczególnych bibliotek. Są oczywiście takie projekty jak jqueryUI, ale większość pluginów trzeba ściągnąć z innych źródeł, a ich kod często pozostawia wiele do życzenia. W przypadku YUI mamy zwarty zestaw komponentów, łatwy do rozszerzania i rozwijany przez specjalistów w celu wykorzystania na stronach odwiedzanych codziennie przez miliony internautów.

Z drugiej strony to co było banalne w jQuery często było ciężkie do uzyskania w YUI. A jak wszyscy wiedzą jeżeli chodzi o zabawę z DOM, animacjami i ajaxem z jQuery jest ciężko wygrać. Dlatego gdy używałem komponentów YUI w jednym z projektów, w którym przy okazji używałem jQuery, to do manipulacji elementów DOM używałem jQuery, a z YUI wybierałem tylko komponenty.

Wersja trzecia YUI może to zmienić. Zespół z Yahoo postanowił przepisać bibliotekę zupełnie od nowa z naciskiem na lekkość i szybkość. Najważniejsze zmiany

  • zmienione API do manipulacji DOM, czyli “jQueryzacja” – łańcuchy komend, proste funkcje typu addClass, remove, append itp.
  • ułatwiona praca z eventami
  • modularyzacja biblioteki

Najbardziej obiecująco wygląda ostatni punkt. Do tej pory poszczególne komponenty nie były modularne, co prowadziło do powtarzającego się kodu w różnych komponentach. Dodatkowo jeżeli ktoś chciał stworzyć Tooltip dziedziczący po Overlay, to musiał wykorzystać wszystkie elementy, które Overlay zawiera. Jest to oczywiście zbędne wykorzystywanie pamięci i Tooltip, który jest obecnie dostępny w YUI właśnie z tego powodu nie jest najlepszą możliwą implementacją.

W YUI3 poszczególne funkcjonalności są rozbite do modułów. Dlatego, żeby zbudować wspomniany wyżej tooltip nie trzeba dziedziczyć po Overlay, tylko zmiksować (czy to nie brzmi znajomo?) na przykład: moduł pozycjonowania i moduł animacji. Dodatkowo można wmiksować poszczególne moduły nie tylko do klas, ale także instancji poszczególnych obiektów. Jeżeli będzie to rzeczywiście działało tak fajnie jak mówią programiści z YUI (polecam obejrzeć video ze zlinkowanego wcześniej posta), to YUI3 na pewno zagości w moich projektach.

To co najbardziej denerwuje mnie obecnie w różnego rodzaju bibliotekach do jQuery czy prototype, to całkowite oderwanie poszczególnych bibliotek od siebie. Używam na przykład jqueryUI i żeby użyć tooltipa, muszę ściągnąć zupełnie inną bibliotekę, która jest napisana zupełnie inaczej i nie dzieli żadnego kodu z innymi bibliotekami (tutaj też wychodzi swoboda javascriptu, jeżeli ktoś próbował porównywać implementacje różnych bibliotek, to na pewno wie na ile różnych sposobów można zaimplementować te same funkcje). Jeszcze gorzej jest gdy trzeba napisać własne komponenty – lekkość jQuery i brak oficjalnych bibliotek pomagających w takich wypadkach jest dość dużą przeszkodą.

W tym momencie YUI team zachęca programistów do używania YUI3 w nowych projektach, szczególnie tych, które nie planują wykorzystywać dużej ilości widgetów obecnych w YUI2. Oficjalna wersja ma być dostępna w 3 kwartale tego roku. Rozwój można biblioteki śledzić tutaj

Posted in  | Tags , , , ,  | no comments | no trackbacks

Jak użyć jQuery na stronie bez jQuery?

Posted by Piotr Sarnacki Thu, 06 Nov 2008 22:07:00 GMT

Czasami gdy chodzę po sieci chciałbym mieć możliwość wykonania jakiegoś kodu na stronie, na której aktualnie się znajduję. Do tego wystarczy konsola javascript w firebugu. Niestety można wtedy używać jedynie bibliotek, które są dołączone do strony. Co jeżeli nie ma tam jakiegoś prototype’a czy innego jquery? Najczęściej potrzebne mi są selectory i traversing – ostatnio na przykład chciałem na szybko policzyć jakieś dane na podstawie sporej tabeli na stronie internetowej. I co wtedy? Bawić się w getElementById i inne tego typu historie? Niefajne to, szczególnie jeżeli strona to jedna wielka tabelka bez prawie żadnych id, klas czy innych elementów pomocnych w wybraniu upragnionego kawałka.

Trochę ponad rok temu z kilkoma ludźmi pisałem startupa (po 2-3 miesiącach wszystko się rozpadło, ale było ciekawie), w którym duży nacisk był na dostarczenie prostych narzędzi (coś w rodzaju małego toolbara) do dowolnej strony internetowej. Oczywiście nie można zmusić właścicieli stron do wklejenia czegokolwiek na swoją stronę, ale można użyć zakładek przeglądarki, żeby coś takiego udostępnić.

Przeglądarki mogą obsługiwać adresy w postaci “javascript: alert(‘Why are you so serious?’);”. Wystarczy wkleić coś takiego w pasku adresu – oczywiście wyskoczy alert. A skoro użytkownik może dodać zakładkę do dowolnego adresu, to adres tej postaci też przejdzie.

Cały myk polegał więc na tym, żeby w kodzie javascript, który był dodawany do zakładek dołączyć jakąś bibliotekę (wtedy akurat używałem jQuery) i samą aplikację, która wyświetlała toolbar z różnymi opcjami.

Używając tej techniki można zrobić całkiem fajne rzeczy, ale w tym momencie ograniczę się do pokazania jak załączyć samą bibliotekę jQuery.

Kod wygląda mniej więcej tak:

(function( {
  var s = document.createElement('script');
  s.src="http://drogomir.com/jquery.js";
  document.body.appendChild(s);
})()

Można jeszcze dodatkowo zrobić drugi skrypt, który dołączymy po jQuery, a w nim dodać na przykład jQuery.noConflict, albo jakiś inny kod wykonany po załączeniu jQuery.

Dodajcie do zakładek tego linka i po wybraniu go na jakiekolwiek stronie jQuery zostanie dodane do skryptów na stronie.

Mam nadzieję, że komuś się przyda. Próbowałem znaleźć kod, o którym pisałem powyżej, który wyświetlał warstwę z toolboxem, z różnymi fajnymi opcjami, ale cholera chyba zniknął w pomroce dziejów. Będę musiał bardziej dbać o kod starych projektów, fajnie byłoby się teraz przyjrzeć pracy sprzed roku ;-)

Posted in  | Tags  | no comments | no trackbacks

Po dłuższej przerwie

Posted by Piotr Sarnacki Tue, 30 Sep 2008 14:38:00 GMT

Przez jakiś czas nie pisałem nic na blogu. Długo zbierałem się do napisania czegokolwiek, od dawien dawna miałem przetłumaczyć wpisy na moim angielskojęzycznym blogusiu. Tak bardzo mi się nie chciało, że jak tylko siadałem do kompa z zamiarem przetłumaczenia czy napisania czegoś podobnego coś mnie odrzucało.

Dlatego, żeby więcej się nie męczyć podsumuję ten temat i podam linki – większość ludzi, którzy tutaj trafią i tak na pewno zna angielski.

Napisałem apache upload progress module do apacha. Moduł, dzięki któremu można pobrać dane o wysyłanych plikach. Format odpowiedzi oparłem o moduły tego typu dla nginxa i lighttpd dlatego jeżeli wcześniej ktoś używał któregoś z nich, przesiadka będzie całkowicie bezbolesna. Sam używałem wcześniej nginx upload progress (głównie dlatego napisałem moduł do apacha) i po przerzuceniu aplikacji na apacha z nowym modułem nie trzea było zmieniać ani jednej linijki. Na angielskim blogu zamieściłem opis instalacji i konfiguracji modułu.

Żeby można było w miarę łatwo używać modułu napisałem także pluginy do “prototype’a”http://github.com/drogus/prototype-upload-progress/tree/master i jquery, które obsługują pasek postępu. Przykłady są w repozytoriach, umieściłem je także na serwerze dla obczajenia w akcji. Popełniłem także tekst o tym jak hackowałem plugin, żeby działał w safari – safari w tym momencie nie było wcale lepsze od IE… nawet powiedziałbym, że gorsze. Swoją drogą plugin nie działa w najnowszej operze (działał w 9.5 zdaje się), więc jeżeli ktoś ma chwile czasu i mógłby sprawdzić dlaczego i co można zrobić, żeby działał, to może wnieść swój wkład w rozwój (dodam, że nie jest to ta sama kwestia co dla safari, bo to już sprawdziłem) – nie sądzę żebym miał teraz czas sam na tym siedzieć.

Dodatkowo napisałem jeszcze tekst o tym jak można fajnie uatrakcyjnić aplikację używając jQuery. Część pierwsza. Część druga będzie jak będę miał więcej czasu, czyli pewnie niezbyt szybko.

Pozdrowienia ze słonecznego Wrocławia, gdzie mam zamiar mieszkać przez najbliższy rok (miła odmiana od Pruszkowa :).

Posted in , ,  | Tags , , , ,  | no comments | no trackbacks

Livequery

Posted by Piotr Sarnacki Mon, 03 Mar 2008 20:41:00 GMT

Pisałem jakiś czas temu o nieinwazyjnym javascripcie w ruby on rails. Zapomniałem wtedy napisać o pluginie do jQuery, który ułatwia pracę stosując nieinwazyjny javascript.

Livequery ułatwia znacznie korzystanie ze zdarzeń. Często podczas manipulowania DOM tworzy się i/lub usuwa nowe elementy. Co gdy przypiszemy do kilku elementów jakieś zdarzenie po czym dodamy nowe elementy?

Zmontowałem prosty przykład, na którym można to sprawdzić. Do pierwszej listy linki dodawane są bez żadnych dodatków. Zwykłe:


  $('<li><a href="#">Link</a></li>').appendTo($('.without ul'));

Dlatego funkcja clicked uruchomi się tylko dla 2 pierwszych linków.

W drugim przypadku dodałem bind dla nowo stworzonego elementu:

  $('<li><a href="#">Link</a></li>').
          appendTo($('.with ul')).
          bind('click', clicked);

Zdarzenie jest więc przypisywane również dla nowych linków.

Jednak gdy ilość różnych zdarzeń zaczyna się niepokojąco powiększać, a cały interfejs strony zmienia się przy każdym prawie kliknięciu często można zapomnieć o przypisaniu zdarzeń. Nawet jeżeli ktoś nie jest zapominalski, to zapewne jest leniwy (ponoć dobrego programistę cechuje lenistwo). Na ratunek przychodzi Livequery, plugin, który sam dba o przypisywanie lub usuwanie zdarzeń w razie manipulacji DOM.

Drugi przykład# wykorzystuje już LiveQuery – jak można łatwo zauważyć nie trzeba już dopisywać żadnych dodatkowych funkcji.

I jedno zmartwienie przy pisaniu mniej ;-)

Posted in  | Tags , , ,  | no comments | 1 trackback

jQuery.noConflict i $ - fajny trick

Posted by Piotr Sarnacki Tue, 18 Sep 2007 11:46:00 GMT

Dzisiaj króciutko: fajny trick podpatrzony gdzieś w skryptach jQuery.

Pisząc skrypty najlepiej robić to tak, żeby można było je uruchamiać na każdej stronie. Nie mogą się gryźć z innymi bibliotekami. Dlatego jQuery wprowadziło funkcję:

jQuery.noConflict();

Po jej wywołaniu kontrola $ jest zwracana bibliotece, która wcześniej go używała. Dzięki temu można używać jQuery w połączeniu z innymi bibliotekami, a nawet ze starszymi wersjami jQuery (bardzo przydatne przy pisaniu widgetów). Minusem jest konieczność pisania jQuery zamiast $. Można oczywiście przypisać jQuery na krótszą zmienną, ale wtedy ciężej jest wklejać kod napisany przez innych.

Aby temu zaradzić wystarczy użyć takiej konstrukcji:


(function($) {
  //tutaj można używać $ bez strachu o konflikt
})(jQuery);

Stworzona zostaje funkcja, która jest od razu wywołana z podanym argumentem. I voilla :)

Posted in  | Tags , ,  | 2 comments | no trackbacks

Generowanie HTMLa w javacripcie

Posted by Piotr Sarnacki Sun, 16 Sep 2007 10:43:00 GMT

Czasami bywa tak, że jakaś wyższa siła każe nam generować duże ilości HTMLa. Wygląda to dość nieładnie:


var el = document.createElement("div");
el.setAttribute('id','elementId');
el.setAttribute('class','someClass');
document.body.appendChild(el);

Stworzony został jeden element. A jakby elementów było 10? I każdy miałby po parę atrybutów? Masakra.

Na szczęście powstają różnego rodzaju DOM buildery. Od wersji 1.5.1 użytkownicy prototype’a będą mogli cieszyć się jego dobrodziejstwami. Jeżeli chodzi o jQuery to znalazłem dość fajną implementację. W komentarzach jest też inna wersja, która mi osobiście bardziej odpowiada.


$.create(
   'table', { 'class':"MyTable" }, [
      'tbody', {}, [
         'tr', {}, [
            'td', { 'class':"MyTableCol1" }, [ "howdy" ],
            'td', { 'class':"MyTableCol2" }, [
               "Link:", 'a', { 'class':"MyLink", 'href':"http://www.example.com" }, ["example.com"] ] ] ] ]
).appendTo(document.body);

Całkiem ładnie to wygląda. używając createElement wyszłoby pewnie ze 20 linijek.

Są oczywiście inne implementacje, które nie wymagają jQuery czy prototype’a, przydatne szczególnie w przypadku różnego rodzaju widgetów. Odsyłam do wujka G ;)

Tak jak obiecałem, wrzucam ostateczne wersje zaproponowanych w powyższym linku funkcji. Teraz powinno działać bez zarzutu.


jQuery.create = function() {
  var ret = [], a = arguments, i, e;
  a = a[0].constructor == Array ? a[0] : a;
  for(i=0; i<a.length; i++) {
    if(a[i+1] && a[i+1].constructor == Object) { // item is element if attributes follow
      var tag = a[i];
      attrs = a[++i];
      if(jQuery.browser.msie && (attrs.name || attrs.checked)) {
        tag = '<' + tag + ' ' + (attrs.name ? 'name="' + attrs.name + '" ' : '')+ (attrs.checked ? "checked" : " ") +'>';
        if(attrs.name) delete attrs.name;
        if(attrs.checked) delete attrs.checked;
      }
      e = document.createElement(tag);
      jQuery(e).attr(attrs); // apply attributes
      if(a[i+1] && a[i+1].constructor == Array) jQuery(e).append(jQuery.create(a[++i])); // optional children
      ret.push(e);
    } else { // item is just a text node
      ret.push(document.createTextNode(a[i]));
    }
  }
  return ret;
};

jQuery.tpl = function(json, tpl) {
  var ret = [];
  jQuery.each(json.constructor == Array ? json : [json], function() {
    var o = jQuery.create(tpl.apply(this));
    for(var i=0;i<o.length;i++) ret.push(o[i]);
  });
  return ret;
};

Posted in  | Tags , , , ,  | no comments | no trackbacks

jQuery vs Prototype

Posted by Piotr Sarnacki Tue, 04 Sep 2007 12:10:00 GMT

Kilka dni temu wrzuciłem notkę promującą jQuery. Często podczas porównywania narzędzi przeżywam pewien rodzaj euforii, która nie pozwala mi na obiektywne rozpatrzenie wszystkich za i przeciw. Przez chwilę wydaje mi się, że znalazłem narzędzie idealne (co oczywiście jest okropnym nadużyciem. jak ogólnie wiadomo idealny jest tylko polski rząd i jego sukcesy na przestrzeni ostatnich 2 lat – widziałem w reklamach).

W każdym razie ochłonąłem trochę i ze spokojem buddyjskiego mnicha (mówiłem już, że jestem oazą spokoju?) przetrząsnąłem cały internet w poszukiwaniu informacji. Próbowałem nawet wywołać flamewara na google groups. I biednie jest. Niewiele znalazłem. Wszędzie jakieś artykuły, których sens jest mniej więcej taki: “Przez długi czas używałem prototype(jQuery) i stwierdziłem, że muszę dać jQuery(prototype) szansę. jQuery jest prototype killerem!”. Nie licząc fajnego artykułu na agile ajax. Stety albo niestety autor nie do końca chce wyjawić, które podejście jest dla niego lepsze. Aczkolwiek pewną wskazówką może być przesiadka na jQuery, a nie odwrotnie.

No i krytyka modelu dziedziczenia zastosowanego w prototype.

Pozwoliłem sobie zrobić własne porównanie. Mam nadzieję, że chociaż w małym procencie obiektywne. ;-)

Manipulacja DOM i CSS

Na tym polu zdecydowanie wygrywa jQuery. Twórca zapewnił coś, co nazywa się “chainability”. Metody manipulujące elementami HTMLa można wywoływać w łańcuchach, na przykład jQuery('#some').show('slow').css('background-color', 'white').add('<p>Dodatkowy paragraf!</p>').

Jeżeli chodzi o same selektory, to od wersji 1.5.0 prototype ma obsługę selektorów CSS, więc nie ma już problemu z wybieraniem elementów w bardzo fikuśnych konfiguracjach ;-)

jQuery ma jeszcze jedną ciekawą właściwość. Wybrane elementy zawsze zwracane są w tablicy dzięki czemu biblioteka sama zadba o przeiterowanie po kolekcji i zaaplikowaniu metody do każdego jej elementu. Na przykład zamiast napisać (prototype):


$$('a').each(function(v, i) { Event.observe(v, 'click', fn); });
Możemy użyć:

jQuery('a').click(fn);

Wydajność

Na tym polu prototype mocno dawał w kość jQuery, ale sytuacja się poprawiła. W poprzednim poście zamieściłem 2 screeny, na których można zauważyć, że obecnie jQuery jest jakieś 2 razy wolniejsza (oczywiście jeżeli chodzi o same selektory). Dla innych metod podejrzewam, że będzie podobnie (dla each i map na pewno – jeżeli ktoś się bardzo nudzi może się pobawić i zrobić więcej benchmarków).

Ale statystyki na szczęście nie zawsze oddają to, co dzieje się w rzeczywistości. Jeżeli ktoś dysponuje odpowiednio wolnym komputerem (kilkaset mhz najlepiej), łatwo może sprawdzić, że efekty napisane w script.aculo.us bardziej “mulą” kompa niż ich odpowiedniki w jQuery (linux, firefox2 – wydaje mi się, że na innych systemach i przeglądarkach będzie podobnie). Szczególnie widać tą różnicę przy wszelakich tworach drag&drop.

Rozszerzenia

W tym miejscu wystarczy spojrzeć na listę rozszerzeń dla jQuery. Tego chyba nic w tej chwili nie pobije. Rozszerzenia z zakresu UI dla prototypa (a właściwie script.aculo.us) wyglądają biednie w takim porównaniu.

Duży plus dla jQuery.

Społeczność

jQuery jest niewątpliwie biblioteką popularniejszą. Niektórzy mówią, że to chwilowy buzz (znowu ulegam modzie frameworkowej? :).

Prototype z kolei, chociaż mniej popularny, ma mocne wsparcie w społeczności RoR i wsparcie Rails Core Team. Podobno niektórzy pracują nad czymś co można nazwać “jQuery on Rails”, ale nadal prototype jako jedyny jest dostępny “out of the box”.

Rozszerzenia języka.

Prototype dodaje do javascriptu bardzo dużo metod, wzorowanych na metodach rubiego, ułatwiających pracę z wbudowanymi typami. Między innymi moduł Enumerable, Hash, sporo metod do String, Date i dużo dużo więcej.

jQuery z kolei udostępnia tylko kilka metod (each, map, trim, grep…). Oczywiście można dodać swoje metody, ale w tym miejscu trzeba wspomnieć o filozofii jQuery.

Prototype dodaje nowe metody do poszczególnych klas, dzięki czemu można napisać na przykład:


['a', 'b', 'c'].each(function(v, i) { alert(v); });

W jQuery wyglądałoby to w ten sposób:


jQuery.each(['a', 'b', 'c'], function(v, i) { alert(v); });

Jeszcze nie jestem do końca pewien, które podejście mi bardziej pasuje. Być może połączenie jQuery z podejściem prototype?


jQuery.extend(Array.prototype, {
  each: function(iterator) {
    jQuery.each(this, iterator);
  }
});

I już można użyć konstrukcji analogicznej do prototype. Po paru zmianach można dodać też resztę funkcji z Enumerable – po odpowiednim przygotowaniu potrzeba niewiele więcej niż copy&paste. Podobnie łatwo będzie z resztą rozszerzeń.

Można również zostać przy podejściu jQuery i napisać metody działające mniej więcej tak:


jQuery.collect(arr, function(v, i) { /* jakiś kod */});

Chwilę po dodaniu tego posta przypadkiem trafiłem na fajny artykuł, który pokazuje dlaczego podejście a’la prototype jest po ciemnej stronie mocy ;-)

W następnym poście opiszę jak można to szybko, łatwo i przyjemnie zrobić. (o ile starczy mi czasu i samozaparcia)

Od wersji 1.6.0 prototype dostanie też parę bardzo przydatnych funkcji i narzędzi. Między innymi DOMBuilder, custom events, wrap() – bardzo podobają mi się takie smaczki. Więcej informacji w notce na stronie prototype

Podsumowując ten punkt, jeżeli chcemy intensywnie korzystać z wymienionych powyżej metod (polecam przejrzeć dokumentację prototype) lepszym wyborem będzie prototype. Z zaznaczeniem, że sporo z tych funkcji można bardzo łatwo przenieść do jQuery ;-)

Materiały

Przez pewien czas, dawno dawno temu, prototype nie miał prawie dokumentacji, co mogło niektórych zniechęcać. Aktualnie można powiedzieć, że zarówno prototype, jak i script.aculo.us są dobrze udokumentowane i raczej nikt nie będzie miał problemu z nauką. Tak samo zresztą jest z jQuery.

Oba framweorki doczakały się książek.

Podsumowanie

Ciężko mi wybrać ten lepsiejszy framework. I na pewno wybór ten nie będzie obiektywny – każdy musi sam rozważyć czego oczekuje po bibliotece.

Wydaje mi się, że przy projekcie, który w tym momencie zaczynam bardziej sprawdzi się jQuery. Mam w głowie ułożony zaawansowany interfejs użytkownika i nie chciałbym żadnych zgrzytów, a jak pokazuje przykład scriptaculous, płynność różnych efektów nie ma wiele wspólnego z szybkością biblioteki.

Z drugiej strony jeżeli ktoś uważa, że będzie wykonywał po stronie użytkownika sporo obliczeń, pętli, działania na dużych tablicach itp. itd. prawdopodobnie dobrym wyborem będzie prototype – nie dość, że jest łatwiej wykonywać te czynności, to jeszcze wszystko działa szybciej.

Mam nadzieję, że powyższy opis pomoże w wybraniu biblioteki lepszej do rozwiązania danego problemu. Jeżeli pominąłem jakieś soczyste właściwości którejś z bibliotek proszę o komentarz – uzupełnię porównanie :)

Posted in  | Tags , , , , ,  | no comments | no trackbacks

Dlaczego jQuery?

Posted by Piotr Sarnacki Fri, 31 Aug 2007 18:17:00 GMT

Jako javascriptowego frameworka (z góry przepraszam ukrytych purystów językowych za brutalne wrzucanie spolszczonych angielszczyzmów – w razie czego proszę o wersję przetłumaczoną w komentarzu, trochę humoru zawsze się przyda) przez długi czas używałem zestawu prototype + script.aculo.us. Po krótkim czasie przywiązałem się i stwierdziłem, że nie ma sensu sprawdzać innych możliwości
  • bo i tak większość frameworków oferuje podobne możliwości
  • będę musiał stracić czas na nauczenie się czegoś nowego
  • Ruby on Rails wspiera powyżej wymieniony zestaw

Właściwie to “wybranie” prototype’a było bezpośrednim następstwem ostatniego punktu. Pomyślałem, że skoro DHH wybrał ten framework, to coś w tym musi być. Podejrzewam, że w rzeczywistości było to spowodowane tym, że jQuery miał w tamtym okresie małą popularność (o ile w ogóle istniał). Patrząc na to jak wyglądają obie biblioteki można odnieść wrażenie, że filozofię dużo bliższą Railsom realizuje jQuery.

Najlepiej to widać patrząc na przykłady:

prototype:
  new Ajax.Updater('id', url, { method: 'get', parameters: par });
  var anchors = document.getElementsByTagName('a');
    for (var i=0; i<anchors.length; i++)
    {
        var anchor = anchors[i];
        var relAttribute = String(anchor.getAttribute('rel'));
        if (relAttribute.toLowerCase().match('history'))
        {
            Event.observe(anchor, 'click', function(){
              //siakaś funkcja
             });
        }
    }
jQuery:
  $('#id').load(url + par);
  $("a[@rel='history']").click(function(){
    //siakaś funkcja
  });

Od razu widać po której stronie stoi przejrzystość (i jasna strona mocy). Ten drugi przykład może nie być już aktualny, bo ostatnio programiści prototype wzięli się do roboty i co jakiś czas zamieszczają wiadomości o zmianach w API, ale takich kawałków można wkleić dużo więcej. Wszystko idzie w dobrą stronę, ale nie wiem czy uda się w niedalekiej przyszłości uzyskać lekkość jQuery.

Ruby on Rails niestety nie mają wsparcia dla jQuery, ale nie jest tak źle. Selektor elementów w RJS’ach dalej będzie działał, resztę kodu można wrzucać bezpośrednio poprzez `page <<`, a brak helperów? Możnaby je przepisać (i zapewne ktoś już to zaczął robić). Aczkolwiek pojawiają się głosy, że domyślne helpery w RoR są krnąbrne oraz złe. Po części całkiem słusznie. Z drugiej strony w niektórych aplikacjach nie ma sensu robić obsługi bez javascriptu (jakieś rozbudowane interfejsy użytkownika), a podobno używanie event handlerów jest wolniejsze niż zwykły onclick. Jak zwykle wszystko zależy od zastosowań i potrzeb. Ciężkie jest życie programisty. Kiedyś padnę na zawał od takiego nawału trudnych decyzji do podjęcia ;)

Jako dalszą lekturę polecam propagandę na blogu jQuery i doniesienia o nowej wersji, gdzie można podziwiać wyniki zabiegów optymalizacyjnych i sporo nowych mechanizmów. Całkiem niedawno jQuery doczekało się książki. Dużym plusem jest też ogromna ilość rozszerzeń. Lista wygląda imponująco.

Jedyne co mnie ostatnio zaniepokoiło to przesiadka z jQuery na prototype, o której mówi Zbigniew Sobiecki w wywiadzie. Jego doświadczenie widać najlepiej patrząc na blipa, więc jakieś powody musi mieć. Będę musiał to zbadać ;)

W każdym razie w tym momencie moim frameworkiem javascriptowym “of choice” jest jQuery. Jeżeli ktoś zna argumenty przemawiające za pozostaniem przy prototype i script.aculo.us niech się nie krępuje i zostawi komentarz.

Dopisane: Znalazłem wczoraj fajne narzędzie do benchmarków. Niestety wersje bibliotek nie są najnowsze, co owocuje cienkimi wynikami jQuery, ale na szczęście jest link do źródeł, więc można wrzucić swoje wersje (ostatnie stabilne wersje jQuery i prototype). Jak widać na obrazkach twórcy jQuery włożyli ogromną ilość pracy w optymalizację, ale cały czas jeszcze trochę brakuje, żeby dogonić prototype.

Rozmawiałem wczoraj ze sztywnym na blipie (jest teraz jednym z developerów blipa). Zwrócił mi uwagę na parę rzeczy, które mi umknęły. Jedną z nich jest brak rozszerzeń dla obiektów istniejących już w javascripcie. Prototype udostępnia bardzo dużo metod, wzorowanych głównie na metodach rubiego, które ułatwiają pracę z typami wbudowanymi (wszelkie iteratory typu collect, each, any, all, różne metody dla klasy String, hashe itp. itd.). Szczerze mówiąc nawet nie pomyślałem, że nic podobnego nie ma w jQuery – przerzuciłem się dosłownie parę dni temu i nie pisałem nic większego. W takim momencie trzeba zadać sobie pytanie co jest priorytetem w danym projekcie. Oczywiście warto znać obie biblioteki, ale niestety do danego zadania trzeba wybrać jedną z nich (teoretycznie nic nie stoi na przeszkodzie, żeby załączyć obie, dzięki jQuery.noConflict, ale trzeba się liczyć z dodatkowymi kilobajtami).

Przejrzałem dodatkowo bloga prototypa i pojawia się cały czas sporo fajnych rzeczy. Myślę, że przy wyborze między tymi dwoma bibliotekami trzeba pomyśleć czy bardziej przydatne będą efekty wizualne i ogólnie grzebanie w CSS i DOM, czy stawiamy na pisanie różnych funkcji “niższego poziomu”. Najgorsze jest to, że wydaje mi się, że w projekcie, który zaczynam będzie się to rozkładało mniej więcej po połowie. Coś czuję, że wrócę jeszcze do tego tematu.

Posted in  | Tags , , ,  | no comments