TurboPress: The High Performance Guide to WordPress - Jeff Waugh - WordCamp Sydney 2012

Preview:

DESCRIPTION

Jeff Waugh coaches WordCamp Sydney 2012 on turboboosting your WordPress site, and setting it up for Higher Performance #wcsyd

Citation preview

TurboPressThe High Performance Guide to WordPress

Let’s start withsome theory.

INTERWEBS AMIRITE?

Browser

Web Server

PHP

WordPress

MySQL

shovelling

shovelling

shovelling

shovelling

0. The Browser

Browser Router ISP DNS“ bethesignal.org ”

“ 70 . 85 . 31 . 216 “

1. DNS

DNS Host

Browser Router ISP DNS“ bethesignal.org ”

“ 70 . 85 . 31 . 216 “

1. DNS

DNS Host

10 ms 160 ms

210 ms

Browser Router ISP DNS“ bethesignal.org ”

“ 70 . 85 . 31 . 216 “

1. DNS

Google’s web performance team calculate the average DNS query takes 130ms!

DNS Host

10 ms 160 ms

210 ms

Browser Router ISP DNS“ bethesignal.org “

“ 70 . 85 . 31 . 216 “

2. HTTP

10 ms 160 ms

DNS Host210 ms

Web Server70 . 85 . 31 . 216 : 80

Browser Router ISP DNS“ bethesignal.org “

“ 70 . 85 . 31 . 216 “

2. HTTP

10 ms 160 ms

DNS Host210 ms

Web Server70 . 85 . 31 . 216 : 80

220 ms

Browser Router ISP DNS“ bethesignal.org “

“ 70 . 85 . 31 . 216 “

3. PHP

10 ms 160 ms

Web Server70 . 85 . 31 . 216 : 80

220 ms

PHP

DNS Host210 ms

Browser Router ISP DNS“ bethesignal.org “

“ 70 . 85 . 31 . 216 “

3. PHP

10 ms 160 ms

Web Server70 . 85 . 31 . 216 : 80

220 ms

PHP

DNS Host210 ms

650 ms

Browser Router ISP DNS“ bethesignal.org “

“ 70 . 85 . 31 . 216 “

4. MySQL

10 ms 160 ms

MySQLWeb Server70 . 85 . 31 . 216 : 80

220 ms

PHP

DNS Host210 ms

5. Back to the browser!

Browser

Web Server

PHP

WordPress

MySQL

shovelling

shovelling

shovelling

shovelling

Some gory detail…

GET / HTTP/1.1Host: bethesignal.orgConnection: keep-aliveUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Encoding: gzip,deflate,sdchAccept-Language: en-AU,en;q=0.8,en-US;q=0.6Accept-Charset: UTF-8,*;q=0.5Cookie: wordpress_logged_in_...=jdub...If-Modified-Since: Thu, 12 Jul 2012 21:27:06 GMT

HTTP/1.1 200 OKServer: nginx/1.2.1Date: Fri, 20 Jul 2012 23:48:04 GMTContent-Type: text/html; charset=UTF-8Transfer-Encoding: chunkedConnection: keep-aliveVary: Accept-EncodingVary: CookieX-Pingback: http://bethesignal.org/xmlrpc.phpExpires: Wed, 11 Jan 1984 05:00:00 GMTLast-Modified: Fri, 20 Jul 2012 23:48:03 GMTCache-Control: no-cache, must-revalidate, max-age=0Pragma: no-cacheContent-Encoding: gzip

