{"id":1183,"date":"2020-05-28T17:11:45","date_gmt":"2020-05-29T00:11:45","guid":{"rendered":"https:\/\/traverstodd.com\/?p=1183"},"modified":"2020-06-04T12:52:20","modified_gmt":"2020-06-04T19:52:20","slug":"wordpress-missed-schedule-post-refactored-large-site","status":"publish","type":"post","link":"https:\/\/traverstodd.com\/wordpress-missed-schedule-post-refactored-large-site\/","title":{"rendered":"How We Fixed WordPress’ Missed-Schedule Post (by Refactoring a Large WordPress Site)"},"content":{"rendered":"\n

The skinny:<\/strong> We fixed missed-schedule posts by reducing the site’s code landscape, examining the hosting environment, and implemented a three-prong, bulletproof approach to ensuring posts publish on time. In the process we also trimmed megabytes<\/em> of render-blocking CSS and JavaScript, changing the site’s performance measured by Google Lighthouse from 17 to 75<\/strong>. So, that’s nice.<\/p>\n\n\n\n

But first<\/h3>\n\n\n\n

A primer: <\/strong>We generally build WordPress sites that we ourselves have designed, and as part of that we build from scratch. This ensures we know every part of the site is high performance and security solid. <\/p>\n\n\n\n

But we also inherit sites built before us. Often a site is handed our way because there are frustrations or limitations with the prior developers. Either of those scenarios generally mean we’re inheriting a site with code bloat, and by extension technical-debt. <\/p>\n\n\n\n

Inheriting (or creating) code bloat means troubleshooting will be more difficult, and this was particularly true with one major site we maintain. They have an editorial schedule that requires scheduling posts within WordPress, and far too often they would log in to WordPress to see the post didn’t go out at the scheduled time and would be labeled “missed schedule”.<\/p>\n\n\n\n

Having built multiple enterprise, battle-tested healthcare apps in the last few years, we’re generally able to detect and fix problems. But troubleshooting this WordPress ecosystem always presented a big challenge and we were indeed short on definitive answers, which (to state the obvious) is demoralizing to not be able to provide real, actionable answers to a client. In addition, there were sporadic but significant remarks about the site working slowly, which was also hard to pin down. So to help in solving both efforts, we first aimed to trim bloat.<\/p>\n\n\n\n

Ok, but what the heck is the missed-schedule issue in WordPress? <\/h2>\n\n\n\n

It’s complicated.<\/strong> Ideally, you’d schedule your post to go out at 8 am Wednesday on some date, and yet you log into WordPress later to find the label “missed schedule” next to your scheduled post. And even though WordPress knows<\/em> it’s past schedule, it’s still sitting there. Not published. WTH.<\/p>\n\n\n\n

To understand how it works, you have to glimpse the mechanics behind the scenes. Put quickly, despite WordPress being a hugely-sophisticated piece of machinery, it’s ultimately only web software that sits atop a server, and it doesn’t have direct access to what servers call a “cron job” (short for “chronological” or “time-based” job). A cron job<\/a> is just a scheduled task. I can instruct the server to “do this thing every hour of every day<\/em>“, and it’ll do it. It’s really powerful. <\/p>\n\n\n\n

But WordPress doesn’t have server access that deep. So it relies on a pseudo-cron job that isn’t chronologically-based, but “event-based”. What’s the “event”? Someone visits the site. That’s it. <\/p>\n\n\n\n

The Big Event<\/h2>\n\n\n\n

When someone visits the site, that counts as an “event”, and WordPress will be triggered to run through its routines, including performing any scheduled tasks. But…let’s say you scheduled your post at 8 am Wednesday, and your site is low-traffic enough that you didn’t get a visitor until, say, 9 am. Well, WordPress ran through its tasks at 9 am and determined that based on the current time, your post is now behind schedule and labeled as “missed-schedule” instead of deployed. It’s a frustrating and kind of stupid feature.<\/a> <\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

But missed-schedule isn’t just an issue that plagues low-traffic sites. High-traffic sites are troubled as well, just different mechanics. This part of things gets much more nuanced because higher-traffic sites will inherently have more complicated server setups, plugin ecosystems, and other dependencies that can affect server routines. <\/p>\n\n\n\n

To explain the problem we were solving more directly, which was a high-traffic site on an enterprise-level hosting plan with a major Managed-WordPress provider, we need to talk about all these other ecosystem dependencies. <\/p>\n\n\n\n

So is this the reason for the refactor?<\/h2>\n\n\n\n

It is, and that’s an astute observation, so I thank you for that. The site we inherited was based on the parent-child theme pattern in WordPress, which in many cases can mean a lot of extra boilerplate code your client’s business doesn’t need and also which is hurting their SEO. So, to combat that tech-debt, we opted to rid the reliance on a parent theme. <\/p>\n\n\n\n

To be sure, the exercise for refactoring wasn’t academic. There are real-world benefits to trimming any codebase, especially if it affects the code shipped to a browser. Reduce code shipped to a browser and you’ll ostensibly impact SEO in a positive way (with limits, of course. I mean, if your UX is terrible, shipping less code isn’t your problem). <\/p>\n\n\n\n

Refactoring was difficult. For one, the parent theme had a ton of boilerplate CSS and JavaScript, some of which we needed (barely), so we had to extricate it. This is not easy nor fun. Said best by one of the gurus of CSS<\/a> about trimming extraneous CSS:<\/p>\n\n\n\n

Here\u2019s what I\u2019d like you to know upfront: this is a hard problem<\/strong>.<\/p>Chris Coyier<\/a><\/cite><\/blockquote>\n\n\n\n

It was indeed hard. We painstakingly separated the child theme from the parent, bringing over only the parts we needed. Once that was done, we then tackled the plugin ecosystem to rid WordPress of plugins that added little value (or which were determined to be no longer needed because of business rule changes). With that done, it helped us reduce complexity so as to troubleshoot more efficiently. <\/p>\n\n\n\n

But at this point, we’d only trimmed enough to be able to solve the missed-schedule posts issue. The site was still bloated and things like page-load time (and UX and SEO by extension) were still going to suffer if we didn’t remedy the frontend bloat that slows loading and hinders good UX. <\/p>\n\n\n\n

Hang on a sec:<\/strong><\/em> it’s worth noting that we never sought to delay this cleanup effort, nor was our client unwilling to condone this effort. Good businesses are busy. We did what a lot of developer groups do, which is to deal with what you have, make it work, and where possible, fine-tune it and make it better as you go. In this case, we were able to go an extra few steps thanks to a less-demanding sprint. <\/em><\/p>\n\n\n\n

So we examined the CSS and JavaScript dependencies that had been historically loaded into the existing site. This is because CSS and JavaScript are render-blockers. Normally a page downloads all the HTML it needs (including images, JavaScript, and CSS files) and then parses all the CSS and JavaScript to determine how they will impact how the page looks or feels. <\/p>\n\n\n\n

If you have just enough CSS to style the page, parsing will be fast and the user will see the page quickly. Same with JavaScript. Quick parsing means the end-user sees your content quickly. But if you’re dealing with any of the zillions of clock-punching, cavalier web devs out there, it’s common to find they’ve installed 45 WordPress plugins, and in addition, they’re using a ton of extra CSS and JavaScript libraries where maybe 1% of it is needed. They build the site, get paid, and then it’s on to the next disaster someone else will have to clean up.<\/p>\n\n\n\n

In examining the leftover CSS and JavaScript, we found terrible, terrible things. <\/h2>\n\n\n\n
\"\"<\/figure>\n\n\n\n

Warning<\/strong>: if you already understand best UX\/dev practices, what you’re about to read may be horrifying. Viewer discretion is advised. <\/em><\/p>\n\n\n\n

Things like boilerplate.css version.whocares<\/sup><\/strong><\/em> were loaded (hundreds of KB in CSS!), despite in Chrome Devtools you could see the coverage<\/a> was less than 0.5%. It was needless, page-load-hurting waste. And JavaScript payloads were also huge, which is unarguably the most expensive payload you can ship to a browser. Developers for enterprise-level clients can’t just write\/include code that “gets it done”. It has to be necessary and purposeful. Including a bloated-boilerplate CSS file, where 99%+ is unused, is negligent for the singular reason that building websites requires thinking about the end-user’s experience.<\/p>\n\n\n\n

We managed to make some huge reductions in critical JavaScript and CSS, and the impact wasn’t small. We saw page-load times go from 5-8 seconds<\/strong> to more reasonable 1-2 second<\/strong> loads. Here’s a snapshot of before and after for the most expensive resources a browser has to deal with: <\/p>\n\n\n\n

Before<\/h3>\n\n\n\n
\n