Stack: WordPress · Porto child theme · WooCommerce · 50+ active plugins
Engagement: Performance and SEO refresh — no platform migration

What we were asked to do
57Cards.com is a working e-commerce site with years of content, a thousand-plus product variants, real customer accounts, and an active order pipeline. The owner didn’t want a rebuild. He wanted modern performance and a refreshed front-end without throwing away a stack that was working — just slower than it should be.
This is the situation most established WordPress sites land in eventually. A premium theme bundled with a page builder, a payment plugin here, a security plugin there, three commercial plugins for things the theme already does, and over time the site is shipping seventy-plus render-blocking assets to render a homepage. The instinct is “we need to redo this.” The right move, almost always, is surgical.
What changed
| Metric | Before | After |
|---|---|---|
| Mobile Performance | 61 | 72 |
| Desktop Performance | 72 | 96 |
| SEO | 100 | 100 |
| Mobile LCP | 7.2s | 5.1s |
| Render-blocking requests (homepage) | ~71 | ~38 |
About four hours of investigation, implementation, four PageSpeed measurement rounds, and production deploys. No theme rewrite. No new plugins. The same content, the same admin, the same SEO history.
What we actually did
1. Conditional asset enqueue, per page
WordPress’s biggest performance liability is global plugin enqueue: every plugin loads its CSS and JS on every page, “just in case.” We built seven conditional templates — homepage, about, games, FAQ, care, blog, single product, shop archive — and gave each one a dedicated *-enqueue.php file that runs at priority 9999, after Porto, WPBakery, and Slider Revolution have finished registering, and dequeues anything that isn’t relevant.
A single dequeue file (perf-dequeue.php) strips ~40-50 render-blocking requests from the homepage alone:
- WPBakery Page Builder front-end — we render with our own templates
- Slider Revolution — not used outside the legacy homepage
- WooCommerce front-end bundle on non-shop pages (cart, checkout, fragments, attribution, sourcebuster)
- CleanTalk anti-spam, Mailchimp form CSS, fresh-framework, go_pricing, ShareThis — none present on the page they were loading on
- Stripe Blocks checkout CSS, PayPal smart-button gateway CSS — gated to actual checkout pages
2. Late-stage suppression for plugins that cheat
Some plugins re-enqueue assets after wp_enqueue_scripts is over. WooCommerce Blocks’ Stripe support and Slider Revolution’s global handler both do this during the_content; standard dequeue doesn’t catch them. We added a style_loader_tag filter that runs at print time and drops the <link> tag entirely. Belt and suspenders.
3. Deferred non-critical CSS
For stylesheets we couldn’t fully drop — Porto’s footer styles, contact widget, plugin styles bundled into the theme — we used the media="print" onload="this.media='all'" pattern to fetch them after first paint, with a <noscript> fallback for correctness. The browser stops blocking on them; the user gets pixels sooner.
4. Honest font loading
We trimmed the preloaded font set down to exactly what’s used above the fold: the Porto icon font, Font Awesome solid, Font Awesome brands. We added preconnect hints for fonts.googleapis.com and fonts.gstatic.com so the Playfair Display + Inter request starts earlier. We tried deferring Google Fonts and immediately reverted it when CLS regressed — performance work without measurement is just guessing.
5. Native LCP optimization
The homepage hero is now a real <img fetchpriority="high"> with native srcset and sizes, replacing an earlier <link rel="preload">. This lets the browser prioritize the image directly and lets WP Smush’s CDN rewrite the URL consistently — preload hints don’t always pick up CDN-rewritten URLs, which silently doubles the LCP fetch.
6. The admin side: blocking outbound calls
A separate 57cards-perf plugin blocks eight known-slow outbound HTTP calls during wp-admin requests, identified via Query Monitor. The worst offenders were Porto’s license check (60-second timeout), WPMUDEV Hub analytics (15s), and fresh-framework’s plain-HTTP phone-home over three retries — about thirty seconds of cumulative dashboard hang. Editors get a snappy admin without losing license functionality; those endpoints are the banner endpoints, not the update endpoints.
7. Surgical fixes for the side effects
Aggressive dequeue creates new bugs. When we stripped porto-header-shop CSS on non-shop pages, the always-visible mini-cart icon broke because the display:block rule for .minicart-icon lived in that file. The fix wasn’t to re-enqueue 20 KB of CSS — it was to inline the ~600 bytes of layout rules the cart icon actually needs. Net: still saving 95 percent of the bytes, no broken pixels.
The philosophy
You can ship modern performance from an aging WordPress install. You don’t need a rebuild, you don’t need a framework migration, you don’t need to throw away a working WooCommerce store and the SEO history that’s tied to it. What you need is:
- A real measurement loop (Lighthouse, Query Monitor, Web Vitals) to find the actual costs
- Conditional, scoped enqueue instead of global plugin sprawl
- Inline critical CSS for what’s above the fold; defer or drop the rest
- A willingness to write 600 bytes of CSS instead of accepting 20 KB
- Discipline about what you remove, with a verification step on the live site every time
This is how we keep proven WordPress sites fast, modern, and intact — without the rebuild.