My website is a mess. Oh sure, it looks just fine, but it’s all smoke and mirrors. Behind the surface, half the website runs on an older version of Silverstripe, and the other half uses WordPress.
This used to work, but the situation is now critical, because:
- The Silverstripe part has both custom code, and an old no longer updated theme, which makes updating hard
- Changing to a new theme would be double-work because any change on Silverstripe would have to be matched on WordPress. It’s effectively a double-theme change
- The Silverstripe portion is incompatible with PHP 8, so it’s keeping the entire website stuck on PHP 7.4
- Meanwhile, some of my WordPress plugins are already PHP 8 only, and so I can’t update them
- Finally, the entire website is on the slow side
- Static pages load relatively fast, but as soon as you click add to cart or visit a page with dynamic content, the true sluggishness of the server shows…
- This slowness results in higher bounce rates which hurts search engine rankings
- It also causes higher shopping cart abandonment rates
And all this adds up to fewer sales, which is bad for business, and bad for me (I have a family to feed).
As much as I like Silverstripe, I’ve got to get rid of it in order to improve my website and be able to move forward. Will updating to PHP 8.3 boost the website’s performance like I hope? We’ll find out once the conversion is done.
But first, the elephant in the room: how did I end up with such a two-faced frankensteinian mess in the first place?
Why Was My Website A Silverstripe/WordPress Hybrid?
Back in late 2011, I chose Silverstripe for my newly formed company’s website. Why? Because I had a friend who worked for Silverstripe, and I thought it looked great. Not the best reason, but hey, decision made…
Initially, everything looked good. I got the website up and running, and eventually opened my store using Silverstripe’s ecommerce addon. Alas, that was not to last. Silverstripe’s main customers seemed to be mostly government organisations, including the DNC’s website when President Obama was running for office.
Governments have no need for ecommerce modules, because they just take your money straight out of your pocket via taxes or inflation. So, the ecommerce module was abandoned. Stupid government, always causing trouble, always getting in the way…
While there were some attempts to create a good ecommerce module for Silverstripe, it became clear to me that they just wouldn’t get enough momemntum to deliver what I needed. In particular, nobody else would integrate with it.
I wanted to connect my shop with my accounting software. Xero provided integrations for WooCommerce, Shopify, BigCommerce, etc., but for Silverstripe I’d have to write it myself. Want to connect your store to a Print-On-Demand (POD) provider? Great! They have integrations for WooCommerce, Shopify, BigCommerce, and others. But, not Silverstripe.
The list went on and on. Integrations galore for wooCommerce, Shopify and others, but if you’re using Silverstripe, then you’re on your own. I simply didn’t have the resources to write those integrations myself, or pay someone else to do so.
So, I decided to switch to WooCommerce. However, there was no easy way to convert from Silverstripe to WordPress. So, I took the easy way out. I stuck WordPress in a sub-directory and paid a guy to make it look like the main Silverstripe website.
That worked okay for a while. Just some minor inconveniences. But, trouble was brewing. It’s now reached a critical juncture, where this mess must be cleaned up. That’s what I’m going to do now.
Getting Rid of Silverstripe
I already scouted for tools to do the conversion ahead of time. No 100% automated tool exists. The best possible tool I could find was a plugin called WP Scraper. It can scrape pages of a website and import them into your website. I’d still have to do some manual rework, but it should save me a lot of time as I convert 221 blog posts and 30-40 pages.
After some experimentation I decided to go for it. And, the scraper totally ruined the formatting of source-code blocks in my blog. This is a highly technical blog, so having source-code block formatting destroyed was unacceptable.
I tried copying and pasting those, but that was clearly going to waste a huge amount of time, and also be error prone. The core problem was that the scraper was removing newline characters, which usually don’t matter, but are critical for content in pre-formatted blocks.
So, I hacked the WP Scraper code to disable it. While I was at it, I made a few other tweaks to minimise the rework I had to do, including adding code to automatically fetch the blog post date. There will still be some rework, but it’s a huge step up from manual copy and paste.
With that done, I was ready to do the conversion for real.
First, a full backup just in case something goes seriously wrong. After that, I updated the blog post permalink URL structure to match the original blog. That way the blog post URLs will remain unchanged.
Next, I created the root blog page, but kept it private. I don’t want it visible until the conversion is done.
Now I could finally start migrating blog posts. I start with a batch size of 10. I have to tell the scraper where it can find the title, content, category, tags, etc., and then I let it do its thing, followed by manually checking and fixing any problems.
Looking good, but a batch size of 10 is a bit slow. So, I increased it to 20 by changing the original blog’s pagination. From here it’s rinse and repeat until all blog posts and pages are converted.
Alight! I have all of the blog posts and pages converted. Now I want the images to be imported into WordPress’ media library.
Next I needed to import the images into WordPress’ media library. I had disabled WP Scraper’s image import code because the new blog is wider, and I wanted to use the original images instead of the rescaled ones. Now, I need to import the images into WordPress. And for that, I use the Auto Image Upload plugin. This plugin doesn’t import images on the same domain, so I tweak the code (yet again) to import any images that are stored within Silverstripe’s assets directory.
The basic conversion is now done! But I felt that the converted site looked a little ugly. So, I installed a new theme, and set about customizing it. This included copying some customizations from the old child theme into the new one.
I recreated the menus, which were previously baked directly into the child-theme’s templates. Now that everything is in WordPress, it makes sense to use its menu builder.
After that, I had a whole set of redirections to recreate. These redirections sent traffic from easy to enter URLs to the actual URLs (that are a lot harder to type out).
After a few more theme customizations it’s once again time to create a full backup
Now for the big moment, switching from the old site to the new! At this point Silverstripe was still running. Time to remove it, and put WordPress at the domain root.
To do this I need to copy WordPress from its /store/ subdirectory to the root. This was done using an ssh terminal because moving it via FTP would be a download and upload operation, which would be very very slow.
Next, I transferred the domains over to the new application, and… disaster. The website wasn’t working. After some trouble-shooting I got it up and running again
So I published the blog posts and pages, and fixed the store’s permalinks to that the shop part of the site remains at /store/. Next, I had to reconnect payment gateways, Zapier and adjust Zapier’s API callback URLS. After this, I added more redirects to map old URLs to the new page locations.
At this point I thought I would be finished, but no. The images on all my sales funnels and Kea Campus pages were broken, and I didn’t know why.
After metaphorically tearing my hair out for a while, I discovered that OptimizePress has a “special” way of storing its page data that bypassed my previous image URL migration process. So, I installed their OpHelper3, and it failed…
Or did it? After some rounds of cache flushing the images finally appeared, and I could go to bed in the early hours of the morning. Exhausted, but happy that the conversion was done
Results
So, how did I do? Is the website faster? Did I achieve my goals? Let’s take a look…
Yes, Silverstripe is gone, and the website is fully functional. The conversion to WordPress only is done. So I can tick off that goal.
The website is updated to PHP 8.3; another success.
As for the performance boost, let’s look at the data:
- The blog post loading went from ~3.7s down to 0.96s. Awesome!
- The store page went from 1.3s to 1.25s. So almost no change. Disappointing
- Add to cart went from ~2 to ~2.15s. Slightly worse, but roughly the same
- Reloading the cart page went from ~2.9s to ~2.8s. No change there
- The checkout page went from 8.8s to be fully done to 7.7s, so better, but still horrible
- The Kea Campus home went from taking 8.7s to up to 9.4s. Really bad
The ultimate incriminating evidence, is that Google’s Core Web Vitals report now says that all my pages need improvement on desktop machine, and a larger number are now considered poor on mobile.
That’s disappointing. Really, really disappointing. What happened to PHP 8’s amazing new JIT compiler that I’d been told achieves large performance gains?
It turns out that PHP 8’s JIT is disabled by default due to teething issues. I asked my hosting provider to enable it, and… no big change. It delivered a slight improvement, but not the big performance boost that I was hoping for.
I think the big problem is that the underlying Apache server is rather slow. Caching can hide this for static sites, but it’s of no use for dynamic pages like an e-commerce store, or forums. That, and there are some evil douche-bag bots continually wasting server resources by trying to brute-force hack user accounts on the website.
I’ve also noticed periodic high server loads that slow the website down even further, something’s not right. It’s running on a 2 core server which I think should be okay for a website with of this size and traffic. I shouldn’t need an expensive high-end server at this stage.
Conclusions
On the bright side, I now have a nicer looking WordPress only website, which makes moving forward easier. However, this is NOT over, because the website is still too slow. I did NOT get the performance boost that I wanted.
There are a few things I could try. Perhaps a better caching plugin might help, but that won’t fix the underlying slow server.
I may have to switch to a different server altogether. I’ve heard good things about LightSpeed.
Either way, this is to be continued…