Körülbelül 10-20 webalkalmazást csináltam eddigi pályafutásom során, kb. 7 különböző Java és/vagy Javascript keretrendszert használva. Egységsugarú szoftverfejlesztőként leginkább az érdekelt, hogy mennyire kényelmes a mások által kiválasztott keretrendszert használni, mennyire jól karbantartható a kód. A leggyakoribb esetben semmi kapcsolatunk sem volt az üzemeltetőkkel, ritkább esetben volt némi kommunikáció. Ilyenkor azt hallottuk hogy utálnak minket, mert a webalkalmazás lassú, rohadtul zabálja a sávszélességet és lehetetlen konfigurációs szinten optimalizálni, pl. nem lehet úgy beállítani a proxy-t, hogy cache-elni tudja a tartalmat, de különben is egy login oldalhoz minek kell 1 megabájt? Az architekt-jeink általában egy hanyag "sorry"-val elintézték az ügyet. Bocs, ilyen a keretrendszer amit használunk - és továbbra is toltuk bele a megabájtokat a drótba. Szerintem ez nem volt valami profi hozzáállás.
Úgy gondolom, hogy aki több akar lenni mint "egységsugarú webprogramozó", nem elég hogy a nyelvet ismerje amin webalkalmazást ír, és persze a HTML-t és a Javascript-et, hanem azzal is tisztában kell lennie, hogy a bájtok hogyan jutnak el a browser-hez és a browser mit kezd velük. Ennek ismeretében képes lesz rá, hogy az aktuális keretrendszert optimálisabban használja, vagy legalább meg tudja indokolni hogy miért kellene az egészet kidobni a fenébe.
A Devoxx-on több kiváló előadás is volt a témában Ilya Grigorik-tól. Ezek közül az egyik hozzáférhető a Parley's-on, amit egyébként a Devoxx egyik legjobb előadásának választottak és ahol igazán tanulságos dolgokat sikerült lejegyzetelnem.
Egy weboldal letöltődési sebessége kulcsfontosságú. A Google-nél úgy gondolják, hogy 250ms lenne az elfogadható, amivel megelégszik az ember. Ezzel szemben azt mérik, hogy a valódi weblapok betöltődési mediánja 2.7s, mobiloknál 4.8s. Ez elég sok. Amikor egy browser be akar tölteni egy oldalt, először is fel kell oldani az URL-t fizikai címre DNS segítségével. Ez átlagosan 130ms, függ attól hogy a webcím milyen szolgáltatónál van beregisztrálva. A namebench egy nyílt forrású eszköz, amivel a DNS lookup sebességét lehet méricskélni.
Érdekes módon, ha növeljük a sávszélességet, a weboldal betöltődése 5mbps fölött már nem fog számottevően gyorsulni, mégpedig azért, mert nem a sávszélesség hanem a késleltetés (latency) a szűk keresztmetszet. Ez egyrészt a fénysebességből, másrészt a TCP protokoll Slow-start részéből adódik, vagyis hogy új connection nyitása egy lassú adatátvitellel indul, ami aztán fokozatosan gyorsul. Ha sok kis fájlot kell átvinni és mindig újra kell nyitni a kapcsolatot, az mindig lassan fog indulni. A browser-ek segítenek ahol tudnak a kapcsolatok újrahasznosításában. Fájlok konkatenálása és sprite image-ek használata emiatt jó ötlet, viszont rossz ötlet Javascript-ből letöltögetni resource-okat, mivel abban a böngésző abszolút nem tud közreműködni optimalizálás szempontjából. Egy browser egy host felé 6 kapcsolatot tud nyitni egy időben, tehát egyidőben 6 resource-ot tud letölteni.
A HTTP1.1 nem igazán optimális protokoll, rengeteg kvázi fölösleges meta-adat megy át a dróton plain text formátumban. A HTTP2.0 ezzel szemben már némileg optimalizált lesz. Az SPDY pedig a Google által fejlesztett protokoll, ami a mostani HTTP-re épül, csak optimálisabban használja azt ki.
A mobiltelefonoknál még kacifántosabb mutatvány egy weboldal letöltése. Nemcsak azért, mert a mobilhálózat tornyaival kell pingpongozni, hanem még a belső adó-vevőt teljesítményét is le-fel kell kapcsolgatni, merthogy amikor nincs forgalmazás, a mobil adóvevője energiatakarékos állapotban van. Emiatt egy sima HTTP GET kérés is 2 másodpercig tarthat 3G-n.
Ahogy a bájtok kezdenek megérkezni a browser-be, ez elkezdi felépíteni a dokumentumot. Progresszív építés és renderelés van, azaz amint kiderül hogy valamit le kell tölteni, a browser elkezdi letölteni, feltéve hogy van szabad kapcsolat az adott host irányába a 6-ból. Azt is meg lehet tenni, hogy bizonyos resource-okat más host-ról szolgálunk ki (CDN), de akkor a DNS lookup jelenthet némi többletidőt. Amint valamit ki lehet renderelni, a browser máris megteszi. Az a jó, ha a user minél hamarabb lát valami renderelést. Ezzel kapcsolatban a következőeket tudjuk tenni:
- CSS fájlok előre, JS fájlok hátra a HTML-ben.
- Ne legyen végrehajtandó Script tag a HTML-ben, mert az megakasztja a renderelést. A browser elkezdi parszolni és végrehajtani a Javascriptet, ami elég sok idő. Ha inline Javascript-ből kezdünk letöltögetni még content-et, az még külön szívás, mert addig fog malmozni a browser, amíg vissza nem jön a válasz.
- Szerveroldalon, amint tudunk küldjük ki a content-et. (flush early, flush often) A Google kereső pl. amint bejön egy kérés, még azelőtt elkezdi tolni ki a választ, mielőtt a kérést feldolgozná, mivel a header úgyis mindig ugyanaz lesz.
- Óvakodjunk a redirect-ek használatától.
A developers.google.com/speed oldalon még további hasznos tippek találhatóak.
Ilya másik előadása a Chrome Devtools-ról szólt (A Chrome böngésző Firebugja). Ennek a slide-jait itt lehet megnézni. Azt eddig is tudtam, hogy a Devtools-ban lehet böngészgetni a DOM-ot és Javascript-et lehet debugolni, de az előadáson elég sok újat hallottam.
A DOM nézegetőben az elem-ekre is lehet breakpoint-ot tenni, pl. ha valaminek változik az attributuma, megállítja a javascript-et. Ha kiválasztunk egy elemet a DOM fában, a konzol ablakban $0 begépelésével tudunk hivatkozni rá.
A Network timeline-ben nyomon követhetjük az oldal betöltődését. Melyik request-nek mennyi a latency-je, melyik request-ek blokkolják a többit, melyik request-et ki kezdeményezte. A poszt elején leírt kritériumok ismeretében (6 connection/host, javascript kéréseket nem optimalizálja a browser, caching) elég sokat ki lehet olvasni a waterfall diagramból és elég jó ötleteket lehet gyűjteni az optimalizáláshoz. Alapból időrendben vannak a request-ek, de meg lehet változtatni a sorrendet más szempont alapján is, pl. hogy a legnagyobb késleltetésű request legyen elől. Ha archiválni akarjuk a diagramot, vagy meg akarjuk mutatni másnak, vagy bugreporthoz akarjuk csatolni, exportálni is lehet HAR (HTTP archive format) formátumban. Sokféle eszköz van HAR-ok nézegetésére, pl. a chromeHAR, ami egy online webapp és a chrome-hoz hasonlóan meg tudja jeleníteni a diagramot.
A Heap Profiler-ben snapshotokat lehet készíteni a memória állapotáról. Két különböző időpillanatban keletkezett snapshotot pedig össze lehet hasonlítani, akár objektumszinten is le lehet ásni, melyik objektum szaporodik el veszélyesen.
Az Audits panelen megkérhetjük a Chrome-ot, hogy analizálja a weboldalt. Ez néhány hasznos tanáccsal tud ellátni, pl. észreveszi a kihasználatlan CSS stílusokat, de ha valakinek komolyabb tanácsokara fáj a foga, akkor letöltheti a PageSpeed Insights-et. Ez már olyan tanácsokat is fog adni, hogy "hé, ezt az image-et értelmesebb módon is össze lehetne tömöríteni". Egyéb eszköz a PhantomJS, amit Jenkins-sel is lehet integrálni. A PhantomJS analizálni tudja az oldal letöltődését és egy riportban jelzi a potenciális problémákat.
Nemcsak játékok esetén, de webappoknál sem árt, ha scrollozásnál vagy böngészgetésnél tudunk hozni egy egészséges FPS-t. 60 frame per second lenne az ideális, de az is jó lehet ha kevesebbel megelégszünk. Lényeg, hogy maradjunk konzisztensek. Ha néha leesik az FPS, az nagyon zavaró tud lenni. A sokáig futó javascript-ek tudják megakasztani a renderelést. Ezt a Timeline panelen tudjuk böngészgetni. Ezt a WebWorker-ek használatával, vagy a nagyobb időigényű javascript logikák szétcincálásával tudjuk orvosolni.
Az előadás vége a Chrome DevTools bővíthetőségéről szólt. A DevTools maga is egy webalkalmazás, amihez plugineket lehet írni Javascript-ben és akár más böngészőre is rá lehet kapcsolódni. Sőt, van egy olyan nyílt forrású progi, amivel iOS alkalmazások hálózati forgalmazását lehet debugolni Chrome-ban (PonyDebugger). A Chrome-ban, az URL helyére lehet beírni még érdekes dolgokat, amivel a browser mélyebb lelkivilágát kutatgathatjuk.
A végén valaki megkérdezte a közönségből, hogy jó-jó, de mi Java fejlesztők vagyunk, JSP-ket és egyéb keretrendszereket használunk, amikről az előadáson egyáltalán nem esett szó. Mit csináljon egy Java fejlesztő, hogy gyorsabb legyen a webapp-ja? Ha benned is motoszkál ez a kérdés, olvasd el újra a posztot az elejétől.