Skip to main content

How We Optimized WordPress from 4 Seconds to 180 ms

Insight

WordPress performance optimization with FrankenPHP

Your website is slow. And Google has noticed.

WordPress performance isn't about installing a caching plugin and hoping for the best. It's about architecture. The server. The PHP version. The number of plugins. The database. The hosting environment. Everything is connected, and a single bottleneck drags down the rest.

Most WordPress sites we encounter take between 2 and 5 seconds to load. Google recommends under 2.5 seconds for Largest Contentful Paint. Every additional second increases bounce rate by up to 32%. The consequence is tangible: you're losing traffic, rankings, and conversions.

But it doesn't have to be this way. With the right infrastructure and a few structural changes, most WordPress sites can achieve total response times under 200 milliseconds. Here's how.

Why is WordPress slow?

WordPress itself isn't slow. It's the sum of decisions made around WordPress that creates the problem. Some were deliberate. Most were made by the agency that built the site three years ago and never looked back.

Too many plugins

Each plugin adds JavaScript, CSS, and database queries. 20 plugins can mean 400 KB of extra JavaScript and 50+ database queries per page view. Some plugins load their resources on every page, regardless of whether they're actually used there.

We regularly see sites with 25-40 active plugins. Three of them do the same thing. Five haven't been updated in over a year. And two have known security vulnerabilities that nobody has addressed.

Heavy page builders

Elementor, WPBakery, and Divi solve a real problem: they let people without coding skills build websites. The problem is the performance penalty.

A typical Elementor page loads 300-500 KB of extra JavaScript and CSS. On every page. Even those that don't use Elementor functionality. Every widget element generates nested HTML that makes the site heavier than necessary. Gutenberg with custom blocks is a better choice for performance.

Shared hosting

You're sharing a server with hundreds of other websites. When a neighbouring site gets a traffic spike, you feel it. The PHP version is often outdated (7.x is still common). And you have no control over the server configuration.

Shared hosting is fine for a hobby blog. For a business website that needs to generate leads and sales, it's indefensible.

Slow database without caching

WordPress's database model (the EAV pattern in wp_postmeta) is flexible but slow at scale. Without object cache, the database does the same work for every single visitor. 100+ queries per page view is common on poorly configured sites.

FrankenPHP: The server that changes the equation

Traditional WordPress hosting uses Apache or Nginx with PHP-FPM. Every time someone visits the site, the server starts PHP from scratch. Loads the WordPress core, all plugins, connects to the database, builds the page, and sends it to the browser. Then does it all over again for the next visitor.

FrankenPHP changes this fundamentally. It's a modern application server built on Caddy. Worker Mode keeps the WordPress application in memory, ready to respond instantly.

The difference in practice:

  • Traditional PHP-FPM: TTFB 200-400 ms (best case). Often 1-4 seconds on shared hosting.
  • FrankenPHP Worker Mode: TTFB under 30 ms. Consistently.

It's not just speed. FrankenPHP provides automatic HTTPS via Let's Encrypt, HTTP/2 and HTTP/3 out of the box, and Early Hints that let the browser start loading resources before the page is fully generated.

Simply by switching from shared hosting to FrankenPHP, we typically see a 90-99% reduction in TTFB. Without changing a single line of code.

Redis: The database that lives in memory

The second most important change after the server switch is Redis Object Cache. Instead of WordPress querying the MySQL database on every single page visit, Redis stores the results in memory.

A site with 127 database queries per page view can be reduced to 8-10 (the rest hit the cache). Shopping carts and sessions are served from Redis instead of slow MySQL. And queue systems for email and ERP synchronization run in the background without affecting performance.

Redis isn't a plugin. It's an infrastructure service that runs alongside WordPress. A caching plugin inside WordPress is a compromise. Redis is the solution.

Plugin cleanup: Fewer, lighter, better

After the infrastructure, we tackle the plugins. The rule is simple: if it can be solved with 50 lines of clean code, that's better than a plugin.

What typically gets removed

  • Caching plugins (unnecessary with Redis and FrankenPHP)
  • SEO plugins that duplicate each other
  • "Optimization" plugins that paradoxically slow things down
  • Inactive plugins that still load code in the background
  • Contact form plugins with 400 KB of JavaScript for a form with three fields

What gets replaced with custom code

We build lightweight WPFluent plugins with MVC architecture. Contact forms, newsletter integration, custom post types, and similar functionality that plugins do halfway but custom code does precisely. Typical size: 10-20 KB. The plugins they replace: 1-3 MB.

The result: JavaScript reduced from over 1 MB to under 350 KB. CSS from 600+ KB to under 150 KB.

Elementor out, Gutenberg in

