Page Speed and Performance — How WarmySender stays fast

How WarmySender stays fast — a plain-language tour of how our public pages and the product surface are engineered for Google's Core Web Vitals, and how we keep them fast as the codebase grows.

Why page speed matters for you

Page speed isn't a vanity metric. It is a confirmed Google ranking signal since 2021, with the biggest impact on mobile rankings. Pages in the 'Poor' tier on Google's Core Web Vitals dashboard lose visibility in mobile search results — that means fewer of your prospects find your sales page, comparison pages, and credibility content when they search for tools like WarmySender. It also matters inside the product. Every dashboard load, every campaign-wizard step, every analytics chart, every unified-inbox switch is on the same engineering budget as our marketing pages. When we trim a hundred kilobytes from the entry bundle, that saving compounds across every screen you visit during a working session. Google publishes the formal CWV ranking documentation at developers.google.com/search/docs/appearance/core-web-vitals. The thresholds are simple — and we hold to them across every measured URL on the site.

How fast is WarmySender?

We target Google's 'Good' tier on all three Core Web Vitals metrics. These are field metrics — measured from real browsers on real devices — not lab synthetic numbers. Concretely, our targets are:

LCP (Largest Contentful Paint) — under 2.5 seconds on mobile, under 2.0 seconds on desktop. Measures how fast the biggest above-the-fold element renders. For the marketing pages on WarmySender, that element is the hero headline.

INP (Interaction to Next Paint) — under 200 milliseconds. The worst-case time between a tap or click and the resulting visual update. Replaced FID in March 2024 as the official responsiveness metric.

CLS (Cumulative Layout Shift) — under 0.1. Measures unexpected movement of page elements during load. Images, fonts, and async content are the usual culprits when CLS regresses.

What we did to get there (technical overview)

The biggest wins came not from adding more clever optimizations, but from removing weight from the parts of the site that load first. Four categories of fix:

  1. Bundle splitting. Every below-the-fold marketing section (pricing, testimonials, FAQ, partner logos, etc.) is loaded on demand rather than statically included in the entry bundle. The Vite bundler is configured to emit known-heavy dependencies (animation libraries, Lottie) as named chunks so they get stable filenames and cache reuse across deploys. Our React entry chunk is held under 400 KB.
  1. CSS-first animations. Fade-in, slide-up, and other static reveals use CSS keyframes rather than a JavaScript animation library. CSS animation runs on the compositor thread, doesn't block the main thread during hydration, and ships zero kilobytes of JavaScript. We reserve JS animation for the small number of cases where the design genuinely needs interactive motion.
  1. Font preload. We use the Inter typeface. Rather than load every weight upfront, we preload only the weights actually used above the fold and let the browser stream the rest as needed. Combined with matched fallback metrics, the swap from system font to Inter doesn't shift text — CLS stays well under the 0.1 threshold.
  1. Lazy decorative components. Decorative animations (Lottie pieces, scroll-tracked flourishes, marquee logos) are loaded after the page is already usable. The page renders, becomes interactive, and then the decorative layer streams in. Visitors get to read and click immediately.

How we keep it fast (regression sentinels)

Speed regressions are easy to introduce — a single PR that adds a heavyweight dep to the eager import tree can quietly add 100+ kilobytes to every page load on the site. We catch these before they reach customers with three independent layers of defense:

Layer 1, build-time: Bundle-size gate (npm run perf:bundle-check). Runs on the post-Vite build artifact and fails the build if the entry JavaScript chunk grows past 400 KB. Any PR that accidentally pulls in a heavyweight dependency is caught before it merges — the fix is to lazy-load the component that imports it, or add the dep to the manual chunk configuration.

Layer 2, post-deploy: PageSpeed Insights check (npm run perf:lcp:prod). Runs against the live site after every deploy and asserts the LCP on the most-trafficked URLs stays under the 2.5s mobile target. Uses Google's official PageSpeed Insights API, so the measurement is the same data Google would see when crawling your site.

Layer 3, real-user: [WEB-VITAL] telemetry from real browsers. A 1-in-100 sample of real browsers reports their measured LCP, INP, CLS, FCP, and TTFB back to our logging pipeline. Each line carries the URL, the connection type, and the metric value, so we can see regressions on real devices within minutes — not 28 days from now when Google Search Console would surface the field-data drop.

Where speed shows up in your daily use

Dashboard navigation: jumping between Campaigns, Mailboxes, Warmup, Analytics, Unified Inbox, and LinkedIn shouldn't ever feel like a page reload. We use client-side routing and aggressive prefetch so each subsequent screen is effectively instant after the first paint.

Campaign wizard load: the campaign wizard is one of the most-used surfaces in the product. We keep its bundle lean so opening a draft to edit one line doesn't make you wait for a 2 MB payload. Step transitions stay under 200 ms even on mid-range laptops.

Analytics charts: charts are notorious for ballooning bundle size — we lazy-load the chart library only on screens that actually render charts. Pages that don't need it never pay for it.

Unified inbox: conversation views are virtualized so a folder with thousands of messages opens and scrolls smoothly. Each message body is fetched on demand rather than upfront.

Reporting a slow page

If a specific URL feels slow to you — particularly on a mobile connection — please tell us. We treat performance regressions as bugs. Every confirmed regression gets a new assertion added to our smoke suite so the same class of issue can't silently come back. Email [email protected] with: the URL, your device and connection (e.g., 'iPhone 13 on 4G', 'MacBook on home Wi-Fi'), and a screenshot of the network panel or a PageSpeed Insights report for that URL, if you have one handy.

Back to all documentation | Contact support