laupäev, 31. juuli 2010

Statistika: JavaScripti kasutamine Eesti veebilehtedes

Eelmistes postitustes tundsin huvi milliseid JavaScripti teeke Eesti veebilehed kõige parema meelega kasutavad. Esialgu uurisin käsitsi lappasin läbi 30 enam külastatavat veebilehte, kuid kuigi tulemused olid muidugi huvitavad, ei andnud see suuremat pilti Eesti veebilehtede kohta üldisemalt. Seega kirjutasin lihtsa roboti, mis võttis ette kõigi Eesti veebilehtede esilehed ja kontrollis nendes kasutatud teeke.

Tulemused pole 100% usaldusväärsed kuid piisavalt ülevaatlikud. Probleemid tekkisid peamiselt kahest asjast - kas ebaõnnestus serveriga ühendus (läks kirja, et sait ei kasuta JavaScripti) või oli lehel näiteks osa skripte pandud tegelikult HTML kommentaaride sisse. Robot otsis aga skripte regulaaravaldistega, ning kommentaare ei jälginud. Nii jäid esimesel juhul osad asjad märkimata, aga teisel juhul märgiti üle asju, mida tegelikult ei kasutatud. Samuti jäi teegi kasutamine märkimata, kui see laeti lehele dünaamiliselt (näiteks Google Ajax API goole.load abil). Kokkuvõttes aga ei tohiks need probleemid lõpptulemust väga mõjutada, kuna valim oli suhteliselt suur (~50 000 veebilehte).

NB! Kõik numbrid on graafikutel protsentides.

1. JavaScripti kasutamine üldisemalt

Selles testis vaatasin, kas sait a) ei kasutanaud üldse JavaScripti, b) kasutas mõnda tuntud teeki või c) ei kasutanud ühtegi teeki, vaid midagi muud (siia alla lähevad ka Google Analytics jms loendurprogrammid).



2. Teekide omavaheline osakaal

Järgmisena vaatasin, milline on teekide kasutamise omavaheline osakaal - milliseid teeke kasutatakse rohkem, milliseid vähem. Teeke kasutavaid saite oli üldse kokku 19%.



3. Teekide versioonid

Viimasena uurisin täpsemalt teegi siseselt, millised konkreetsed versioonid kindlast teegist kasutusel on ja millised on nende omavahelised suhted.

3.1 jQuery

jQuery on enimkasutatud teek ja seega on ka erinevaid versioone kasutusel seinast seina.



3.2 MooTools



3.3 Prototype



3.4 YAHOO



3.5 Ext-JS



3.6 DOJO



Nagu näha on olukord üsna kirju. Teekide hulgas troonib suurelt jQuery, mida kasutab sama palju veebilehti, kui kõiki teisi kokku. Samas aga on veel väga palju veebilehti, mis teeke ei kasuta. Siinkohal tundub olevat mõistlik kasutada Google AJAX API majutust teekide serveerimiseks - juhul kui kasvõi väike osa veebisaitidest seda kasutavad, muutub üsna tõenäoliseks et kui kasutaja esimest korda sinu saidile satub, on tal saidil kasutatav teek juba brauseri poolt puhverdatud ja seega on säästetud ekstra 100kB lehe laadimisaega ja mis veel tähtsam - 100kB võrguliiklust. Üks klient ei tähenda suurt midagi, aga kümne tuhande kliendi puhul on see juba terve gigabait.

kolmapäev, 28. juuli 2010

JavaScripti teekide kasutamine Eesti lehtedel vol 2

Panin eile käima roboti, mis kammib läbi Eesti veebilehtede esikülgi (kasutan NETI serverite nimekirja) ja lootsin, et täna õhtuks on tulemused käes. Paraku on robot väga aeglane ja praeguseks on läbi käidud vaid pool 50 000 aadressist, seega mingeid lõplikke järeldusi veel teha ei saa. Kui robot on oma töö ükskord lõpetanud, siis panen tulemused kindlasti üles.

