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.
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.
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.
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.
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.
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.
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.
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
★
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.
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.
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.
| Test | Tool | Target | When to run |
| Mobile PageSpeed | pagespeed.web.dev | 90+ on homepage and primary service page | After all optimisations complete |
| Desktop PageSpeed | pagespeed.web.dev | 95+ (desktop is always higher) | After mobile target is met |
| LCP | PageSpeed Insights | Under 2.5 seconds | Included in PageSpeed run |
| CLS | PageSpeed Insights | Under 0.1 | Included in PageSpeed run |
| INP | PageSpeed Insights | Under 200ms | Included in PageSpeed run |
| TTFB | GTmetrix | Under 400ms (Kinsta), under 500ms (Pressable) | GTmetrix run after PageSpeed |
| Waterfall check | GTmetrix | No single resource over 200KB | GTmetrix run |
| Mobile visual check | Real device | No layout shift, hero loads immediately | After 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.
| Symptom | Most likely cause | Fix |
| LCP over 4 seconds | Hero image not preloaded or too large | Set hero image fetch priority to High; confirm image is under 150KB WebP |
| CLS over 0.15 | Images without explicit dimensions, or web fonts causing layout shift | Add width/height to all images; set font-display: swap; exclude LCP image from lazy load |
| TBT over 300ms | Heavy JavaScript from a plugin or booking embed loading on the main thread | Identify the offending script in GTmetrix waterfall; add to WP Rocket JavaScript deferral or exclusion list |
| Render-blocking resources | CSS or JS loading in <head> before page render | Enable WP Rocket CSS async delivery; check for plugins adding non-deferred scripts |
| High TTFB (over 800ms) | Server response slow — caching not working | Confirm WP Rocket page caching is active; clear Kinsta/Pressable server cache; check for uncached database-heavy queries |
| Score 90+ on desktop, under 70 mobile | Large images not served at mobile-appropriate sizes | Ensure WordPress responsive images are enabled; confirm Kadence responsive image settings; check for fixed-width images that do not resize |