Caching Small Big Things

A presentation at WordCamp Switzerland 2014 in May 2014 in Zürich, Switzerland by Andrey Savchenko

Slide 1

Slide 1

Slide 2

Slide 2

2 Andrey “Rarst” Savchenko • Rarst.net ♦ WPSE ( s.tk/wp ) • QueryPosts.com • Composer.Rarst.net

Slide 3

Slide 3

Caching

Slide 4

Slide 4

Slide 5

Slide 5

5 Rarst.net load time • 2.0s median • 4.3s average

Slide 6

Slide 6

Apdex ( satisfied + tolerating / 2 ) / total

Slide 7

Slide 7

7 Rarst.net apdex — 0.87 • 77% satisfied ( <4s ) • 19% tolerating ( <16s ) • 4% frustrated ( >16s )

Slide 8

Slide 8

$€£ What is visit’s potential worth? ( ask aloud — you’ll be surprised ) ¥₽₴

Slide 9

Slide 9

9 Gotchas of full page cache • reuse between pages • resource usage • cold cache • rewrite

Slide 10

Slide 10

10 HTTP Cache 304 Not Modified • serve page when necessary • browser & proxy cache centric symfony.com/doc/2.4/book/http_cache.html

Slide 11

Slide 11

11 Edge Side Includes ( ESI ) <esi:include src="http://example.com/1.html" /> • dynamic web content assembly • high reuse between pages w3.org/TR/esi-lang

Slide 12

Slide 12

12 Fragment cache • independent cache of page parts • high reuse between pages + async updates / serving stale

Slide 13

Slide 13

13 Gotchas of fragment cache • anonymizing • invalidation • context • locking

Slide 14

Slide 14

14 Transients API • storage • persistence • object cache support codex.wordpress.org/Transients_API

Slide 15

Slide 15

15 TLC Transients • wraps Transients API • async updates • safe locking /markjaquith/WP-TLC-Transients

Slide 16

Slide 16

16 Fragment Cache ( the plugin ) • wraps TLC Transients • “framework” plugin • bundled & external handlers /Rarst/fragment-cache

Slide 17

Slide 17

17 Plugin responsibilities • spawn update server • accept handler registrations • expose handlers as services

Slide 18

Slide 18

18 Handler responsibilities • extend base cache class • capture fragments’ data • callback, arguments, and salt

Slide 19

Slide 19

Magic is slow

Slide 20

Slide 20

Slide 21

Slide 21

21 component time menu 9% sidebar 39% gallery 47% content 5%

Slide 22

Slide 22

22 Gallery fragment handler • hijacks [gallery] shortcode • invalidated by: • shortcode arguments • post modification time • post attachments

Slide 23

Slide 23

23 component time menu 16% sidebar 72% gallery 2% content 9%

Slide 24

Slide 24

24 Widget fragment handler • hooks into: • widget_display_callback • widget_update_callback • invalidated by widget instance modified

Slide 25

Slide 25

25 component time menu 59% sidebar 4% gallery 4% content 33%

Slide 26

Slide 26

26 Menu fragment handler • pre_wp_nav_menu — new in 3.9! • epic dirty hack before that: add_filter( 'wp_get_nav_menus', '__return_empty_array' ); • invalidated by any menu modified

Slide 27

Slide 27

27 component time menu 9% sidebar 9% gallery 9% content 73%

Slide 28

Slide 28

28 But how much faster is it? component improvement menu ×19 sidebar ×80 gallery ×97 total w/ content ×19

Slide 29

Slide 29

29 Never just “On” a cache 1. Implement 2. Monitor 3. Profit

Slide 30

Slide 30

30 Thank you for listening! Questions? • @Rarst • The Loop ( s.tk/chat ) Rarst.net/slides/caching