Küll aga võib niipalju öelda, et praeguseks kogutud andmete põhjal on juba selgunud paar huvitavat asja. Esiteks fakt mida võis juba varem eeldada - suurem osa veebilehtedest ei kasutagi (vähemalt populaarsemaid) teeke. Teiseks veidi üllatuslikuks momendiks on enamkasutatavate teekide järjekord. Esimene on oodatult suure ülekaaluga jQuery, kuid järgmised kohad läksid minu ennustustest veidi lahku. Aga sellest kõigest siis, kui lõplikud tulemused käes.

Seega kuigi uuringutulemusi veel päris kätte täna ei saanud, õnnestus mul lõpuks ometi saada üles Node.JS server aadressile node.ee. Siiani olen katsetanud localhostis ning veidi ka Amazon EC2 virtuaalmasinas, kuid Amazon on lihtsalt katsetamiseks kallis (ligi 1000 krooni kuus kui server töötab 24/7), localhosti aga väljastpoolt keegi ligi ei pääse. Täna siis lõpuks tellisin Zone virtuaalse privaatserveri ja seadistasin selle jooksutama Nginx + Node.JS + mongoDB.

Nginx'i installisin Node.JS ette puhtpraktilistel kaalutlustel - et saaks kasutada serverit ka tavalise failiserverina (näiteks kasvõi HTML ja pildifailide serveerimiseks), Node.JS puhul on see veidi ebamugavam. Pealegi saan nii Node.JS'i taustal restartida, ilma et server sel ajal eetrist ära kaoks. Failid jõuavad ikka kohale, lihtsalt Node.JS skriptide poole pöördudes tuleb sel ajal Error 503 Bad Gateway.

MongoDB valisin andmebaasiks seetõttu, et mul õnnestus see ära installida. Tahtsin tegelikult kasutada CouchDB'd, kuid miskipärast kukkus paketihaldur selle installi peale nii pröökama, et kogu paketimajandus läks veidi nihu (ei saanud enam midagi peale ega maha installida) ja pidin Google abil veidi nikerdama enne kui kõik korda sain. CouchDB aga ei hakanudki tööle ja võtsin selle asemel siis eelpoolmainitud MongoDB.

kolmapäev, 21. juuli 2010

Flash upload Linuxi all nüüd korras

Kes on Linuxi kasutaja, peaks olema kokku puutunud probleemiga kus veebisaitidel failide üleslaadimisel brauser suuremate failide korral hangub - olukord tekib juhul kui üleslaadimiseks kasutatakse Flashi komponenti. Flash võimaldab küll tekitada kena cross-browser üleslaadimise progressiriba, kuid Linuxis on Flash selle koha pealt senini bugine olnud - nimelt ei edastanud Flash skriptile onprogress sündmust ning teatas andmed alles üleslaadimise lõpus, senini aga oli brauser lihtsalt jäätunud olekus. Väiksemate failide puhul polnud see probleemiks, kuna need läksid nii kähku üles, et väike kangestumine ei seganud, aga suuremate failide korral on lood muidugi teised.

Igatahes, juba kuu aega on väljas Flashi versioon 10.1, mis selle probleemi lahendab. Kellel ikka veel brauser failide üleslaadimisel pangestub, kontrollige Flashi versiooni ja vajadusel uuendage.

esmaspäev, 19. juuli 2010

Milline on kasutatavaim JavaScript library Eesti lehtedel?

Selleks on jQuery. Vaatasin läbi 30 külastatavamat Eesti veebilehte ja leidsin, et jQuery on kasutusel neist 19 lehel (63%), Prototype 2 lehel (7%) ja EXT-JS 1 lehel (3%). Omaloomingut või netist copy-paste teel omandatud menüüskripte jms. kasutas 8 lehte (27%). Mõnevõrra üllatuslikult polnud esimese 30 hulgas ühtegi YUI ega DOJO põhjal tehtud lehte, võibolla see muutuks, kui vaadata vähe suuremat valimit (kuigi ma isiklikult arvan, et suurem valim suurendaks ainult jQuery osakaalu ning muud ei midagi)


esmaspäev, 12. juuli 2010

HTML Notifications API

HTML5 Notifications API võimaldab veebilehtedel brauseriaknast "välja murda" ja kuvada erinevaid teavitusi veebilehe asukohast sõltumatult töölaual sarnasena näiteks MSN Messengeri sisselogimisteavitustega. Pikemalt kirjutasin sellest siin.

