Tweakblogs - faster and fancier! 
Was het je wel eens opgevallen dat 'onze' tweakblogs eigenlijk best wel snel zijn? Toegeven: we bieden nog niet zoveel opties als vergelijkbare sites waar je je blog kan huisvesten, en het is erg 'kaal' vergeleken met een zelf gehoste WordPress, Movable Type of Typo al dan niet opgetuigd met vele plugins, maar het is wel snel, en het is zojuist nog sneller geworden!
De afgelopen week ben ik tussendoor wat bezig geweest met query-optimalisaties voor de tweakblogs. Zoiets begint doorgaans met het kijken op een aantal pagina's hoeveel queries er gedaan worden en hoeveel tijd die kosten. Daar hebben we een eenvoudige indicatie voor, en mischien is het je ook wel eens opgevallen in de statusbalk van je browser (vermits je browser die niet standaard onderdrukt):

Dat verdient wat uitleg:
'Server' staat voor de server die het request heeft afgehandeld. Zoals je misschien wel weet hebben we meerdere webservers in ons serverpark, en aangezien deze niet allemaal dezelfde hardware hebben is het soms wel handig te weten of het request werd afgehandeld door een relatief snelle of tragere server (hetgeen doorgaans overigens geloadbalanced wordt).
'Server time' staat voor de gehele tijd dat de betreffende webserver bezig was met het verwerken van de request. Dat omvat echter enkel de tijd dat PHP hiermee bezig was en niet de verwerkingstijd van Apache, maar dat laatste is meestal verwaarloosbaar aangezien de meeste processing door PHP wordt gedaan.
Dan staan er tussen haakjes nog wat vage aanduidingen en getallen, waarvan hier de officiële uitleg:
'C' staat voor de Computing time; oftewel de echte processing tijd van het request.
'Q' staat voor Queries, gevolgt door het aantal queries en de totale tijd die het de database koste om deze queries uit te voeren.
'M' staat voor Memcached, gevolgt door het aantal calls naar onze memcached server en de totale tijd die het koste om deze calls af te handelen.
'A' staat voor ActiveMQ; onze messaging implementatie om veelvuldige updates te aggregeren en op de achtergrond uit te voeren. Ook hier het aantal calls gevolgt door de tijd die het koste om deze calls uit te voeren.
Hoge waardes hier zijn voor ons natuurlijk altijd een trigger om meer onderzoek te doen, maar zo nu en dan kijken we ook eens of sommige dingen niet gewoon efficiënter kunnen zelfs als de totale tijd ruim binnen onze maatstaf (van max 0.1 seconde per request) ligt. Hiervoor hebben we ook een aantal tools tot onze beschikking die het mogelijk maken alle queries en memcached calls te loggen naar een tabel voor verdere analyse.
Bij de tweakblogs viel mij vooral het benodigde aantal queries per request op, en ook al waren dat stuk voor stuk kleine snelle queries nodigde dat toch uit tot een verder onderzoekje. Een index-pagina van iemands blog had al gauw 15 queries nodig, en dat liep al snel op tot boven de 20 bij een blog-artikel of een categorie-overzicht.
Hier waren 2 oorzaken voor aan te wijzen: in de eerste plaats werden het aantal reacties en de categorieën per post los opgehaald, en in de tweede plaats deden alle functies voor o.a. de sidebar-elementen hun eigen queries terwijl ze eigenlijk daarbij dezelfde data verwerkten, maar telkens op een andere manier.
Dat hebben we nu geaggregeerd naar een functie die vooraf in 1 keer alle benodigde data met betrekking tot de posts en de categorieën ophaalt en die 'op aanvraag' die data op maat kan aanbieden. Verder hebben we het opvragen van het aantal reacties zoveel mogelijk geprobeerd te combineren.
Dat heeft al geleid tot een behoorlijk vermindering van het aantal benodigde queries; op mijn blog index bijvoorbeeld van zo'n 18 queries naar 5* en op een blogpost pagina zoals deze van ongeveer 22 queries naar 8*. Door de interne cacheing en processing is wel de benodigde 'Computing time' toegenomen, maar dat weegt niet op tegenover de performance winst die behaald wordt op het reduceren van het aantal queries.
*o.a. afhankelijk van of je je eigen weblog bekijkt en/of je ingelogd bent
Maar ook clientside viel er nog wel wat te verbeteren qua performance. Zo werden er nogal wat JS en CSS bestanden ingeladen die niet of nauwelijks noodzakelijk waren. Dat is nu ook teruggebracht tot de basis wat tot deze prachtige score in YSlow resulteerde:

Jep, op een klein onbeduidend puntje na (we gzippen javascript al, dus minification zal weinig extra opleveren en de pagina's zijn al klein) een almost perfect score!
Last but not least heeft onze rob_erwt ook de mogelijkheden om je eigen tweakblog op te leuken flink uitgebreid (link alleen beschikbaar als je een tweakblog hebt)
De afgelopen week ben ik tussendoor wat bezig geweest met query-optimalisaties voor de tweakblogs. Zoiets begint doorgaans met het kijken op een aantal pagina's hoeveel queries er gedaan worden en hoeveel tijd die kosten. Daar hebben we een eenvoudige indicatie voor, en mischien is het je ook wel eens opgevallen in de statusbalk van je browser (vermits je browser die niet standaard onderdrukt):
Dat verdient wat uitleg:
'Server' staat voor de server die het request heeft afgehandeld. Zoals je misschien wel weet hebben we meerdere webservers in ons serverpark, en aangezien deze niet allemaal dezelfde hardware hebben is het soms wel handig te weten of het request werd afgehandeld door een relatief snelle of tragere server (hetgeen doorgaans overigens geloadbalanced wordt).
'Server time' staat voor de gehele tijd dat de betreffende webserver bezig was met het verwerken van de request. Dat omvat echter enkel de tijd dat PHP hiermee bezig was en niet de verwerkingstijd van Apache, maar dat laatste is meestal verwaarloosbaar aangezien de meeste processing door PHP wordt gedaan.
Dan staan er tussen haakjes nog wat vage aanduidingen en getallen, waarvan hier de officiële uitleg:
'C' staat voor de Computing time; oftewel de echte processing tijd van het request.
'Q' staat voor Queries, gevolgt door het aantal queries en de totale tijd die het de database koste om deze queries uit te voeren.
'M' staat voor Memcached, gevolgt door het aantal calls naar onze memcached server en de totale tijd die het koste om deze calls af te handelen.
'A' staat voor ActiveMQ; onze messaging implementatie om veelvuldige updates te aggregeren en op de achtergrond uit te voeren. Ook hier het aantal calls gevolgt door de tijd die het koste om deze calls uit te voeren.
Hoge waardes hier zijn voor ons natuurlijk altijd een trigger om meer onderzoek te doen, maar zo nu en dan kijken we ook eens of sommige dingen niet gewoon efficiënter kunnen zelfs als de totale tijd ruim binnen onze maatstaf (van max 0.1 seconde per request) ligt. Hiervoor hebben we ook een aantal tools tot onze beschikking die het mogelijk maken alle queries en memcached calls te loggen naar een tabel voor verdere analyse.
Bij de tweakblogs viel mij vooral het benodigde aantal queries per request op, en ook al waren dat stuk voor stuk kleine snelle queries nodigde dat toch uit tot een verder onderzoekje. Een index-pagina van iemands blog had al gauw 15 queries nodig, en dat liep al snel op tot boven de 20 bij een blog-artikel of een categorie-overzicht.
Hier waren 2 oorzaken voor aan te wijzen: in de eerste plaats werden het aantal reacties en de categorieën per post los opgehaald, en in de tweede plaats deden alle functies voor o.a. de sidebar-elementen hun eigen queries terwijl ze eigenlijk daarbij dezelfde data verwerkten, maar telkens op een andere manier.
Dat hebben we nu geaggregeerd naar een functie die vooraf in 1 keer alle benodigde data met betrekking tot de posts en de categorieën ophaalt en die 'op aanvraag' die data op maat kan aanbieden. Verder hebben we het opvragen van het aantal reacties zoveel mogelijk geprobeerd te combineren.
Dat heeft al geleid tot een behoorlijk vermindering van het aantal benodigde queries; op mijn blog index bijvoorbeeld van zo'n 18 queries naar 5* en op een blogpost pagina zoals deze van ongeveer 22 queries naar 8*. Door de interne cacheing en processing is wel de benodigde 'Computing time' toegenomen, maar dat weegt niet op tegenover de performance winst die behaald wordt op het reduceren van het aantal queries.
*o.a. afhankelijk van of je je eigen weblog bekijkt en/of je ingelogd bent
Maar ook clientside viel er nog wel wat te verbeteren qua performance. Zo werden er nogal wat JS en CSS bestanden ingeladen die niet of nauwelijks noodzakelijk waren. Dat is nu ook teruggebracht tot de basis wat tot deze prachtige score in YSlow resulteerde:

Jep, op een klein onbeduidend puntje na (we gzippen javascript al, dus minification zal weinig extra opleveren en de pagina's zijn al klein) een almost perfect score!
Last but not least heeft onze rob_erwt ook de mogelijkheden om je eigen tweakblog op te leuken flink uitgebreid (link alleen beschikbaar als je een tweakblog hebt)
|
|
IE6: exit |
|
|
IE8 standards compliant by default - but not for Tweakers.net |
Reacties
Tof! Het viel me al eerder op dat de tweakblogs (in vergelijking met de frontpage) behoorlijk snel zijn. Natuurlijk zijn de pagina's clientside ook vrij licht, op mijn N95 bijvoorbeeld laadt een tweakblog bijna instant en de fontpage heeft er een seconde of 10 voor nodig (symbian heeft nogal een traaaaage browser
).
Mooi werk iig
Mooi werk iig
Wat ik alleen mis in het verhaal: waren deze optimalisaties nu echt nodig, of had je gewoon zin om te gaan optimaliseren? En wat zijn de consequenties van deze aanpassingen op de leesbaarheid van de code en de logische structuur ervan? Een functie die specifiek alle benodigde data op gaat halen kan logisch geïmplementeerd zijn, maar klinkt nu niet direct als de meest voor de hand liggende aanpak voor zoiets als dit. En was extra (page)caching niet net zo efficient en (mischien) makkelijker? Behalve reacties denk ik namelijk niet dat weblogs veel dynamische data bevat, waardoor het dus relatief goed te cachen is...
Goed bezig! Leuk om dit soort technische verhalen te lezen, onderscheidt t.net ook wel een beetje van de rest imho.
Het was niet echt noodzakelijk maar als je toch in de code bezig bent en je ziet de mogelijkheid om dingen te optimaliseren (en je hebt er tijd voor - in mijn geval heb ik veel dingen in mijn eigen tijd gedaan, mede omdat ik zelf ook een persoonlijk belang heb in deze omdat het ook mijn eigen blog betreftWat ik alleen mis in het verhaal: waren deze optimalisaties nu echt nodig, of had je gewoon zin om te gaan optimaliseren?
In dit geval was het refactoren naar een generieke aggregatie-functie juist een voordeel voor de code; in plaats van dat je tig gelijksoortige queries verdeelt hebt over verschillende functies heb je dat nu geconcentreerd. Dat maakt het eventueel voor de toekomst ook makkelijker om daar een extra cacheing-laag overheen te bouwen.En wat zijn de consequenties van deze aanpassingen op de leesbaarheid van de code en de logische structuur ervan?
Cacheing is zeker niet makkelijker want juist het belangrijkste aspect daarvan - hoe hou je je cache zo goed mogelijk in sync met de actuele situatie - is vaak een lastig en complex probleem. Zoals gezegd maken de aanpassingen die nu zijn gedaan het wel makkelijker om cacheing toe te gaan passen (op data-niveau), maar vooralsnog is dat pas echt pure overkillEn was extra (page)caching niet net zo efficient en (mischien) makkelijker?
Het klopt dat behalve de reacties de data niet heel erg dynamisch is, aan de andere kant praat je ook niet over erg veel data: je hebt een blog met bijbehorende categorieën, blogposts en de daarbij horende reacties en dat is het wel.
DamnLast but not least heeft onze rob_erwt ook de mogelijkheden om je eigen tweakblog op te leuken flink uitgebreid (link alleen beschikbaar als je een tweakblog hebt)
Goed werk hoor
respect voor de 98% score op YSlow.. Zelf zorg ik altijd dat ik op z'n minst een C haal, maar veel hoger dan een vette B ben ik nooit gekomen.
Naja, CDN heb ik niet en gzip kan ik vaak niet eenvoudig aanpassen, dus daar mis ik al dikke punten.
Btw, hier zie ik vanuit YSlow dat er wat zaken lager gescoord worden hier:
B 2. Use a CDN
Using these CDN hostnames from your preferences: tweakimg.net
These components are not on a CDN:
* http://tweakers.net/ext/f/eOyb69vb3OptXr60fvU5bClI/full.png
* http://tweakers.net/ext/f/ekJFhPqPgKT54Fij4fiF1uyA/full.png
B 6. Put JS at the bottom
2 external scripts were found in the document HEAD. Could they be moved lower in the page?
* http://tweakimg.net/x/general.js?1235487101
* http://tweakimg.net/x/reacties.js?1227257899
B 10. Minify JS
The following JavaScript files do not appear to be obfuscated nor minified.
* (14.2K) http://tweakimg.net/x/general.js?1235487101
* (5.7K) http://tweakimg.net/x/reacties.js?1227257899
Je totaal score komt dan ook op een 95% hier. Komt dit door de aanpassingen?
Naja, CDN heb ik niet en gzip kan ik vaak niet eenvoudig aanpassen, dus daar mis ik al dikke punten.
Btw, hier zie ik vanuit YSlow dat er wat zaken lager gescoord worden hier:
B 2. Use a CDN
Using these CDN hostnames from your preferences: tweakimg.net
These components are not on a CDN:
* http://tweakers.net/ext/f/eOyb69vb3OptXr60fvU5bClI/full.png
* http://tweakers.net/ext/f/ekJFhPqPgKT54Fij4fiF1uyA/full.png
B 6. Put JS at the bottom
2 external scripts were found in the document HEAD. Could they be moved lower in the page?
* http://tweakimg.net/x/general.js?1235487101
* http://tweakimg.net/x/reacties.js?1227257899
B 10. Minify JS
The following JavaScript files do not appear to be obfuscated nor minified.
* (14.2K) http://tweakimg.net/x/general.js?1235487101
* (5.7K) http://tweakimg.net/x/reacties.js?1227257899
Je totaal score komt dan ook op een 95% hier. Komt dit door de aanpassingen?
@link0007: nee, dat komt niet door de aanpassingen van rob_erwt maar omdat de 98% score (bijna 99% zelfs, maar YSlow rond af naar beneden) gemeten is op de index van mijn blog en niet op een blogpost pagina zoals deze 
Op een blogpost pagina laden we inderdaad een extra javascript bestand, en je hebt - zoals ook in deze post - soms nog wat extra plaatjes in de post staan die niet van een 'CDN' afkomen.
Sommige rules moet/mag je ook wel wat losser interpreteren af en toe; minification of obfuscation van onze javascripts zal bijvoorbeeld maar erg weinig extra winst opleveren aangezien we ze al compressed serveren. YSlow lijkt ook helemaal niet naar filesize te kijken, dus een uncompressed JS bestand van 10KB kost je meer puntaftrek dan een compressed en minified JS bestand die al met al toch nog 100KB is over de lijn...
Voor het eerste punt, 'Make fewer HTTP requests' scoorden we al een 100% A grade toen we nog 3 CSS files per pagina hadden (tesamen ruim 65KB uncompressed), maar ook dat heb ik teruggeschroeft naar 1 CSS bestand van slechts 9KB uncompressed. Een behoorlijke reductie dus, maar het levert je geen punt extra op in YSlow...
Op een blogpost pagina laden we inderdaad een extra javascript bestand, en je hebt - zoals ook in deze post - soms nog wat extra plaatjes in de post staan die niet van een 'CDN' afkomen.
Sommige rules moet/mag je ook wel wat losser interpreteren af en toe; minification of obfuscation van onze javascripts zal bijvoorbeeld maar erg weinig extra winst opleveren aangezien we ze al compressed serveren. YSlow lijkt ook helemaal niet naar filesize te kijken, dus een uncompressed JS bestand van 10KB kost je meer puntaftrek dan een compressed en minified JS bestand die al met al toch nog 100KB is over de lijn...
Voor het eerste punt, 'Make fewer HTTP requests' scoorden we al een 100% A grade toen we nog 3 CSS files per pagina hadden (tesamen ruim 65KB uncompressed), maar ook dat heb ik teruggeschroeft naar 1 CSS bestand van slechts 9KB uncompressed. Een behoorlijke reductie dus, maar het levert je geen punt extra op in YSlow...
Mooi incentive om eens wat meer te posten danHet was niet echt noodzakelijk maar als je toch in de code bezig bent en je ziet de mogelijkheid om dingen te optimaliseren (en je hebt er tijd voor - in mijn geval heb ik veel dingen in mijn eigen tijd gedaan, mede omdat ik zelf ook een persoonlijk belang heb in deze omdat het ook mijn eigen blog betreft) is het zonde om dat dan niet te doen.
F5'en gaat inderdaad retesnel op Tweakblogs nu. Ook handig met de nieuwe bloggers straks 
Die extra info in je taakbalk, heeft dat een naam, en hoe schakel je dat in? (Fx3) Nu zijn er 1680px behoorlijk leeg, en da's toch zonde. Extra informatie echter, is altijd tof
Die extra info in je taakbalk, heeft dat een naam, en hoe schakel je dat in? (Fx3) Nu zijn er 1680px behoorlijk leeg, en da's toch zonde. Extra informatie echter, is altijd tof
In Firefox (Engelse versie) zit dat onder Tools->Options, tabje Content en dan achter 'Enable JavaScript' op het knopje 'Advanced' klikken en 'Allow scripts to: Change statusbar text' aanvinkenDie extra info in je taakbalk, heeft dat een naam, en hoe schakel je dat in?