De perfecte score

Schermafbeelding perfecte pagespeed score

Het doel

Een perfecte pagespeed-score halen met m’n wordpress site. De code moet passen in een wordpress thema, flexibel genoeg zijn om gemakkelijk aanpassingen te maken, maar er moet zoveel mogelijk geautomatiseerd zijn. En het moet netjes samenwerken met modernizr tests.

Waarom?

Google vind een snelle site steeds belangrijker voor SEO, dus voor toekomstige sites zou het tof zijn als ik zonder teveel ingrepen een zo hoog mogelijke pagespeedscore heb. Omdat ik een eigen wordpress thema heb die ik als basis voor nieuwe sites gebruik moet ik dit er gemakkelijk aan toe kunnen voegen.

Wat moest er gebeuren?

Ik begon met het testen van m’n site om te kijken wat de huidige score was. Die zat voor desktop ergens rond de 80/90, en voor mobiel was het volgens mij ietsje lager. Dit zijn de regels die Google gebruikt om een site te testen. De basis, code verkleinen en afbeeldingen optimaliseren, is gemakkelijk, dus dat zat wel goed.

De lastige regels zijn:

De stylesheet

Ik ben begonnen met het splitsen van de stylesheet, zodat ik regel 2 op kon lossen. Een stylesheet voor content boven de ‘vouw’, die inline in de header staat, en een stylesheet voor de rest. Het selecteren van de content boven de vouw is een beetje natte vinger werk, maar wat er in ieder geval in moet staan is het grid, een normalize of reset, de header en eventueel nog het eerste contentblok daaronder. Omdat ik met SMACSS en gulp werk was het gemakkelijk om de stylesheet te splitsen. Het enige probleem was dat ik afbeeldingen en fonts vanuit m’n stylesheet aanroep, maar dat de url daarvan de hele template url moet zijn als het in de header staat. Daarvoor gebruik ik het volgende stuk code:

<style>
<?php

// Add the theme url to external files
function replaceUrl($buffer) {
return (str_replace('url("', 'url("' . get_bloginfo('template_url') . '/', $buffer));
}

// Include the above the fold css
ob_start('replaceUrl');
include 'style-above-the-fold.css';
ob_end_flush();

?>
</style>

Deze code staat in de header, en vervangt alle url’s door de volledige template url voordat de stylesheet (style-above-the-fold.css) geinclude wordt. De andere stylesheet voeg ik asynchroon met dit stukje script in de header toe:

<script>
var cb = function() {

var l = document.createElement('link'); l.rel = 'stylesheet';
l.href = '<?php bloginfo('stylesheet_url'); ?>';

var y = document.createElement('script');
y.src = '<?php bloginfo('template_url'); ?>/js/yepnope.min.js';

var h = document.getElementsByTagName('body')[0];
h.parentNode.insertBefore(y, h);
h.parentNode.insertBefore(l, h);
};

var raf = false;
try {
raf = requestAnimationFrame || mozRequestAnimationFrame || webkitRequestAnimationFrame || msRequestAnimationFrame;
} catch(e) {}

if (raf) raf(cb);
else window.addEventListener('load', cb);
</script>

Dit is een aangepast stukje code dat Google als voorbeeld geeft bij Pagespeed. De extra stylesheet wordt als eerste geinjecteerd, en daarna wordt de yepnope loader toegevoegd die ervoor zorgt dat de rest van de javascriptbestanden worden toegevoegd. Het originele script van Google injecteert de extra css boven de head, maar het is beter om dit na de head te doen, zodat je met de extra stylesheet de vormgeving van bepaalde elementen nog aan kunt passen.

Bezoekers zonder javascript krijgen deze tweede stylesheet niet, dus daarvoor heb ik deze stylesheet in een noscript tag in de header gezet:

<noscript>
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" media="screen">
</noscript>

De javascript

Om het blokkeren van de pagina terwijl de javascript geladen wordt tegen te gaan moest de javascript asynchroon geladen worden. Het mooie is dat dat heel gemakkelijk met yepnope kan (templateUrl is de template url als javascript variabele)

// Async loading
yepnope([{
load: templateUrl + '/js/modernizr.min.js',
complete: function() {
// Modernizr
}
} , {
load: 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js',
complete: function() {
// jQuery
if (!window.jQuery) {
// Zet ook een jquery lokaal, voor het geval dat google offline is
yepnope(templateUrl + '/js/jquery.min.js');
}
}
} , {
load: templateUrl + '/js/functions.min.js',
complete: function() {
// Custom functions
}
}]);

Voila!

Een perfecte score! Nu (1 mei 2014) sta ik op de 7e plek als je googled op freelance front-end developer. Ik ben vooral benieuwd of m’n plaats in de zoekresultaten verbetert, of dat deze moeilijkste optimalisaties eigenlijk niet zoveel doet voor m’n vindbaarheid.

Update 9 mei

Het lijkt er op dat ik twee plaatsen opgeschoven ben en nu op de vijfde plaats sta. In de afgelopen negen dagen heb ik verder geen aanpassingen aan m’n site gedaan. Vandaag heb ik twee dingen aangepast: na een aantal performance tests leek het er op dat het ongeveer een seconde duurt voordat jQuery van de Google CDN gedownload is. Dus jQuery staat nu lokaal. En ik kreeg deze discussie vandaag doorgestuurd. Het inline zetten van modernizr heb ik snel getest, en ook dat leek milliseconden snelheidswinst op te leveren. We gaan zien wat deze aanpassingen doen!

Update 15 mei

M’n positie in Google schommelt. Soms de zesde, dan weer de vijfde plaats. jQuery haal ik inmiddels weer van de Google CDN, omdat ik er op gok dat de meeste mensen deze al, via een andere site, in hun cache hebben. En modernizr staat niet meer inline. Misschien is het iets sneller, maar de pagespeed score gaat erdoor weer omlaag.

Update 25 mei

Nu sta ik op de vierde plaats.

Update 3 juni

Ik ben inmiddels opgeschoven naar de derde plaats. Nog twee te gaan! 😉

3 Reacties

  1. Nu sta je tweede! =D

  2. Hallo wout, mooi stuk over de “perfect score” ziet er zo simpel uit zoals jij dat beschrijft. Ik zit al weken te knutselen om hoger te komen met mijn pagespeed-score, maar ter vergeefs. Zoals hierboven door jou beschreven kan dat met elke WP-theme? Ik mis gewoon nog heel veel kennis. Kan ik de codes gewoon kopiëren en plakken? Of moet ik ergens nog op letten? grtjs, Sander

    1. Hoi Sander,

      Deze werkwijze werkt eigenlijk vooral met thema’s die helemaal zelf gebouwd zijn. Gekochte thema’s wil je af en toe ook kunnen updaten, en met deze extra code kan dat niet meer.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *