WordPress As An Application Framework

A summary of my notes from my SyntaxCon 2017 “WordPress As An Application Framework” presentation.


Constraints of working in and around the WordPress application.

Built-In Overhead

Using any framework adds overhead to your application.  It is the trade-off for rapid development with well-vetted components.   The bigger the framework the more overhead.

WordPress did not originate with the intent to become an application framework.  In addition, Automattic continues to be driven by Matt’s what some would consider an over-zealous desire to maintain backwards compatibility with prior releases of the core product.   Along with those attributes comes some overhead you may not see in other frameworks.

WordPress Heartbeat

The “heartbeat” is one example.   WordPress is configured to fire off a “heartbeat” every 60 seconds.   When the heartbeat process executes it loads the entire WordPress application and runs configured “heartbeat tasks”.   That means all plugins and themes are loaded and executed, often doing nothing.   Depending what you have running on your site that can be a lot of overhead.    Most plugins and themes do not “short circuit” when the heartbeat happens despite the fact that they do not do anything to process or influence “heartbeat tasks”.   That means more overhead do literally do nothing.

On a positive note, one of the advantages of writing your own application on top of WordPress is that you are controlling the environment.  You can craft your own plugins and theme to short circuit if that piece of your app is not doing “heartbeat stuff”.   In the top of most of my plugins you will find the following line which basically says “don’t load up anything else in this plugin when the heartbeat comes in” saving file I/O and server memory.

