Page Speed – Best practices revisited
Török Gábor küldött be blogmarkot a Google Page Speedről. Ennek kapcsán szépen sorjában végigmentem az ajánlásokon és néhány helyen az eddigi szemlélettel – amit mindenki „kőbe vésett szentírásnak” vett – homlokegyenest ellenkező javaslatot olvastam. Emiatt gondoltam, hogy a számomra kérdéses dolgokat összegyűjtöm. Nézzük hát egyenként ezeket a pontokat.
Ahogy írják is, egyszerűbb és jobb megoldás, ha diszkrét JavaScriptet használunk az expressionök kiváltására.
Ugyanakkor ez ellentmond annak a megállapításuknak, miszerint minél kevesebb felesleges CSS szabályt szolgáljunk ki. Hiszen ha egyetlen CSS állományunk van, akkor a következő oldalnál megspóroljuk azt az időt, amit a böngésző az állomány letöltésére fordítana, cserébe persze a megnövekedett CSS méret miatt a render picivel lassabb lehet, de véleményem szerint még mindig elenyésző a HTTP kéréshez képest.
Persze amennyiben YSlow ajánlás szerint aÍgy a
Fontos a gzip használatakor tisztában lenni azzal is, hogy Internet Explorer 6 alatt a Flash applet a betöltött gzippelt szöveges tartalmat nem képes feldolgozni, így azokat nem lehet például tömörítve kiszolgálni.Vagy magában a fájlnévben:
Azzal viszont nem, hogy ne ugyanazt a (tartalmi) képet használjuk fel, ha két különböző méretben akarjuk megjeleníteni, például avatarok esetében. Ez akkor természetesen igaz, ha – vegyük például a Flickrt – a fotók listázásakor nem a teljes felbontású képet használjuk fel.
…eddig?
Ráadásul az újrafelhasználása a kódnak is macerás lehet, illetve az ajánlást követve megnövekedik a HTML. Nem rajongok az ötletért! És vajon egy összetettebb oldal esetében is mennyivel növekedhet meg a renderelés ideje? 10-100 ms? És akkor szerintem sokról beszélünk. Bár tény, hogy a YSlow prezentációban megmutatták, hogy egyes szolgáltatások forgalma mennyivel csökkenne ilyen mértékű oldalbetöltődési idő növekedés esetén. Valószínűsítem, ez szolgáltatásfüggő.Avoid the
Viszont ami miatt igazán ez a bejegyzés született, az nem más, mint hogy a következőt olvashatjuk ebben a pontban:
Na most vajon nem pont az lenne a lényeg, hogy JavaScript nélkül is elérhető legyen minden lényegi funkció? Ezt az utolsó gondolatot inkább vitaindítónak szánom, sem mint, hogy én magyarázzam meg. Biztos maga a helyzet az – ebben egyetértek –, ami meghatározza a létjogosultságát a „teljes” JS nélküli funkcionalitásnak, de nem érdemes erre törekedni mindig?
■ Avoid CSS expressions
Egyetértek, hiszen ha nincs a JavaScript futtatása engedélyezve, akkor amúgy sem fognak lefutni a CSS expressionjeink, ráadásul egy-egy expressiont akár minden pixelnyi egérmozgatáskor újra és újra lefuttathatja a böngésző, ami feleslegesen terheli a kliens gépét.Ahogy írják is, egyszerűbb és jobb megoldás, ha diszkrét JavaScriptet használunk az expressionök kiváltására.
Combine external CSS
Jó meglátás, hiszen eleve törekedni kell a lehető legkevesebb request számra, másrészt – ahogy később ajánlják is –, a böngészők egy időben ugyanarról a hosztról párhuzamos csak 2–6 fájlt töltenek.Ugyanakkor ez ellentmond annak a megállapításuknak, miszerint minél kevesebb felesleges CSS szabályt szolgáljunk ki. Hiszen ha egyetlen CSS állományunk van, akkor a következő oldalnál megspóroljuk azt az időt, amit a böngésző az állomány letöltésére fordítana, cserébe persze a megnövekedett CSS méret miatt a render picivel lassabb lehet, de véleményem szerint még mindig elenyésző a HTTP kéréshez képest.
Combine external JavaScript
Teljesen egyetértek, nincs nagyon mit rajta boncolgatni. Talán annyi hozzáfűzni való lehet, hogy a Yahoo! YSlow ajánlásban az áll, hogy abody
legvégére rakjuk a script
elemeinket, mivel így nem fogják megakasztani a renderelést a feldolgozásukkal. Ezzel szemben a Google a példáiban előszeretettel a head
be rakja őket.Defer loading of JavaScript
Sajnos még nem sikerült olyan oldalt létrehozzak, ahol a masszív tömegű JavaScript alkalmazása – természetesen csakis diszkréten! –, lehetővé tette volna, hogy „defer” betöltést alkalmazzak:- ha pl. bármilyen JS könyvtárat is használunk, annak betöltését már nem tehetjük deferre, mivel az összes többi fájlunk rajta alapszik;
- ha az oldal specifikus JS állományunk tartalmaz load vagy domready handlert, akkor a defer betöltési mód megakadályozhatja azok lefutását.
Persze amennyiben YSlow ajánlás szerint a
script
eket a tartalom után helyezzük el, nem lesz szükségünk load handlerekre, mivel a script
ek lefutásakor már minden elemünk létezni fog a DOM-ban, azokra hivatkozhatunk bátran. Ugyanakkor ezen esetekben nem is lesz szükségünk a defer használatára, mert az oldal renderelését már nem fogják megakasztani a script
jeink feldolgozása.Enable gzip compression
A tanácsuk megfontolandó, miszerint – azon túl, ahogy a címben is szerepel, minden szöveges tartalmat gzippelve szolgáljunk ki – a CSS szabályokon belül a tulajdonságokat és a HTML tageken belül az attribútumokat is ábécérendbe írjuk, ezzel is növelve a gzip hatékonyságát. Erre megoldás lehet, ha a publikáló scriptünket felkészítjük ennek a lekezelésére, így a fejlesztés alatt ezzel nem kell törődnünk. Ugyanakkor ebben a scriptben figyelnünk kell arra, hogy CSS hackek alkalmazásakor már nem mindegy a tulajdonságok sorrendje a szabályainkban, így azokat saját jelöléssel ellátva lehet megjelölni:
#links ul li
{
min-height: 100px;
/* !+ min-height emulálása IE6 és IE7 számára */
height: auto !important;
height: 100px;
/* -! */
}
!+
kezdetű és a -!
közötti megjegyzés blokkot érintetlenül hagyhatja, és mondjuk a szabály legvégére sorolhatja, míg a többi szabályt ábécé szerint rendezheti.Fontos a gzip használatakor tisztában lenni azzal is, hogy Internet Explorer 6 alatt a Flash applet a betöltött gzippelt szöveges tartalmat nem képes feldolgozni, így azokat nem lehet például tömörítve kiszolgálni.
Leverage browser caching
A statikus állományokatExpire
vagy Cache-Control
fejléccel ellátva nagy sávszélességet és — ami még fontosabb — felhasználói időt spórolhatunk meg. Mindig is gyorsabb lesz kiszolgálni egy fájlt a helyi lemezről, mint hálózatról. Ugyanakkor ez magában hordozza azt a veszélyt, hogy ha a lejárati idő előtt módosítjuk a tartalmat, az a felhasználónál nem fog frissülni. Ennek kiküszöbölésére alkalmazható a kiszolgált fájlok verziózása, ami annyit tesz, hogy az állományokra hivatkozáskor a query stringben elhelyezünk egy, az adott fájlra érvényes verziószámot, ami lehet például az SVN revision száma:
<img src="my-image.jpg?1234" alt="Some picture" />
<img src="my-image_v1234.jpg" alt="Some picture" />
Serve resources from a consistent URL
Egyértelmű, ha más domainről szolgáljuk ki ugyanazt, újra be kell gyorsítótáraznia, egyértelműen kerüljük.Specify image dimensions
Azzal kapcsolatban egyetértek, hogy a beszúrt képek méretét határozzuk meg, így könnyítve a megjelenítést.Azzal viszont nem, hogy ne ugyanazt a (tartalmi) képet használjuk fel, ha két különböző méretben akarjuk megjeleníteni, például avatarok esetében. Ez akkor természetesen igaz, ha – vegyük például a Flickrt – a fotók listázásakor nem a teljes felbontású képet használjuk fel.
Use efficient CSS selectors
Logikailag teljesen helytállóak, ellenben ha azt vesszük, a HTML csak jelölésre szolgál, a megjelenésért kifejezetten a CSS a felelős. Legalábbis ezt szajkózták anno, most……eddig?
Ráadásul az újrafelhasználása a kódnak is macerás lehet, illetve az ajánlást követve megnövekedik a HTML. Nem rajongok az ötletért! És vajon egy összetettebb oldal esetében is mennyivel növekedhet meg a renderelés ideje? 10-100 ms? És akkor szerintem sokról beszélünk. Bár tény, hogy a YSlow prezentációban megmutatták, hogy egyes szolgáltatások forgalma mennyivel csökkenne ilyen mértékű oldalbetöltődési idő növekedés esetén. Valószínűsítem, ez szolgáltatásfüggő.
Avoid the :hover
pseudo-selector for non-anchor elements
Viszont ami miatt igazán ez a bejegyzés született, az nem más, mint hogy a következőt olvashatjuk ebben a pontban:Avoid the
Instead of using the pseudo-selector, use a JavaScript
:hover
pseudo-selector for non-anchor elements.Instead of using the pseudo-selector, use a JavaScript
onmouseover
event handler.Na most vajon nem pont az lenne a lényeg, hogy JavaScript nélkül is elérhető legyen minden lényegi funkció? Ezt az utolsó gondolatot inkább vitaindítónak szánom, sem mint, hogy én magyarázzam meg. Biztos maga a helyzet az – ebben egyetértek –, ami meghatározza a létjogosultságát a „teljes” JS nélküli funkcionalitásnak, de nem érdemes erre törekedni mindig?
Köszönjük
Az utolsó kérdésről a véleményem, hogy a :hover -el és a mouseover -el is valamit jelezni akarok az usernek, valami lényegit, akár anchor-on van akár nem. Így hát minden lehetséges eszközzel el kell hogy juttassam hozzá azt az infót, innentől kezdve nem kérdéses, hogy nem szabad kizárni azokat, akiknek a böngészőjében nincs javascript (vagy fordítva, nincs css, bár az gondolom ritkább).
Üdv:
Gábor.
JS-ből törölni a hover-es szabályokat
– Avoid CSS
Hehh. Ez folyton előjön.
1. A css expressionök egyetlen értelmes felhasználási területe az IE6-7 CSS-implementációk egyszerű pótlása.
„hiszen ha nincs a JavaScript futtatása engedélyezve, akkor amúgy sem fognak lefutni a CSS expressionjeink” – nadehát akkor a diszkrét JS-eink se!
2. „ráadásul egy-egy expressiont akár minden pixelnyi egérmozgatáskor újra és újra lefuttathatja a böngésző” – erre a problémára van megoldás, csak szerintem nem sokan tudnak róla.
3. a css expressionök is diszkrét js.
(Egyébként egy IE kikapcsolt JS-sel már eleve paradox helyzet, de ez más kérdés.)
diszkrét!
A diszkrét JS pont azt jelenti, hogy a kérdéses funkció kikapcsolt JS esetén is működjön, nem?!
És a kérdéses funkció hogy
Azt lehet mondani, hogy JS-sel egyáltalán ne korrigáljunk IE-ben css-implementációs hiányokat. És akkor semmilyen JS-ben. Ennek van értelme, bár sztem tarthatatlan álláspont.
Ha meg már engedjük a JS-t erre a feladatra, akkor teljesen mindegy, hogy expression vagy nem, egyik se fog működni kikapcsolt JS-nél, és mindkettő működni fog bekapcsoltnál.
Az expressionök elleni egyetlen normális érv az említett performance flaw (teljesítményhasadék) volt.
Hozzászólás a témához:
Defer loading of JavaScript:
* Azzal, hogy nem a Headerbe teszem bele a JS-et csak az óldal kódja fog nőni, ezáltal több adatott kell letöltenie.
* A head részben elhelyezet scripteket egyes bongészők cache-elik, így gyorsabb a letöltés.
Leverage browser caching:
* Ezt az ötletet díjazom :-)
Use efficient CSS selectors:
* A véleményem szerint, a HTML és a CSS -est külön kell választani! Viszont az már nem fer, hogy a böngészők a szabványokat ..., ezért a fejlesztő szív vele! Sokszor a fapados módszerek a legjobbak, mert minden lekezeli!
Valaki próbált dinamikus táblázatot (colspanolva+rowspanolva) összerakni divből, úgy hogy nem fix a mérete a celláknak és minden böngésző támogatja? (Ha valakniek sikerül megoszthatja velem én feladtam a próbálkozást ahol lehet div ahol meg nem table).
Azt se értem, hogy használj AJAX-ot mert sokkal interaktívabb az oldal és a felhasználónak nem villog a kép meg ilyesmi trend..., da akkor kérdem én? Ha JS levan tiltva, akkor hogy használjak AJAX-ot?
Igaz ezt a problémát a keretrendszerk megoldhatják, de csak a fejlesztő szív vele :-(
Amúgy kössz a cikket :-) Érdekes volt!
??
Div => Table kérdése
Volt egyszer régen, hogy azt szerették volna, ha minden divből áll és még a táblázat is, mert az a trend, meg gyors meg ilyesmi :-) Eddig nem is volt gond, de jött a csavar a táblázat dinamikus és nem tudjuk a méretét. Volt pár ötletem (megvalósításom), de a méret kérdését PHP-val nem megoldható és ezt nem akarták megérteni miért nem.
Félreértelmezted
SAXUS ott a pont!
Akkor korrigálok
Ha itt a "header" alatt a response HTTP header-eket érted, akkor biztos nem fog működni, mivel ott nem tudsz JavaScript file-okat meghatározni. Ha pedig a <head> elemet, akkor sincs igazad, mivel valahova be kell ágyaznod a <script> elemet, és mindenhol ugyanannyi byte-ot fog "megenni".
A böngészők minden letöltött állományt cache-elnek, akárhol is helyezed el a html-ben — vagy akár JS-ben. Ezáltal minden állományra való hivatkozást ott érdemes megejteni — értsd: a kódban elhelyezni —, ahol arra szükséged van, illetve azt például az ajánlás is javasolja: script-eket a css-ek után, stb.
Az AJAX használatával tehermentesíted a szerveredet, a hálózatot és a kliens gépét is, mivel olyankor csak a szükséges adatok fel–le töltése történik meg, nem töltődik le újra a css, js, képek vagy akár a favicon. Mindemellett a felhasználó — ha pl. egy videót néz az oldalon, miközben azt kedvencnek jelöli — nem irányítódik el az éppen használt funkciótól, hanem azzal párhuzamosan történik az interakció.
Az AJAX pedig, amennyiben nem webalkalmazásokról beszélünk, minden esetben diszkréten kell, hogy működjön, tehát ha nincs JS, akkor ha az adott linkre vagy submit gomb-ra kattint a felhasználó, igenis újratöltődve az oldal fog megtörténni a kívánt művelet.
Jogos
ajax terhelés
Gmail
AJAX
Először implementálj minden funkciót HTML és PHP alapon. Ha működik, akkor diszkrét JavaScripttel kapd el az adott eseményt és oldalújratöltés helyett küldd el AJAX-szal a kérést.
IE
Remélem
nem vicc
A hover-t minden esetben kerüljük (?)
Amúgy zárójelben: sajnos az IE6 a linkeken sem mindig jól kezeli a hover-t, majd megpróbálok egy minimalizált mintát is bemutatni, csak most nincs a közelemben Windows és ezáltal IE6.
Paradicsom
El ne gyere onnan! Az maga a Paradicsom :-)
:)
....
Javascript fejlesztésnél a kód fele (vagy több) az ie bugok vagy különcködések kijavítása.
Hogyanok?
Illetve egy másik mondat hiányzik nekem, hogy mit csináljon az átlagjuzer, hogy az adott probléma megoldódjon. a két nulla pontos: Enable gzip compression, Leverage browser caching Mivel hibák nagyrészénél a képeket, css fájlokat, js fájlokat mondja, gondolom az Apache körül kellene keresni a megoldást.
Viszont az Apache ismereteim elég minimálisak, a Google meg nem annyira segített:
A .htaccess-be bekerült a következő: SetOutputFilter DEFLATE de ettől még nem lett Enable gzip. De simán lehet, hogy mást állítottam (volna).
Megköszönném, ha ebben a kérdésben segítséget kapnék. :)
Köszönöm a bíztató
Igazából azért is vannak a címek belinkelve, mivel a Google ott szépen el is magyarázza, hogy mi az ő álláspontjuk azzal kapcsolatban, emiatt is gondoltam úgy, hogy felesleges megismételnem azt, amit ott úgyis leírnak.
A magyar fordítása az oldalnak meg megint egy másik tészta, időhiányban én biztos nem fogok vállalkozni rá ;)
GZIP, DEFLATE
Header append Vary Accept-Encoding
De ez csak akkor fog működni, ha az apachban a mod_deflate engedélyzve van (httpd.conf).
Ha ez nem elérhető, de van zlib:
php_value zlib.output_compression_level 6
Ez ugye csak a php fájlokra fog teljesülni, de egy kis trükközéssel megoldható css és js fájlok esetén is:
AddHandler application/x-httpd-php .js
php_value auto_prepend_file "pre.php"
Ezzel a szerver a css és js fájlokon is lefuttatja a php értelmezőt, valamint minden fájl elejére beszúrja a pre.php tartalmát.
Ezután már csak vissza kell állítani a megfelelő HTTP fejléceket a pre.php-ban.
$path = pathinfo($_SERVER['SCRIPT_NAME']);
if ($path['extension'] == 'css') {
header('Content-type: text/css');
}
if ($path['extension'] == 'js') {
header('Content-type: application/x-javascript');
}
Sok sikert!
Nem kell
Nem biztos
Benéztem
a hover mikor lényegi?
szerintem a hover az esetek 99,9%-ában nem tartalmaz fontos tartalmat, csak a design miatt lényeges.
Fontos UI elem
Lényeges felületi elem a hover!
régen rossz
gexnek igaza van, rossz
Jogos kritika
Megkövet
Lehet, hogy csak elütötte a
hehe
Jó példa?
mindenféle
http://stevesouders.com/cuzillion/?ex=10017&title=IE+Ensure+Ordered+Execution
http://stevesouders.com/cuzillion/?ex=10018&title=FF+Ensure+Ordered+Execution
több js aszinkron betöltése
A demó itt megtalálható: http://galambalazs.extra.hu/multiload/
Eddig IE5.5+, FF3, Opera 9.6, Chrome 2, Safari 4 alatt teszteltem.
gzip compression level
Tömörítés
arány
meg sem érzik
Korrekt