neljapäev, 8. juuli 2010

JavaScripti moodulite vaheline suhtlus JavaScriptis

Tänapäevased keerulisemad veebilehed koosnevad tõenäoliselt mitmetest eri komponentidest, mida suuremal või vähemal määral manatakse lehele JavaScripti abil. Nendeks komponentideks võivad muu hulgas olla näiteks järgmised elemendid - sisselogimise vorm mis avaneb hiirekliki peale (algselt on näha ainult tekst "Logi sisse"); bännerite kuvamine lehel; pisike interaktiivne kast ilmateateinfoga (saab valida piirkonda, aega jne); lightbox efekt piltide kuvamiseks; valuuta konverteerimise vidin jms.

Kuigi eemalt vaadates pole neil komponentidel palju ühist, võib siiski juhtuda olukordi kus eri komponendid vajavad võimalust üksteisega suhtlemiseks, et selle abil enese tööd parendada. Näiteks kui kasutaja valib ilmateate kastis mõne muu asukoha, kui algselt määratud, tahaks bännerite kuvaja võibolla näidata kasutajale ainult neid bännereid, mis on valitud piirkonnaga seotud. Või kui kasutaja passiivsuse tõttu keskkonnast automaatselt välja logitakse, ilma uut lehenäitamist tegemata, tahaksid tõenäoliselt kõik komponendid sellest teada saada, nii et suudaksid endid sobivalt ümber häälestada. Rääkimata siis veel sellistest juhtudest, kus seosed on palju otsesemad - kui kasutaja end välja logib/välja logitakse tuleks taastada vahepeal eemaldatud sisselogimise link.

Tõenäoliselt tegelevad kõikide nende operatsioonidega erinevad moodulid. Sisselogimisega üks, bännerite kuvamisega teine ja ilmateatega hoopis kolmas. Seega tuleb välja mõelda mingi mõistlik viis, kuidas need eraldiseisvad moodulid üksteisega suheldud saaks.

Naabrite eiramine

Kõige triviaalsem on lihtsalt teist moodulit eirata ja selle tegevused ise läbi viia. Näiteks kui ilmateate kastis on element <a id="tervitus_tekst"> mis sisseloginud kasutajale teatab "Tere [nimi]!" ning väljaloginud kasutajale "Tere kasutaja!", siis kutsudes esile väljalogimisprotsessi klikkides lehel lingil "Logi välja", ei anna kasutaja haldamise moodul sellest väljalogimisest ilmateate moodulile teada, vaid lihtsalt kirjutab selles oleva kasutajainfoga seotud elemendi üle.

Kasutaja logib välja ->
kasutajate moodul:
$("tervitus_tekst").innerHTML="Tere kasutaja!"

Antud lähenemine on võibolla lihtsustamise mõttes mõistlik väga väiksemahuliste, kuid kindlasti mitte keerulisemate elementide korral. Esiteks võib selline käitumine teise mooduli katki teha - too eeldab, et lehel on üks asi, tegelikult on aga hoopis midagi muud. Samuti võib kõik katki minna, kui lehel polegi ilmateate moodulit. Pealegi lõhutakse nii päris korralikult modulaarsust, kus iga komponent peaks olema eraldiseisev tervik ning pärsitakse ka skaleeruvust programmikoodi mõistes - taoline tegevus on alati erand ning kui erandid kipuvad kuhjuma, on oodata suuri probleeme.

Tagasikutse funktsioonide kasutamine

Keerulisem viis oleks seada üles tagasikutsefunktsioonide registreerimise süsteem. Sellisel juhul ilmateate moodul ütleks lehe laadimisel, et erinevate sisselogimisega seotud sündmuste korral tuleks käivitada parameetrina antud tagasikutsefunktsioon. Juhul kui nüüd kasutaja välja logib, võtab kasutajate haldamise moodul ette kõik sedasi registreeritud tagasikutsefunktsioonid ja paneb need ükshaaval käima. Nii saab ilmateate moodul teada, et kasutaja on välja loginud ja asendab ise tervituse teksti vastavaga.

Tagasikutse funktsiooni registreerimine ->
ilmateate moodul:
kasutajate_moodul.notify_logout_callback = function(){
    ilmateate_moodul.kasutaja_logis_välja();
};

Kasutaja logis välja ->
kasutajate moodul:
kasutajate_moodul.notify_logout_callback();

Antud lähenemine on juba tunduvalt parem kui eelmisena näidatud variant - seekord on moodulid üksteisest juba üsna eraldatud, kumbki teise tööpõllule ei roni. Samuti ei teki ka probleeme, kui ilmateate moodul lehelt üldse puudu on. Küll aga tekivad probleemid siis, kui lehel puudub sisselogimise moodul. Moodulid on endiselt üksteisest kaudselt sõltuvad, kuna vähemalt üks eeldab teise olemasolu (ilmateate moodul eeldab kasutajate mooduli olemasolu).

Kohandatud sündmuste kasutamine

Nõrgalt seotud elementide korral tasuks kõige rohke kaaluda just kohandatud sündmuste kasutusele võttu. Süsteem oleks sarnane nagu tavaliste tagasikutse funktsioonide kasutamise korralgi - ilmateate moodul registreerib tagasikutse funktsiooni, mis käivitatakse juhul kui kasutaja haldamise moodul on kasutaja välja loginud, kuid seekord ei registreeritaks seda sündmust mitte otse kasutajate haldaja pihta, vaid hoopis kohandatud sündmusena mõne suvalise DOM elemendi, näiteks document pihta.

Kui nüüd kasutaja välja logib, annab kasutajate haldamise moodul sellest teada, aga mitte otse ilmateate moodulile, vaid hoopis sellele sõnumikandjana kasutatavale elemendile. Too võtab ükshaaval ette kõik huvitatud ja käivitab nende tagasikutse funktsioonid.

Kohandatud sündmuse registreerimine ->
ilmateate moodul:
document.observe("kasutaja:logis-välja", function(event){
    ilmateate_moodul.kasutaja_logis_välja();
});

Kasutaja logis välja ->
kasutajate moodul:
document.fire("kasutaja:logis-välja");

Viimane lähenemine on käsitletutest kõige turvalisem - kõik moodulid on üksteisest täielikult eraldatud. Kuna üksteisega suhtlemiseks kasutatakse vahendajat, ei puutu ükski moodul otseselt teisega kunagi kokku. Nii võib suvaline moodul heita üles teate, et nüüd midagi juhtus ja juhul kui mõnda teist moodulit see huvitama peaks, saab ta selle teate kätte. Kui aga selliseid huvitatuid pole, ei lähe ka midagi katki. Samuti kui mõni moodul määrab ära teda huvitava sündmuse, siis ei juhtu ka midagi sellest, kui ühtegi taolist sündmust esilekutsuvat moodulit lehel polegi.

Täiendavaks plussiks kohandatud sündmuste kasutamise korral oleks veel "tasuta kaasa tulevad" sündmuste haldamise võimalused - iga käivitatud tagasikutse funktsioon saab standardsel viisil edasist sündmuse täitmist peatada (event.stopPropagation), saab tegevust ka maha registreerida, nii et seda järgmiste sündmuste juures ei kasutata (document.stopObserving) jne.

Vaata ka seda: Ajaxian, How Custom Events Will Save Us All

NB! Näidetes on kasutatud Prototype käsklusi, sama on võimalik saavutada ka kõigi teiste sarnaste teekide abil.

laupäev, 3. juuli 2010

node.js jooksutamine Amazon EC2 virtuaalserveris

Kirjutasin oma wikisse juhendi node.js kasutamiseks Amazon EC2 virtuaalmasinas. Juhendit saab lugeda siit.

Lühidalt tuleb teha järgnevat
- Luua EC2 virtuaalserver
- installeerida selles C kompilaator ja Git versioonihaldus
- Laadida Git abil node.js lähtefailid serverisse
- kompileerida node.js lähtekoodidest lõplik rakendus
- käivitada .js fail, mis defineerib lihtsa veebiserveri

Täpsemalt saab siis lugeda eespool viidatud aadressilt.