Seravon koodaava toimitusjohtaja Otto Kekäläinen kertoi 29.4.2020 järjestetyssä webinaarissa mitä jokaisen WordPress-kehittäjän kannattaa tietää välimuisteista.
4. Huippuluokan suorituskykyä
Googlen työntekijän
julkaisema vertailu sivustolla
ismyhostfastyet.com
vahvistaa, että Seravon
asiakkaiden sivustot
latautuvat nopeammin kuin
kilpailevissa palveluissa.
Tutkimuksessa on käytetty
Chrome-selaimen tallentamaa
TTFB (time-to-first-byte)
-mittaustulosdataa oikeilta
käyttäjiltä.
Fast/Average/Slow TTFB by WordPress Host
5. “There are only two hard
things in Computer Science:
cache invalidation and
naming things.”
– Phil Karlton
6. Välimuisteja on kaikkialla
● Keskussuorittimen sisällä (tasot L1-L4)
○ Tietoja ei tarvitse hakea RAM-muistista tietoja uudestaan ja uudestaan
● Käyttöjärjestelmässä (Linux) suojaamassa kiintolevyjä
○ Eri ohjelmat ei lue samaa tiedostoa kiintolevyltä asti jatkuvasti
● Eri ohjelmissa on sisäänrakennettuja välimuisteja
○ PHP
■ Tallentaa tiedostoja, jotta niitä ei tarvitse ladata kiintolevyltä joka sekunti
■ Tallentaa tulkittua PHP-koodia, jotta sitä ei tarvitse ladata jatkuvasti uudestaan
○ Tietokanta
■ Käyttää runsaasti välimuistia (RAM), jotta kiintolevyä ei tarvitse lukea niin usein
○ WordPress
■ Tallentaa tietokantaan transientteja, jotta tietokannasta ei tarvitse tehdä laajoja hakuja
jatkuvasti
...ja tässä vain pari esimerkkiä, lista on pitkä.
7. Välimuisteja on kaikkialla koska?
● Nopeus!
○ Osaatko sanoa heti paljonko on 5 * 5 ? Kyllä, koska tulos on valmiina
muistissasi
○ Entä paljonko on 55 * 555 ? Jaa-a.. täytyypä laskea.
● Se nyt vaan on tyhmää laskea liikaa
● Muistiin ei mahdu kaikkea, joten kannattaa tallentaa asioita, joita
todennäköisesti tarvitsee myöhemmin useasti uudestaan
9. Laitetaanko kaikki välimuistiin?
● Muistiin ei mahdu kaikkea, joten kannattaa vain
tallentaa valmiiksi asioita mitä todennäköisesti
tarvitsee kahdesti tai useammin
● Jos asiaa ei tarvitakaan, tyhjennä välimuisti
○ Käskystä tyhjennys, ns. “cache purge”
○ Sisäänrakennettu mekanismi, esim laskuri kertoo että tietoa haettu 0 kertaa edellisen
tunnin aikana
● Välimuisti voidaan nollata koska tahansa, ja jotkin
järjestelmät tekevätkin sitä säännöllisesti
● Lisäksi välimuisti voi vanheta
10. Vaikeaa: Cache invalidation
● Jos välimuisti voi vanheta, niin minkä ikäsenä?
○ 5 sekuntia?
○ 60 sekuntia?
○ 15 minuuttia
○ 7 päivää?
● Riippuu täysin. Siksi se on niin vaikeaa.
11. Välimuistin käsitteitä
Hakuaika – pitää olla nopeampi välimuistista, jotta säästöä syntyy
Invalidation – millä perusteilla välimuistista poistetaan tietoja
Expiry – aika, jossa tieto vanhenee ja poistetaan välimuistista
Bypass – ohitetaan välimuisti tahallisesti
Miss – jos välimuisti oli tyhjä, on pakko hakea uusin tieto
Hit rate – hit/miss-suhde, kuinka usein tieto löytyi välimuistista (99,99% ideaali)
15. Selaimen HTTP-välimuisti
● Tavoite: välttää turhaa verkkoliikennettä
● Selain tallentaa sivuja ja tiedostoja puhtaasti sen
perusteella mitä HTTP-otsakkeet sanovat.
● Huolehdi, että sivustosi lähettää järkevät
HTTP-otsakkeet ja sisällön voimassaoloajat.
● WordPress ei tee tätä vakiona ollenkaan.
16. Esimerkki: WP 5.3.2 CSS-tiedosto
$ curl -IL https://seravo.com/wp-includes/css/dist/block-library/style.min.css?ver=5.3.2
HTTP/2 200
server: nginx
date: Wed, 29 Apr 2020 05:33:47 GMT
content-type: text/css
last-modified: Tue, 28 Apr 2020 11:42:09 GMT
etag: "5ea81691-1d52e"
expires: Thu, 07 May 2020 05:33:45 GMT
cache-control: max-age=691200
x-proxy-cache: HIT P: A: N: H:0 O: S:
x-powered-by: Seravo
x-seravo-request-id: dd1d5d1e649b5f675269a54e86dabacb
Palvelin kertoo selaimelle, että sisältö on voimassa 7 päivää. Ajan pituudella ei ole merkitystä.
Osoitteessa style.min.css?ver=5.3.2 on kuitenkin aina sama sisältö, ja osoitetta on pakko
päivittää uudella versionumerolla jos sisältö päivittyy, muuten sivu on 7 päivää “rikki” vanhoille
vierailijoille.
17. Esimerkki: teeman CSS-tiedosto
wp_enqueue_style(
'seravo', get_stylesheet_directory_uri() . '/dist/layout.min.css',
false,
wp_get_theme()->get('Version')
);
=> https://seravo.com/wp-content/themes/seravo/dist/layout.min.css?ver=1.2.3
Jos teemassa lataa tyylitiedostoja tai skriptejä ilman versionumeroa, tulee selaimelle aina yksi ja
sama layout.min.css
Jos muistaa versionumeron, tapahtuu lataus osoitteella layout.min.css?ver=1.2.3, mikä
varmistaa, että aina kun teemasta on uusi versio, lataa selain myös tyylitiedostosta uuden
version.
18. Esimerkki: seravo.com CSS-tiedosto
wp_enqueue_style(
'seravo', get_stylesheet_directory_uri() . '/dist/layout.min.css',
false,
seravo_get_git_commit_id()
);
=> https://seravo.com/wp-content/themes/seravo/dist/layout.min.css?ver=c98272d0
function seravo_get_git_commit_id() {
// Don't use shell_exec('git rev-parse --short HEAD') or similar since it
// would spawn a shell session on every WordPress load of every page.
// Instead read directly from .git/logs/HEAD to as efficient as possible.
$git_log_file = '/data/wordpress/.git/logs/HEAD';
if ( is_readable($git_log_file) ) {
$lines = file($git_log_file);
$last_line = array_pop($lines);
$fields = explode(' ', $last_line);
return substr($fields[1], 0, 8);
} else {
return wp_get_theme()->get('Version');
}
}
19. Sisällön voimassaoloaika
header.php:
$seconds_to_cache = 3600; // 1 hour
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
header("Expires: $ts");
header("Cache-Control: max-age=$seconds_to_cache");
=>
expires: Wed, 29 Apr 2020 06:55:49 GMT
cache-control: max-age=3600
Dynaamisissa tiedostoissa voimassaoloaika tulee PHP:ltä. WordPress ei itse aseta
oletuksena voimassaoloaikaa. Teema voi halutessaan sen asettaa HTTP-otsakkeiden avulla, jos
tiedetään, että sivu ei päivity juuri koskaan, tai että päivityksen viiveellä ei ole merkitystä.
Staattisten tiedostojen (esim style.css tai script.js) voimassaoloaika tulee HTTP-palvelimen
asetuksista. Staattisissa tiedostoissa Seravolla vakiona 7 päivän expires ja cache-control.
20. Sisällön voimassaolon esto
nocache_headers();
=>
expires: Wed, 11 Jan 1984 05:00:00 GMT
cache-control: no-cache, must-revalidate, max-age=0
WordPress (tai teema tai lisäosa) estää joskus itse voimassaolon nocache_headers() -funktiolla.
21. Palvelimen HTTP-välimuisti
● Tavoite: välttää turhaa PHP-suoritusta ja tarjota
HTML-tiedosto suoraan muistista
● Palvelimen välimuisti (samoin kuin selaimen!)
tallentaa sivuja ja tiedostoja puhtaasti sen perusteella
mitä HTTP-otsakkeet sanovat.
● Huolehdi edelleen, että sivustosi lähettää järkevät
HTTP-otsakkeet ja sisällön voimassaoloajat.
22. Työkalu: wp-speed-test
$ wp-speed-test
Testing speed URL https://seravo.com...
URL TOTAL NAMELOOKUP CONNECT APPCONNECT PRETRANSFER STARTTRANSFER = AVG
https://seravo.com 0.161 0.004 0.005 0.011 0.011 0.159 0.161
https://seravo.com 0.124 0.000 0.000 0.000 0.000 0.122 0.142
https://seravo.com 0.113 0.000 0.000 0.000 0.000 0.111 0.132
https://seravo.com 0.216 0.000 0.000 0.000 0.000 0.215 0.153
$ wp-speed-test --cache
Testing speed URL https://seravo.com...
Warning: invoked with --cache and thus measuring cached results. This does not measure actual PHP speed.
URL TOTAL NAMELOOKUP CONNECT APPCONNECT PRETRANSFER STARTTRANSFER = AVG
https://seravo.com 0.015 0.004 0.004 0.012 0.012 0.013 0.015
https://seravo.com 0.009 0.000 0.000 0.000 0.000 0.007 0.009
https://seravo.com 0.002 0.000 0.000 0.000 0.000 0.001 0.006
https://seravo.com 0.006 0.000 0.000 0.000 0.000 0.005 0.006
Jos --cache antaa paremman tuloksen, toimii HTTP-tason palvelinvälimuisti oikein.
Vakiona wp-speed-test aina ohittaa välimuistin (se ei ole nginx- vaan wp-speed-test).
23. Työkalu: wp-check-http-cache
$ wp-check-http-cache
----------------------------------------
Seravo HTTP cache checker
----------------------------------------
Testing https://example.com...
Request 1: MISS
Request 2: MISS
Request 3: MISS
----------------------------------------
FAILED: HTTP cache does not work for https://example.com.
----------------------------------------
Please review these headers and try to find what emits them:
expires: Wed, 11 Jan 1984 05:00:00 GMT
cache-control: no-transform, no-cache, no-store, must-revalidate
----------------------------------------
You can also test this yourself by running:
curl -IL https://example.com
Sivustolla todennäköisesti päällä WP_DEBUG tai nocache_headers() muuta kautta, koska 1984.
24. Työkalu: wp-check-http-cache
$ wp-check-http-cache
----------------------------------------
Seravo HTTP cache checker
----------------------------------------
Testing https://seravo.com...
Request 1: HIT
Request 2: HIT
Request 3: HIT
----------------------------------------
SUCCESS: HTTP cache works for https://seravo.com.
----------------------------------------
You can also test this yourself by running:
curl -IL https://seravo.com
Sivusto ei lähetä HTTP-otsakkeita jotka estäisivät palvelintason välimuistin.
25. Välimuistin ohittaminen tarkoituksella
Useimmilla sivuilla halutaan, että HTTP-tason välimuisti on käytössä. Poikkeuksena sivu, jonka
sisältöä on räätälöity vain yhdelle kävijälle, kuten esimerkiksi tunnistetulle käyttäjälle
näytettävä “Hei Otto!” tai WooCommercen ostoskori.
Vakiona näytetään tyhjää ostoskoria ja se saa käyttää välimuistia. Mutta heti kun käyttäjä laittaa
jotain ostoskoriin, pitää näyttää räätälöity sisältö juuri sille kävijälle, ja sitä ei pidäkään tallentaa
välimuistiin.
Näin ei myöskään käy, koska WooCommerce asettaa evästeet woocommece_items_in_cart ja
woocommerce_cart_hash käyttäjälle. Evästeiden läsnäolo estää automaattisesti välimuistin
toiminnan, koska ne ovat merkki käyttäjäkohtaisesta sisällöstä, ostoskorista,
sisäänkirjautuneena olosta tms.
26. Voiko palvelinvälimuisti hidastaa sivua?
Ylimääräiset kerrokset välimuisteja voi vähentää tarvetta hakea tietoa suoraan lähteeltä. Paras
välimuisti on selaimessa itsessään. Houkutteleva vaihtoehto voi olla välimuisti palvelimella joka
on käyttäjän lähellä. Liikenteen kierrättäminen CDN:n kautta voi kuitenkin myös lisätä viivettä.
Esimerkissä suora yhteys on 90 ms mutta WooCommercen käyttö CDN:n kautta on 60+60 ms,
eli 120 ms => 30% hitaampi. Muista mitata ennen ja jälkeen!
Lue lisää: https://wp-palvelu.fi/blogi/onko-cloudflaresta-hyotya/
Avaa
ostoskori
Käyttäjä
Berliini
Palvelin
Helsinki
Palvelin
Amsterdam
HTTP/2-yhteys, avaus+haku 90 ms
HTTP/2-yhteys, a+h 60 ms HTTP/2-yhteys, a+h 60 ms
27. Seravon ominaisuus: palvelinvälimuisti
● Normaali WordPress-sivu on palvelintason välimuistissa 10 minuuttia
vakiona (näet toiminnan katsomalla HIT/MISS -rivejä
HTTP-vastauksessa)
● Palvelintason välimuistin voi tyhjentää komennolla wp-purge-cache
● ...tai ohittaa kun lataa sivun selaimella Ctrl+F5
● Jos sivu on rikki (esim. PHP-syntaksivirhe), astuu peliin stale cache ja
näyttää sivun välimuistista sillä aikaa kun koodaaja lisää puuttuvan
puolipisteen, tms.
29. WordPress transients
// Check for transient. If none, then execute WP_Query
if ( false === ( $featured = get_transient( 'foo_featured_posts' ) ) ) {
$featured = new WP_Query(
array(
'category' => 'featured',
'posts_per_page' => 5
));
// Put the results in a transient. Expire after 12 hours.
set_transient( 'foo_featured_posts', $featured, 12 * HOUR_IN_SECONDS );
}
WordPressin oma sisäänrakennettu välimuisti tietojen tallentamiseksi myöhempää (esim 1
minuutti tai 1 tunti) käyttöä varten. Tallentaa tietokantaan vakiona, mutta voi myös käyttää esim
pelkkää RAM-muistia jos object-cache.php käytössä ja esim Redis-palvelin saatavilla (kuten
Seravolla vakiona kaikilla asiakkailla).
Transient API lyhyesti: get_transient(), set_transient() ja delete_transient()
Lisätietoja: https://wp-palvelu.fi/blogi/wordpress-sivut-300-nopeammaksi-transienteilla/
Muista aina expiry! Muuten WP saattaa
ladata datan wp_load_alloptions() kautta
jokaisella sivunlatauksella!
30. WordPress object cache
● Tavoite: välttää toistuvia tietokantahakuja saman
PHP-sivunlatauksen aikana
31. WP object cache
function prefix_get_post_count( $post_status = 'publish' ) {
$cache_key = 'prefix_post_count_'. $post_status;
$_posts = wp_cache_get( $cache_key );
if ( false === $_posts ) {
$_posts = $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'post' AND post_status = %s",
$post_status
));
wp_cache_set( $cache_key, $_posts );
}
return $_posts;
}
Tallentaa PHP:n muistiin esim. tietokantahaun tuloksia, jotta saman PHP-suorituskerran
aikana eri puolilla WordPressin koodia tehtyjä hakuja ei tarvitse tehdä monta kertaa uudestaan.
(En ole koskaan käyttänyt. Transient API on se mitä sivuston kehittäjä oikeasti tarvitsee!)
Esimerkki sivulta https://developer.wordpress.org/reference/functions/wp_cache_get/
38. Tutustu myös
Välimuisteilla löysät pois sivulatauksista
https://wp-palvelu.fi/blogi/wordpress-valimuisti/
WordPress-sivut 300% nopeammaksi transienteilla
https://wp-palvelu.fi/blogi/wordpress-sivut-300-nopeammaksi-transienteilla/
5 common reasons why your WordPress site is slow
https://youtu.be/8sJExUO-U4A
Improving WordPress Performance with XDebug and PHP Profiling
https://youtu.be/oKcIS5A-6_c