Hardt Web Development  ·  SOP Library

Performance
Optimisation

SOP refHWD-SOP-PERFORMANCE
CategoryClient delivery
Applies toEvery new build — run before staging review. Primary host: Kinsta. Alternative: Pressable.
Target90+ mobile PageSpeed on every site, every time
Prepared byCharles Hardt  ·  charleshardt.com
00

Overview & target

Performance is a patient and donor acquisition issue, not a technical nicety.

A 90+ mobile PageSpeed score is achievable on every Kadence site hosted on Kinsta or Pressable. It is not a stretch goal — it is the baseline you deliver on every project. Google has published research showing 53% of mobile visitors abandon a page that takes more than 3 seconds to load. For a medical practice whose site drives patient bookings, a slow site is a direct revenue problem.

Performance optimisation on a Kadence + Kinsta or Pressable stack has four components: hosting-level configuration, WP Rocket caching, image optimisation, and Cloudflare CDN. Each layer addresses different performance bottlenecks. All four must be configured correctly before any site goes to staging review.

Order matters. Configure hosting-level performance settings first, then WP Rocket, then images, then Cloudflare. Configuring them out of order can create conflicts — particularly between WP Rocket's caching and Kinsta or Pressable's built-in server caching.

01

Hosting-level configuration

Kinsta and Pressable both include performance features that must be configured before adding WP Rocket.

Kinsta configuration
PHP version: MyKinsta → Sites → select site → Tools → PHP engine. Set to the highest available stable version (8.2 or 8.3 as of 2026). PHP 8.x is significantly faster than PHP 7.x for WordPress.

Kinsta CDN: MyKinsta → Sites → CDN. Enable Kinsta CDN (powered by Cloudflare) if you are not setting up Cloudflare separately. Kinsta's CDN serves static assets from edge locations globally. If you configure Cloudflare in Section 04, disable Kinsta CDN to avoid double-CDN conflicts.

Edge caching: Enabled by default on Kinsta. No action required.

HTTP/2 push: Enabled automatically on Kinsta. No action required.
Pressable configuration
PHP version: Pressable dashboard → Sites → select site → PHP version. Set to 8.2 or higher.

Jetpack Boost: Pressable includes Jetpack Security on all plans. Jetpack Boost (a separate free plugin) adds Critical CSS generation and image lazy loading. Install Jetpack Boost and enable both features — they contribute meaningfully to mobile PageSpeed on Pressable-hosted sites.

Edge caching: Pressable uses full-page caching at the server level. This functions similarly to Kinsta's edge caching. WP Rocket should be configured to work alongside Pressable's server cache rather than replacing it — see Section 02 for the correct WP Rocket settings.

02

WP Rocket configuration

WP Rocket is the most impactful single plugin for WordPress performance. Every setting matters.

1
Cache settings
WP Rocket → Cache:

  • Enable caching for mobile devices ✓
  • Separate cache files for mobile devices ✓
  • User cache: disable unless the site has logged-in users (members, WooCommerce)
  • Cache lifespan: set to 10 hours (Kinsta and Pressable both handle cache purging at the server level; WP Rocket cache is a secondary layer)
Kinsta note: Kinsta has its own full-page cache that runs independently of WP Rocket. WP Rocket's page caching is somewhat redundant on Kinsta but not harmful. The main value of WP Rocket on Kinsta comes from its minification, lazy loading, and database optimisation features — not page caching.
2
File optimisation
WP Rocket → File Optimization:

  • Minify CSS files ✓
  • Combine CSS files ✓ (test this — can break some themes; disable if layout breaks)
  • Optimize CSS delivery (load CSS asynchronously) ✓
  • Minify JavaScript files ✓
  • Combine JavaScript files: leave disabled by default (high risk of breaking scripts)
  • Load JavaScript deferred ✓
  • Delay JavaScript execution ✓ — this is one of WP Rocket's most impactful CLS and TBT improvements
After enabling these settings, do a full visual test of the staging site — particularly forms, booking embeds, and interactive elements. Some third-party scripts (booking tools, chat widgets) break when deferred.
3
Media settings
WP Rocket → Media:

  • LazyLoad for images ✓
  • LazyLoad for iframes and videos ✓
  • Add missing image dimensions ✓ (reduces CLS)
  • Disable WordPress embeds ✓ (removes bloated WordPress oEmbed JavaScript)
  • Disable emojis ✓
Exception: If the homepage has a hero image that is the LCP element, exclude it from lazy loading. WP Rocket → Media → Excluded images — add the hero image filename or class. Lazy loading the LCP element is a common cause of poor LCP scores.
4
Preload settings
WP Rocket → Preload:

  • Activate preloading ✓
  • Enable link prefetching ✓
  • Preload fonts ✓ — add Google Fonts URL from Kadence
To find the Google Fonts URL: View page source on staging, search for "fonts.googleapis.com", copy the full URL into the WP Rocket preload fonts field.
5
Database optimisation
WP Rocket → Database. Run cleanup immediately after build and before staging review:

  • Post revisions: clean (removes draft revisions accumulated during build)
  • Auto drafts: clean
  • Trashed posts: clean
  • Spam and trashed comments: clean
  • Transients: clean
Enable automatic database cleanup: monthly is appropriate for most client sites. This prevents the database from growing with accumulated post revisions over time.
6
Exclude booking tool scripts from deferral
Booking tool embeds (Jane App, Vagaro, Acuity) use JavaScript that breaks when deferred. WP Rocket → File Optimization → Excluded JavaScript. Add the booking tool script URL or identifier to the exclusion list.

Common exclusions:
jane.app vagaro.com/widgets acuity calendly.com squareup.com stripe.com/v3

03

Image optimisation

Unoptimised images are the single most common cause of poor PageSpeed on small business WordPress sites.

Pre-upload: Squoosh for every image
Before uploading any image to WordPress, run it through Squoosh (squoosh.app — free, browser-based).

Settings:
Format: WebP
Quality: 82 (good balance of quality and file size)
Resize: never upload images larger than they will display. A hero image that displays at 1400px wide does not need to be uploaded at 3000px.

Target file sizes:
Hero images: under 150KB
Service section images: under 80KB
Team photos (headshots): under 40KB
Blog post featured images: under 100KB

A single unoptimised 2MB photo can drop a mobile PageSpeed score by 20+ points. Make Squoosh part of every image upload without exception.
2
Specify image dimensions in Kadence blocks
When adding images in the Kadence block editor, always set explicit width and height attributes. This prevents CLS (layout shift) as the page loads.

In Kadence Image block settings: set the width and height to match the displayed size. In Kadence Row/Section backgrounds: Kadence handles dimensions automatically, but confirm the image is not upscaled from a small source.
3
Set the LCP image to load eagerly
The LCP (Largest Contentful Paint) element is typically the hero image. It must load as a priority — not lazy-loaded. In the Kadence Image block for the hero image, set loading to "eager" rather than "lazy."

In HTML terms this means ensuring the hero image has loading="eager" and ideally a <link rel="preload"> tag in the head. WP Rocket's preload setting handles the preload tag if you add the image URL to the preload list. For the LCP image specifically, adding it to WP Rocket preload is worth the extra configuration step.
4
Audit images after content population
After populating all page content, run a GTmetrix scan on the staging homepage. GTmetrix shows a waterfall chart — look for any images over 200KB. Any image over 200KB on a page that should score 90+ is a problem that needs to be fixed before staging review.

Use the WordPress media library size filter to find large files: Media → Library → filter by file size if your WordPress version supports it, or sort by date and check recent uploads.

04

Cloudflare CDN setup

Free tier is sufficient for all client sites. Do not use Kinsta CDN and Cloudflare simultaneously.

1
When to use Cloudflare vs Kinsta CDN
Use Cloudflare when: The client owns their domain at an independent registrar (Namecheap, GoDaddy, etc.) and you want the additional Cloudflare DDoS protection and analytics.

Use Kinsta CDN when: Simplicity is the priority and the client does not have strong reasons to need Cloudflare specifically. Kinsta CDN is powered by Cloudflare at the infrastructure level — you get the same edge network without managing a separate Cloudflare account.

Pressable + Cloudflare: Pressable includes Jetpack, which already provides CDN for static assets. Adding Cloudflare on top of Pressable is optional but provides additional DDoS protection. Pressable's support recommends using Cloudflare in proxy mode (orange cloud) with their host-specific DNS settings — check Pressable docs for current recommendations.
2
Cloudflare free tier setup
Log into Cloudflare (free account at cloudflare.com). Add site → enter the domain → select Free plan → Cloudflare scans existing DNS records and imports them automatically. Review the imported records for accuracy, then update the nameservers at the domain registrar to Cloudflare's assigned nameservers.

Wait for Cloudflare to confirm the site is active (typically 15–60 minutes). SSL should show as "Active."
3
Cloudflare settings for WordPress
After activation, configure these Cloudflare settings for optimal WordPress performance:

SSL/TLS: Set encryption mode to Full (strict). This requires the origin server (Kinsta or Pressable) to have a valid SSL certificate, which both provide.

Speed → Optimization:
Auto Minify: enable for JavaScript, CSS, HTML ✓
Brotli compression ✓
Rocket Loader: DISABLE — this frequently breaks WordPress JavaScript including booking tools and contact forms.

Caching → Configuration:
Caching level: Standard
Browser Cache TTL: 1 year

Page Rules (optional): Add a page rule for wp-admin and wp-login.php to bypass Cloudflare cache: URL pattern */wp-admin* → Cache Level: Bypass.
4
Add client to Cloudflare account
If managing Cloudflare on behalf of the client, add their email as a member of the Cloudflare account with the appropriate role. Cloudflare → Account → Members → Invite member.

Document the Cloudflare login and account details in the client's Website Handoff Document. If the client is on a maintenance retainer, cache clearing access is needed — include in the handoff document.

05

Kadence theme performance settings

Kadence has built-in performance settings that must be configured alongside WP Rocket.

1
Google Fonts loading method
Appearance → Kadence → General → Typography. For each font set, change the "Load" option from "Default" to "Swap" or "Optional." Font display swap prevents invisible text while the font loads, which directly reduces CLS and improves LCP.

For the performance-obsessed: host Google Fonts locally rather than loading from Google's CDN. Use the OMGF (Optimize My Google Fonts) plugin to download and self-host. This eliminates the Google Fonts connection DNS lookup and improves LCP by 50–150ms on first load.
2
Disable unused Kadence features
Appearance → Kadence → General → Performance. Disable any Kadence Block features you are not using on this site. Each enabled block type loads its associated JavaScript and CSS even if you are not using that block.

Common blocks to disable if unused on a simple medical or nonprofit site: Countdown timer, Progress bar, Lottie animation, Advanced gallery (if not using). Disabling unused blocks reduces the amount of CSS and JavaScript loaded on every page.
3
Preload the LCP image in Kadence
In the Kadence block editor, select the hero row or section. In the Advanced settings for that section, look for the "Loading" or "Priority" option. Set the background image to "Priority" or "Eager" loading.

If the LCP element is a Kadence Image block (not a background): select the block → Advanced → set Fetch Priority to "High." This generates fetchpriority="high" on the img element, which is one of Google's recommended optimisations for LCP improvement.

06

Verification & benchmarking

Run these checks in order after all optimisation steps are complete. Do not skip any.

TestToolTargetWhen to run
Mobile PageSpeedpagespeed.web.dev90+ on homepage and primary service pageAfter all optimisations complete
Desktop PageSpeedpagespeed.web.dev95+ (desktop is always higher)After mobile target is met
LCPPageSpeed InsightsUnder 2.5 secondsIncluded in PageSpeed run
CLSPageSpeed InsightsUnder 0.1Included in PageSpeed run
INPPageSpeed InsightsUnder 200msIncluded in PageSpeed run
TTFBGTmetrixUnder 400ms (Kinsta), under 500ms (Pressable)GTmetrix run after PageSpeed
Waterfall checkGTmetrixNo single resource over 200KBGTmetrix run
Mobile visual checkReal deviceNo layout shift, hero loads immediatelyAfter all optimisations

Record the PageSpeed scores in the client's Handoff Document as the launch baseline. These are used at the 30-day check-in to confirm no performance regression occurred post-launch.


07

Troubleshooting low scores

If the PageSpeed score is below 80 after following this SOP, work through these in order.

SymptomMost likely causeFix
LCP over 4 secondsHero image not preloaded or too largeSet hero image fetch priority to High; confirm image is under 150KB WebP
CLS over 0.15Images without explicit dimensions, or web fonts causing layout shiftAdd width/height to all images; set font-display: swap; exclude LCP image from lazy load
TBT over 300msHeavy JavaScript from a plugin or booking embed loading on the main threadIdentify the offending script in GTmetrix waterfall; add to WP Rocket JavaScript deferral or exclusion list
Render-blocking resourcesCSS or JS loading in <head> before page renderEnable WP Rocket CSS async delivery; check for plugins adding non-deferred scripts
High TTFB (over 800ms)Server response slow — caching not workingConfirm WP Rocket page caching is active; clear Kinsta/Pressable server cache; check for uncached database-heavy queries
Score 90+ on desktop, under 70 mobileLarge images not served at mobile-appropriate sizesEnsure WordPress responsive images are enabled; confirm Kadence responsive image settings; check for fixed-width images that do not resize