10:32:16.084565 * About to connect() to bethesignal.org port 80 (#0)10:32:16.084768 * Trying 70.85.31.216... TCP_NODELAY set10:32:16.283247 * connected10:32:16.283376 * Connected to bethesignal.org (70.85.31.216) port 80 (#0)10:32:16.283528 > GET / HTTP/1.110:32:16.283528 > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/...10:32:16.283528 > Host: bethesignal.org10:32:16.283528 > Accept: */*10:32:16.283528 > Accept-Encoding: deflate, gzip10:32:16.283528 > Cookie: wordpress_logged_in_...=jdub...10:32:16.283528 > 10:32:16.995103 < HTTP/1.1 200 OK10:32:16.995216 < Server: nginx/1.2.110:32:16.995240 < Date: Sat, 21 Jul 2012 00:32:16 GMT10:32:16.995295 < Content-Type: text/html; charset=UTF-810:32:16.995374 < Transfer-Encoding: chunked10:32:16.995412 < Connection: keep-alive10:32:16.995447 < Vary: Accept-Encoding10:32:16.995482 < Vary: Cookie10:32:16.995515 < X-Pingback: http://bethesignal.org/xmlrpc.php10:32:16.995548 < Expires: Wed, 11 Jan 1984 05:00:00 GMT10:32:16.995601 < Last-Modified: Sat, 21 Jul 2012 00:32:16 GMT10:32:16.995642 < Cache-Control: no-cache, must-revalidate, max-age=010:32:16.995680 < Pragma: no-cache10:32:16.995717 < Content-Encoding: gzip10:32:16.995759 < 10:32:16.995794 { [data not shown]10:32:17.393072 * Connection #0 to host bethesignal.org left intact10:32:17.393170 * Closing connection #0

Now you havesome <html> …

GET /wp-content/uploads/2011/04/strange-days.jpg HTTP/1.1Host: bethesignal.orgConnection: keep-aliveCache-Control: no-cachePragma: no-cacheUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Referer: http://bethesignal.org/Accept-Encoding: gzip,deflate,sdchAccept-Language: en-AU,en;q=0.8,en-US;q=0.6Accept-Charset: UTF-8,*;q=0.5Cookie: wordpress_logged_in_...=jdub...

HTTP/1.1 200 OKServer: nginx/1.2.1Date: Fri, 20 Jul 2012 23:50:50 GMTContent-Type: image/jpegContent-Length: 180112Last-Modified: Fri, 08 Apr 2011 14:25:27 GMTConnection: keep-aliveExpires: Wed, 19 Jul 2017 23:50:50 GMTCache-Control: max-age=157680000Accept-Ranges: bytes

10:34:05.051972 * About to connect() to bethesignal.org port 80 (#0)10:34:05.052162 * Trying 70.85.31.216... TCP_NODELAY set10:34:05.251898 * connected10:34:05.251989 * Connected to bethesignal.org (70.85.31.216) port 80 (#0)10:34:05.252123 > GET /wp-content/uploads/2011/04/strange-days.jpg HTTP/1.110:34:05.252123 > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/...10:34:05.252123 > Host: bethesignal.org10:34:05.252123 > Accept: */*10:34:05.252123 > Accept-Encoding: deflate, gzip10:34:05.252123 > Cookie: wordpress_logged_in_...=jdub...10:34:05.252123 > 10:34:05.448816 < HTTP/1.1 200 OK10:34:05.448981 < Server: nginx/1.2.110:34:05.449045 < Date: Sat, 21 Jul 2012 00:34:05 GMT10:34:05.449091 < Content-Type: image/jpeg10:34:05.449131 < Content-Length: 18011210:34:05.449170 < Last-Modified: Fri, 08 Apr 2011 14:25:27 GMT10:34:05.449211 < Connection: keep-alive10:34:05.449250 < Expires: Thu, 20 Jul 2017 00:34:05 GMT10:34:05.449290 < Cache-Control: max-age=15768000010:34:05.449331 < Accept-Ranges: bytes10:34:05.449382 < 10:34:05.449440 { [data not shown]10:34:06.443613 * Connection #0 to host bethesignal.org left intact10:34:06.443714 * Closing connection #0

webpagetest.orgSydney ADSL

webpagetest.orgLos An!eles Fibre

webpagetest.orgLos An!eles Fibre

The Network

Host DNS and web services close to your

primary audience.

(This is one reason why global web sites use CDNs,

particularly for static content.)

The Web Server

Apache

mpm_prefork

mod_php

*.php

shovelling

shovelling

shovelling...����������� ������������������  and����������� ������������������  back����������� ������������������  again!

Apache

mpm_prefork

mod_php

*.png

shovelling

shovelling

shovelling...����������� ������������������  and����������� ������������������  back����������� ������������������  again!

1 process per request

10-100MB per process (or more)

Ri!ht now, web servers around the planet are wastin! !obs of memory

servin! static files.

Try a differentprocess model.

You could use mpm_worker…

MASSIVE PHP FAIL

nginx

1 process per core

request overhead measured in kilobytes

nginx

php-fastcgi

[worker]

*.php

shovelling

shovelling

shovelling...����������� ������������������  and����������� ������������������  back����������� ������������������  again!

nginx

*.pngshovelling

...����������� ������������������  and����������� ������������������  back����������� ������������������  again!

Apache and nginx

Netcraft Surveyto May 2012

PHP

“There are only two hard things in Computing Science: cache

invalidation and naming things.”

- Phil Karlton

It’s turtles allthe way down.

Opcode cachingDon’t let PHP do the same work twice.

APC

APCeverywhere!

WordPress

Object cachingDon’t talk to the database if you don’t have to.

APC or memcachewp-content/object-cache.php

Output or page cachingAvoid PHP entirely…?

WP Super Cache

nginx

*.pngshovelling

...����������� ������������������  and����������� ������������������  back����������� ������������������  again!

Batcache

Reverse proxy cache, such as nginx, Varnish

MySQL

Query (or results) cacheDon’t let MySQL do the same work twice.

Schema, index and behavioural optimisation

Don’t tell MySQL do stupid work in the first place.

Browser

Raw performancevs.

Perception of performance

Measure twice, cut once.

“totes����������� ������������������  insan����������� ������������������  hosting����������� ������������������  guys!”-����������� ������������������  Peter