This part is the most time-consuming but delivers significant impact. Elementor content is migrated to Gutenberg with custom blocks that render clean, semantic HTML.

Custom Gutenberg blocks provide:

  • Clean HTML without nested shortcode spaghetti
  • No Elementor JavaScript framework (300-500 KB saved)
  • Better accessibility (WCAG) because the HTML structure is controlled
  • Faster editor experience in wp-admin
  • Easier maintenance over time

For new projects, we recommend avoiding Elementor entirely. And for projects where WordPress isn't necessary: Sanity + Next.js delivers even better performance without the plugin baggage.

Core Web Vitals: The numbers Google cares about

Google measures user experience through three metrics:

LCP (Largest Contentful Paint): How quickly the main content appears. Google recommends under 2.5 seconds. After optimization: typically 0.8-1.2 seconds.

INP (Interaction to Next Paint): Response time on interaction (click, scroll). Google recommends under 200 ms. After optimization: typically 10-30 ms.

CLS (Cumulative Layout Shift): Visual stability. Google recommends under 0.1. After optimization: typically 0.01.

These three numbers directly impact your rankings. A site with red Core Web Vitals loses traffic to competitors with green ones. This isn't theory — it's confirmed by Google.

How to measure WordPress performance

You don't need to guess. Three free tools give you the answer:

Google PageSpeed Insights: Provides both lab data and field data (from real users). The test takes 30 seconds and tells you exactly what's wrong.

Google Search Console: Shows Core Web Vitals for your entire site over time. The trend is just as important as individual scores.

Query Monitor (WordPress plugin): Shows database queries, hooks, PHP memory usage, and load times per component. Reveals which plugins are actually causing the slowdown.

Run PageSpeed Insights now. If the score is below 70, you have a problem that's costing you money.

What about caching plugins?

WP Super Cache, W3 Total Cache, LiteSpeed Cache. They all promise faster websites. And they deliver. Partially.

A caching plugin stores pre-generated HTML pages and serves them directly without running PHP. That's better than nothing. But it's a band-aid on an architecture problem:

  • The cache must be invalidated on content changes (which often fails)
  • Logged-in users (shopping cart, account pages) don't get cached content
  • The first visit after a cache flush is just as slow as without caching
  • The plugin adds even more complexity to an already complex stack

With FrankenPHP Worker Mode and Redis, you don't need caching plugins. The server is fast enough to generate every page in real time.

Image compression and lazy loading

Images are often the biggest bottleneck in total load time, even when TTFB is fast. A few straightforward measures:

  • Convert to WebP or AVIF (40-60% smaller than JPEG)
  • Use responsive srcset so the browser fetches the right size for the device
  • Lazy-load all images below the fold
  • Compress at 75-85% quality (invisible difference, significant file savings)

A 4 MB JPEG hero image is probably the most common performance mistake we see. Converted to WebP at the right dimensions: 200 KB. Same visual quality.

Version control and CI/CD

Performance optimization is not a one-time effort. New plugins, content changes, and WordPress updates can introduce regressions. Without a pipeline to catch them, performance degrades gradually.

CI/CD with Lighthouse in the pipeline means the build is blocked if performance drops below the threshold. Automated performance testing on every deploy. No regressions make it to production.

When optimization isn't enough

Sometimes the answer isn't to optimize WordPress, but to replace it.

If the site is purely content-driven without e-commerce or heavy integrations, Sanity + Next.js is a better starting point. Static generation delivers sub-100ms load times without caching, plugins, or PHP. And maintenance costs are lower because there are no plugin dependencies to keep updated.

We build Sanity sites from NOK 15,000 with maintenance from NOK 2,500/month.

But if you have a working WordPress site with e-commerce, integrations, and an editorial team that knows the tool? Then modernizing with FrankenPHP, WPFluent, and CI/CD is almost always the right call. Don't migrate for the sake of migrating.

Summary

WordPress performance comes down to five things:

  1. Server: FrankenPHP Worker Mode delivers 90-99% reduction in TTFB. Move away from shared hosting.
  2. Cache: Redis Object Cache eliminates most of the database load. Not a plugin — an infrastructure service.
  3. Plugins: Fewer and lighter. Replace heavy plugins with custom code where it makes sense.
  4. Frontend: Remove Elementor. Use Gutenberg with custom blocks. Compress images.
  5. Pipeline: CI/CD with automated performance testing. No regressions.

Do all five and you go from seconds to milliseconds. Do just points 1 and 2, and you're already ahead of 95% of WordPress sites.

Not sure where to start? Get in touch for a no-obligation performance analysis. We'll tell you what delivers the most impact for your budget.

Frequently asked questions

SB
CG
JB
About us

Is your website slower than it should be?

We run a no-obligation performance analysis and tell you exactly what can be improved.