Best practices-wordpress-enterprise

59
Best Practices for WordPress in Enterprise

Transcript of Best practices-wordpress-enterprise

Page 1: Best practices-wordpress-enterprise

Best Practices for WordPress in Enterprise

Page 2: Best practices-wordpress-enterprise

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

Page 3: Best practices-wordpress-enterprise

10up is hiring!@tlovett12

[email protected]

Page 4: Best practices-wordpress-enterprise

The world’s leading CMS for websites.

24% 66M sites

58.7% of all CMS’s

http://w3techs.com/technologies/overview/content_management/all

Page 5: Best practices-wordpress-enterprise

What is enterprise?

Page 6: Best practices-wordpress-enterprise

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 PA G E V I E W S P E R D AY

Page 7: Best practices-wordpress-enterprise

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

Page 8: Best practices-wordpress-enterprise

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

Page 9: Best practices-wordpress-enterprise

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 ATA

Page 10: Best practices-wordpress-enterprise

W E B S I T E S I N V O LV I N G

M A N Y C O M P L E X I N T E G R AT I O N S

Page 11: Best practices-wordpress-enterprise

L A R G E O R G A N I Z AT 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 AT 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 TA I N A B L E , H I G H LY AVA I L A B L E , D ATA - C E N T I C , A N D S C A L A B L E

Page 12: Best practices-wordpress-enterprise
Page 13: Best practices-wordpress-enterprise

https://10up.github.io/Engineering-Best-Practices/

Page 14: Best practices-wordpress-enterprise

C A C H I N G

Page 15: Best practices-wordpress-enterprise

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/

Page 16: Best practices-wordpress-enterprise

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/

Page 17: Best practices-wordpress-enterprise

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

Page 18: Best practices-wordpress-enterprise

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

Page 19: Best practices-wordpress-enterprise

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.)

Page 20: Best practices-wordpress-enterprise

admin-ajax.php

• Admin-ajax.php is for admin use only. It is not cached as aggressively as the front end. Page caching will not work.

Page 21: Best practices-wordpress-enterprise

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.

Page 22: Best practices-wordpress-enterprise

D ATA B A S E R E A D S A N D W R I T E S

Page 23: Best practices-wordpress-enterprise

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.

Page 24: Best practices-wordpress-enterprise

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.

Page 25: Best practices-wordpress-enterprise

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.

Page 26: Best practices-wordpress-enterprise

Understand WP Query Parameters

new WP_Query( array( 'no_found_rows' => true, 'fields' => 'ids', 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'posts_per_page' => 100, ) );

Page 27: Best practices-wordpress-enterprise

Autoloading Options

• add_option() takes a 3rd parameter $autoload.

• If you don’t need an option on every request, specify false for $autoload.

Page 28: Best practices-wordpress-enterprise

Autoloading Options

if ( ! add_option( 'option_name', 'some_value', '', 'no' ) ) { update_option( 'option_name', 'some_value' ); }

Page 29: Best practices-wordpress-enterprise

B R O W S E R P E R F O R M A N C E

Page 30: Best practices-wordpress-enterprise

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.

Page 31: Best practices-wordpress-enterprise

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?

Page 32: Best practices-wordpress-enterprise

M A I N TA I N A B I L I T Y A N D S TA B I L I T Y

Page 33: Best practices-wordpress-enterprise

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).

Page 34: Best practices-wordpress-enterprise

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.

Page 35: Best practices-wordpress-enterprise

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.

Page 36: Best practices-wordpress-enterprise

Modern JS Design Patterns

• CommonJS

• ES6-7

• Write modular code with tools like Webpack and Browserify

Page 37: Best practices-wordpress-enterprise

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.

Page 38: Best practices-wordpress-enterprise

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/

Page 39: Best practices-wordpress-enterprise

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.

Page 40: Best practices-wordpress-enterprise

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

Page 41: Best practices-wordpress-enterprise

S E C U R I T Y

Page 42: Best practices-wordpress-enterprise

Clean Input

• Validate/sanitize data being inserted into the database to strip anything harmful.

Page 43: Best practices-wordpress-enterprise

Clean Input

if ( ! empty( $_POST['option'] ) ) { update_post_meta( $post_id, 'option_key', true ); } else { delete_post_meta( $post_id, 'option_key' ); }

update_post_meta( $post_id, 'key_name', sanitize_text_field( $_POST['description'] ) );

Page 44: Best practices-wordpress-enterprise

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

Page 45: Best practices-wordpress-enterprise

Secure Output

<section> <?php esc_html_e( get_post_meta( get_the_ID(), 'key_name', true ) ); ?> </section>

<section class="<?php esc_attr_e( get_post_meta( get_the_ID(), 'key_name', true ) ); ?>"> ... </section>

Page 46: Best practices-wordpress-enterprise

innerHTML and jQuery Selectors

• Don’t insert arbitrary data into innerHTML or jQuery selectors.

Page 47: Best practices-wordpress-enterprise

innerHTML and jQuery Selectors

document.getElementsByClassName( 'class-name' )[0].innerText = textString;

var node = document.createElement( 'div' ); node.innerText = textString; document.getElementsByClassName( 'class-name' )[0].appendChild( node );

jQuery( '.class-name-' + parseInt( index ) );

Page 48: Best practices-wordpress-enterprise

Nonces

• Ensure intent of important actions (database modifications) by associating them with a nonce

• wp_create_nonce(), wp_verify_nonce(), wp_nonce_field()

Page 49: Best practices-wordpress-enterprise

Nonces

<form> <?php wp_nonce_field( 'prefix-form-action', 'nonce_field' ); ?> ... </form>

if ( empty( $_POST['nonce_field'] || wp_verify_nonce( $_POST['nonce_field'], 'prefix-form-action' ) { return false; }

Page 50: Best practices-wordpress-enterprise

Limit Login Attempts

• Limit max number of login attempts to prevent password guessing.

Page 51: Best practices-wordpress-enterprise

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.

Page 52: Best practices-wordpress-enterprise

T H I R D PA R T Y C O D E

Page 53: Best practices-wordpress-enterprise

Review Every Line of Code

Over 40,000 community plugins• Plugins reviewed before submission

• Plugin revisions not reviewed

• Review guidelines not geared for enterprise

Page 54: Best practices-wordpress-enterprise

Review Every Line of Code

Thousands of community themes• More stringent review guidelines than

plugins

• Review guidelines not geared for enterprise

• Performance not measured

Page 55: Best practices-wordpress-enterprise

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.

Page 56: Best practices-wordpress-enterprise

T E A M S

Page 57: Best practices-wordpress-enterprise

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/

Page 58: Best practices-wordpress-enterprise

Internal Code Reviews

• Code reviews help ensure performance, security, maintainability, and scalability

• Engineers improve skills by reviewing and receiving reviews.

Page 59: Best practices-wordpress-enterprise

Q U E S T I O N S ?

@ T L O V E T T 1 2TAY L O R . L O V E T T @ 1 0 U P. C O MTAY L O R L O V E T T. C O M