if ( defined( 'DOING_AJAX' ) && DOING_AJAX && ! empty( $_POST[ 'action' ] ) && ( $_POST['action'] === 'heartbeat' ) ) {



Benefits of having pre-defined libraries and UI components.

Time Savings

Time savings at each phase of development.


Flexibility of WordPress as a foundation.


Extensibility of WordPress both internally and via exposed services.


Scalability of the application.

Some jQuery Foo I Learned While “Leveling Up” This Weekend

I am the first to admit that I got on the JavaScript bandwagon a little late.   I was a bit hesitant because of my work with government projects a half-decade ago.   When you work with the US Government you quickly forget the “best of” when coding web apps and instead use their default protocol of using “the oldest crap possible”.   I would not be surprised if they are still using Internet Explorer 6 as their go-to standard.   For the non-geeks, that is the equivalent of setting the standard vehicle fleet to a Ford Model T.  Sure, it is a car that runs on petroleum but it sure as hell isn’t going to get you and your family ANYWHERE safely.

Just 2 years ago I started adding some JavaScript to my locator web app.    It helped bring my 2013 app up to 2001 web interface standards.  A little.   Then I learned about jQuery, a library of features and functions that does a lot of the heavy lifting for you.   It is like going from sawing your own lumber from trees to going down to the lumber yard and picking up 2x4s to build your home.   Much easier.

The Slightly Newer But Old Way

Then I learned jQuery and many of the pre-built “nice to have frills” come shipped with WordPress Core.  What?!?!  Why do 90% of the plugins and themes, from which I snarf a lot of code to make it look like I know what I’m doing, not know this?    During the past year I’ve been learning a lot of new code tricks from my friends at DevriX and teaching myself more by learning new things like advanced jQuery trickery.

New Themes

So now, way down here after my rambling, are my notes on what I learned about jQuery this weekend where I felt myself “level up” on that particular skill.

As you read these tips you’ll notice that I use jQuery “long form” vs. $ which is common practice. I have a good reason for that; lots of WordPress plugins are poorly written and assign no-conflict mode with the $ shorthand improperly and break my application.  When you have 15,000 installations you tend to do things “long form but less prone to others breaking it”.  When I write jQuery… in my examples you most likely see $ instead in “real world” code.

Cache Your Queries

When you want to work with an element on a page you can use jQuery to help find the element and make your changes.    You tend to see stuff like this:

jQuery( '.dashboard-sidebar' ).addClass( 'expand' );
jQuery( '.dashboard-sidebar' ).attr( 'data-mode','expanded' );

That is not very efficient. This jQuery( <selector> ) reads the entire web page each time and makes a whole lot of JavaScript code run EVERY TIME it is processed UNLESS <selector> is a JavaScript object instead of a string.   Lots of code running = slower web apps.

Instead make jQuery “cache” the objects that it finds the first time around by assigning the selection to a variable.  The “lots of code” runs once in the example here and in the examples below it will create a subset of elements to look through versus your entire web page stack of elements.

var the_dash = jQuery( '.dashboard-sidebar' );
jQuery( the_dash ).addClass( 'expand' );
jQuery( the_dash ).attr( 'data-mode','expanded' );

In this mode jQuery reads the entire web page ONCE and stores the matching objects in the_dash.   It then can quickly modify just those elements at requested.

Extend Your Cached Queries

Now that you are caching your queries and making your site visitor’s laptop or mobile device work a lot less , which believe it or not can extend their battery life by a whole microsecond, you can extend those caches without doing the “whole read the page thing” again.

Here is how I used to find the sidebar, modify it, then find all the images in the sidebar and hide them:

if ( is_now === '350px' ) {
    jQuery('.dashboard-aside-secondary').css('flex-basis', '10px');
    jQuery('.dashboard-aside-secondary > IMG').attr( 'style' , 'border:solid 1px red' );
} else {
    jQuery('.dashboard-aside-secondary').css('flex-basis', '350px');

Nice short code which is a little easier, maybe, to read, but this is horribly inefficient in the “350px” mode.   In this mode JavaScript is reading the entire web page, seeking the sidebar, and changing it.   Then it goes and reads the entire web page again, finds the sidebar, then reads everything in the sidebar and finds the images and changes them.    That is a lot of JavaScript code executing.  Executing code takes time. Time is money as they say.

And here is the far more efficient version:

var help_sidebar = jQuery('.dashboard-aside-secondary');
if ( is_now === '350px' ) {
    jQuery(help_sidebar).css('flex-basis', '10px');
    jQuery(help_sidebar).find( 'IMG' ).attr( 'style' , 'border:solid 1px red' );
} else {
    jQuery(help_sidebar).css('flex-basis', '350px');

In this mode it reads the entire page once, and keeps track of what it found in “help_sidebar”.   It then changes what it found without searching again because jQuery is working on help_sidebar which is an object.  If that were all we were doing with it  this would actually be a bit slower since we take the overhead of storing the object with an assigned memory pointer (variable assignment) as noted above.

However when we do the second “change all the images inside that object” we gain back that lost microsecond one-hundred fold.     The second jQuery(help_images)… that is used to modify the image within no longer has to search the entire web page.

BUT… there was a problem.    How do you add “extended selectors” to the cached jQuery?

Above we had ‘.dashboard-aside-secondary > IMG’  to find our images.  This is MORE than just the ‘.dashboard-aside-secondary‘ that we stored in our cache.    Uggh.

Find() To The Rescue

Luckily jQuery has a number of methods that extend your selectors and help you traverse the DOM.  You can find this under the Traversing jQuery docs page.

find() can take any selector or OBJECT, like the one we have containing our sidebar, and then look for any elements inside of it.   As a jQuery padawan I had only ever seen this used to find stuff within the entire DOM.   Being a slow-learner it never dawned on me that this could be extended to ANY part of the DOM not just the entire DOM.

jQuery(help_sidebar).find(‘IMG’) looks within the sidebar only to find images.  This is far faster than reading the entire page.   It then changes those images within.

Children() Is One Level of Find()

One of the incorrect paths I went down, but is very useful to know, is the use of children() in jQuery.    This finds only the matching elements just one level deep in the object stack.   Since you’ve read this far you are a code geek like me so I know that you understand that most web pages are many levels of nested elements and often you want something “deeper down” where you need your great-great-great grandson to be involved.    However there are plenty of cases where I can utilize children() to impact just the next level of menu divs, for example.


Truly understanding how jQuery selectors and “caching”works and how to modify those cached selections with the jQuery traversal methods is going to bring the efficiency of my apps up to a whole new level.    It may only save a half-second of processing time per page interaction, but it all adds up when you have 15,000 websites hosting millions of page views every day.

For my fellow code geeks out there I hope you learned something new and I’ve given you a shortcut to reaching the next level of your jQuery skill.s

Sidebar: Why “caching” in quotes? Because this doesn’t seem like caching to me but rather object-passing, but maybe I’m missing something I’ll learn at level 3.

Selling On eBay? Be Prepared To Pay A Hefty Surcharge

eBay has been the go-to listing service for anyone wanting to get rid of used and unwanted items for over a decade.    I started listing with them in their second year of existence.  Over the past decade I’ve sold over 1,000 items.   This month is likely the last month I’ll be doing that.

I decided to clear out some older items that I no longer use.   Doing so around the holiday season makes for quick sales on eBay and makes room for any new items that are coming next week.    I listed a dozen items on eBay and many sold within a week.

Then the bill came.

Nearly 35% of what I earned went back to eBay.   Where people used to game the system by selling items for a low cost and then charge outrageous shipping to avoid paying eBay fees, eBay is now using that VERY SAME TACTIC to milk your listings for additional fees.

In fact eBay has gotten so good generating revenue here and hiding it from casual users, like myself, that it should be considered false advertising.  At the very least it is very bad customer service.

Case In Point

I listed a $20 computer accessory on eBay.   They tout there “Free Listing” all over the place.   Nice!    I list for free until it sells.   When it does sell I only pay their relatively minor commission, around 10% of the selling price.  Not bad.

They even help me figure out what my shipping fee should be;  just put in the weight and they will calculate how much to charge the buyer based on where they live.

A buyer snags a great deal just 48 hours after I start the listing.     eBay decides that the shipping fee via FedEx based on the product weight should be $12.   Sounds about right.

Package and ship the item.     Buyer is happy.   All is good.

Then the bill arrives.

That $12 shipping , for which eBay gives me their $1.45 corporate discount? WRONG. 

FedEx charged them $17.  Yes, the original freight was $11.13 per their estimate for a 7 pound item.  The problem is that eBay conveniently leaves out the Fuel Surcharge: $0.65, the DAS surcharge of $3.15, and the residential surcharge of $3.25.  Luckily they did get the $1.45 discount right.    The total damage , which eBay is more than happy to pass along despite THEIR CALCULATOR ERROR, is $16.73 not the $11.13 they first calculated nor the $11.91 they charged the buyer.

That is a $4.83 difference on a $12 line item … a 30% error just on shipping.

Then there are the fees.   The listing is free but the rest sure isn’t.   Yes, eBay needs to earn money and they deserve a commission but let’s break down what is REALLY costs versus the 10% they pretend to offer.

$2.20 for the final value of the item, exactly 10%. Add another $1.69 for 10% of the ACTUAL CHARGE the shipper charged them, NOT the $12 they calculated.

At the end of the day a $22 item with $12 shipping brought in $34 and cost $20.62 all going right back to eBay and the shipping company.

Selling on eBay ends up costing an astounding 60% of the total value of the transaction.

Sadly this is not an isolated case.   Adding up the fees and shipping miscalculations is a huge cost to any seller on eBay.

The worst part of it is that eBay must know this is a problem but why would they change it?

By charging 10% fees on the shipping charge, the more their shipping companies charge the more profit eBay makes.  No reason to work with shipping companies for lower rates!

By making their calculator GROSSLY UNDERESTIMATE SHIPPING FEES they convince buyers to purchase items because it costs them “almost nothing” in shipping costs.   Buyers buy more items, eBay earns more commissions.

By passing through actual shipping costs to the sellers eBay assumes ZERO RISK and passes all the costs of the error on to the sellers.

It is a perfect system.   The sellers pay for all fees associated in selling an item: all the shipping costs, the packing materials, the handling, fuel surcharges, liability in product listing errors, liability in damaged or broken products.   It is a great way to earn millions while doing as little as possible to ensure the software works in anyone’s favor but your own.

As you can probably guess, my next items are being listed on Amazon and Let Go.   Maybe they are not better than eBay when it comes to fees, but they certainly can’t be worse.

%d bloggers like this: