10up open sourced their WordPress Best Practices (PHP, JavaScript, tools, and workflows) in late 2014. As the Director of Web Engineering at 10up, I drove this project and am the lead contributor to the docs. These Best Practices allow developers to build sites that scale, perform, and are secure one sites receiving millions of page views per day. They also standardize development practices in such a way that facilitates team collaboration. This talk will highlight some important parts of the Best Practices and reveal some valuable tips about how we (10up) engineer some of the most complex and most viewed WordPress sites in the world.
2. Who Am I?
• My name is Taylor Lovett
• Director of Web Engineering at 10up
• WordPress plugin creator and core contributor
• Open source community member
@tlovett12
6. W E B S I T E S R E C E I V I N G
M I L L I O N S O F
P A G E V I E W S P E R D A Y
7. W E B S I T E S P R O D U C I N G
H I G H D O L L A R
R E V E N U E S
8. W E B S I T E S W O R K E D O N B Y
L A R G E T E A M S
9. W E B S I T E S P R O V I D I N G
C R I T I C A L T I M E
S E N S I T I V E D A T A
10. W E B S I T E S I N V O L V I N G
M A N Y C O M P L E X
I N T E G R A T I O N S
11. L A R G E O R G A N I Z A T I O N S A N D H I G H
D O L L A R B U S I N E S S O B J E C T I V E S
R E Q U I R E W E B S I T E S T H A T A R E
P E R F O R M A N T , E F F I C I E N T , S E C U R E ,
M A I N T A I N A B L E , H I G H L Y A V A I L A B L E ,
D A T A - C E N T I C , A N D S C A L A B L E
15. Redis as a Persistent
Object Cache
• WP lets you drop in a custom object cache.
• Redis lets you store things in memory for fast
read/writes
• Redis offers built in failover features that make it
easier to scale than Memcached
https://wordpress.org/plugins/wp-redis/
16. Page Caching
• Page caching is the act of caching entire
rendered HTML pages.
• Pages can be stored in the object cache avoiding
database queries entirely
https://wordpress.org/plugins/batcache/
17. Fragment Caching
• All output involving a database read on the front
end should be fragment cached aside from the
main WP query.
• For example, generated HTML from a feature
post carousel should be cached since it uses a
WP_Query
18. Remote Calls
• Remote blocking calls can be a huge
performance bottleneck
• Cache remote calls as long as possible
• Utilize non-blocking remote requests wherever
possible
19. Prime Cache
Asynchronously
• Don’t make the user wait for a cache to be
primed.
• Re-prime after invalidation
• Cleverly prime cached data asynchronously
(cron, non-blocking AJAX, etc.)
21. Off the Shelf Caching
Plugins
• Can be difficult to install and even more difficult to
remove.
• Created for the general public and often bloated
with features.
• Keep it simple.
23. Avoid Front End Writes
• Database writes are slow
• Avoid race conditions
• Page caching makes them unreliable.
• If you really need to write data on the front end,
use AJAX.
24. Understand WP_Query
Parameters
• 'no_found_rows' => true: Tells WordPress not to pass
SQL_CALC_FOUND_ROWS to the database query.
• 'update_post_meta_cache' => false: useful when
post meta will not be utilized.
• 'update_post_term_cache' => false: useful when
taxonomy terms will not be utilized.
• 'fields' => 'ids': useful when only the post IDs are
needed (less typical). Avoids lots of extra preparation.
25. Understand WP Query
Parameters
• ‘posts_per_page’ => ‘…’: Sets the query limit to
something other than -1
• ‘post__not_in’: Tells MySQL to run a NOT IN
query which is inherently slow. Try to avoid.
30. Use a CDN
• CDN’s enable you to serve static assets from
servers closer to your visitors while reducing load
on your web server(s).
• CDN recommendation is very unique to each
project.
31. Reduce the Number and Size of
HTTP Requests
• Minify JS and CSS files (we use Grunt)
• Concatenate JS and CSS files (we use Grunt)
• Optimize images
• HTTP 2?
32. M A I N T A I N A B I L I T Y
A N D S T A B I L I T Y
33. Maintainable Code Improves
Stability
• Easily maintainable and extendible code bases
are less susceptible to bugs.
• Bugs in maintainable code are solved quicker
• New features are more easily created in
maintainable code.
• Happy engineers are more productive (often
overlooked).
34. Modern PHP Design
Patterns
• WordPress core is backwards compatible with
PHP 5.2.4.
• Enterprise websites aren’t (usually) constrained
by incredibly outdated software
• Namespaces, traits, composer, etc.
35. Don’t Obsess Over
MVC PHP
• MVC (model, view, and controller) is a great
pattern in many situations.
• WordPress is inherently not object oriented. We
find that forcing MVC with tools like Twig
ultimately leads to more confusing code that is
harder to maintain.
37. Feature Plugins
• Group distinct pieces of functionality into plugins
as much as possible.
• This separation simplifies deployments and
enables you to reuse functionality on other
projects.
38. Documentation
• Properly documented code is more quickly fixed and
iterated upon
• Make documentation a part of your code review process
• PHP Documentation Standards:
https://make.wordpress.org/core/handbook/best-
practices/inline-documentation-standards/php/
• JS Documentation Standards:
https://make.wordpress.org/core/handbook/best-
practices/inline-documentation-standards/javascript/
39. Wrapping Wrappers
• WordPress has a very rich, easy to use API with
ways to create posts, send HTTP requests,
create metaboxes, etc.
• Creating wrappers around these core APIs more
often than not just results in a layer of confusing
code and another library to memorize.
40. Write Tests
• PHPUnit for PHP
• Core unit testing framework and WP Mock -
https://github.com/10up/wp_mock
• Mocha for JavaScript
• Tests improve quality and stability through
identification of issues. Decrease regression
44. Secure Output
• Escape data that is printed to the screen
• Escape data as late as possible
• Check out the esc_* functions in the codex.
https://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Data
47. innerHTML and jQuery
Selectors
document.getElementsByClassName( 'class-name' )[0].i
var node = document.createElement( 'div' );
node.innerText = textString;
document.getElementsByClassName( 'class-name' )[0].ap
jQuery( '.class-name-' + parseInt( index ) );
48. Nonces
• Ensure intent of important actions (database
modifications) by associating them with a nonce
• wp_create_nonce(), wp_verify_nonce(),
wp_nonce_field()
51. Require Strong
Passwords
• Weak passwords are one of the most common
ways attackers exploit websites.
• Require your users create strong passwords.
There are a few great plugins that do this
automatically.
53. Review Every Line of
Code
Over 40,000 community plugins
• Plugins reviewed before submission
• Plugin revisions not reviewed
• Review guidelines not geared for
enterprise
54. Review Every Line of
Code
Thousands of community themes
• More stringent review guidelines than plugins
• Review guidelines not geared for enterprise
• Performance not measured
55. Understand Your
Librarys
• jQuery, Underscores, etc. are helpful tools but
should not be used blindly. There is no substitute
for a solid understand of JavaScript.
• Encouraging engineers to understand the
libraries they are using will improve overall code
quality and decrease bugs.
57. Workflows
• Keeping track of code history with version control
is critical.
• Mandate workflow at the start of project to keep
everyone on the same page.
• Use descriptive commit messages
• Gitflow: http://nvie.com/posts/a-successful-git-
branching-model/
58. Internal Code Reviews
• Code reviews help ensure performance, security,
maintainability, and scalability
• Engineers improve skills by reviewing and
receiving reviews.
59. Q U E S T I O N S ?
@ T L O V E T T 1 2
T A Y L O R . L O V E T T @ 1 0 U P . C O M
T A Y L O R L O V E T T . C O M