HubSpot CMS gives you a global CDN, HTTP/2, automatic minification and image resizing out of the box. So when a HubSpot site loads slowly, the platform is rarely the cause — the build is. In every audit we run, the same handful of decisions account for most of the delay, and they are all fixable without leaving the portal.
This playbook is the order we work in on a real engagement: measure the right thing first, fix what blocks the first paint, then trim the payload that nobody notices until mobile. It complements our deeper diagnostic write-up on why your HubSpot website is slow and what Core Web Vitals actually measure — that post explains the metrics, this one is the implementation sequence.
Speed is also no longer just a ranking input. Slow pages lose conversions before they lose rankings, and AI crawlers that time out simply do not cite you. That is why performance is bundled into HubSpot technical SEO rather than treated as a separate project.
Step 0: measure the page that matters, on the device that matters
Do not optimise the homepage because it is the one you look at. Pull your top five landing pages by sessions from HubSpot analytics, then test each one in PageSpeed Insights on mobile and record the field data (CrUX) alongside the lab score. Field data is what Google uses; lab data is only a debugging aid.
Write the starting numbers down — Largest Contentful Paint, Interaction to Next Paint, Cumulative Layout Shift and total transferred bytes. Without a baseline you cannot tell whether a change helped or whether you just moved the problem.
One caveat specific to HubSpot: preview URLs and the live domain do not perform identically, because preview skips some CDN caching. Always test the published page on the production domain.
| Metric | Good target | Usual HubSpot culprit |
|---|---|---|
| LCP | Under 2.5s | Uncompressed hero image or a font-blocked headline |
| INP | Under 200ms | Chat widget, tracking scripts, heavy carousel JS |
| CLS | Under 0.1 | Images without width/height, late-loading banners and forms |
| Page weight | Under 1.5MB | Theme CSS/JS loaded on every template plus large PNGs |
1. Fix the image pipeline first — it is usually half the win
HubSpot's file manager will happily serve the 4000px PNG someone uploaded from a design tool. Resize before upload to roughly twice the largest rendered size, export as WebP, and let HubSpot's resizing parameters handle the rest. A hero that drops from 1.8MB to 120KB moves LCP more than any other single change.
Use HubSpot's `resize_image_url` HubL filter or the srcset support in the image module so phones do not download desktop assets. Set explicit width and height attributes on every image — missing dimensions are the most common cause of layout shift on HubSpot templates.
Lazy-load everything below the fold and, critically, do not lazy-load the hero. A lazy-loaded LCP image delays the very metric you are trying to improve. Add `fetchpriority="high"` to the hero instead.
2. Stop shipping the whole theme to every page
Marketplace themes and many custom themes attach one global stylesheet and one global JS bundle to every template, including landing pages that use three modules. HubSpot lets you attach CSS and JS at the template and module level — use it. Move slider, tab and animation code into the modules that need them.
Inside modules, prefer `{% require_css %}` and `{% require_js %}` blocks so assets load once, in the right order, only when that module is on the page. This is the change that usually takes a 900KB render-blocking bundle down to something reasonable.
If you inherited a theme you cannot fully restructure, our HubSpot theme customization work typically starts here: audit which assets each template actually needs, then unbundle.
{% require_css %}
<link rel="stylesheet" href="{{ get_asset_url('../../css/carousel.css') }}">
{% end_require_css %}
{% require_js position="footer" %}
<script src="{{ get_asset_url('../../js/carousel.js') }}" defer></script>
{% end_require_js %}3. Take fonts off the critical path
Three weights of two families, loaded from Google Fonts, will delay your headline by hundreds of milliseconds on a mid-range phone. Cut to the weights you actually use, self-host the files in HubSpot's file manager so they come off the same CDN, and set `font-display: swap` so text paints immediately.
Preload only the single font file used by above-the-fold text. Preloading everything is the same as preloading nothing — you just move the contention.
4. Audit third-party scripts ruthlessly
The fastest HubSpot template in the world still loses to five marketing tags. Chat widgets, heatmaps, A/B tools, two analytics platforms and an old retargeting pixel routinely add 400–800KB of JavaScript that competes with your own code for the main thread — and INP is the metric that suffers.
List every script in the portal's tracking code and each template's head. For each one, name the person who reads its data. Anything without an owner comes off. What survives gets loaded `async` or `defer`, and chat widgets get delayed until first interaction or scroll rather than on load.
This is also where HubSpot–GA4 double-tracking hides. If both are firing plus a tag manager container, you are paying three times for the same pageview, which is part of why your HubSpot and GA4 numbers never match.
5. Keep HubDB and dynamic pages honest
Dynamic pages built on HubDB are fast until a template loops the full table on every request, or runs several `hubdb_table_rows` calls to render one listing. Query once, filter with the API's own parameters rather than in HubL, and limit the columns you pull.
For large directories, paginate at the query level instead of rendering 500 rows and hiding most with CSS. The pattern we use for scaled listings is in HubDB programmatic SEO.
6. Forms, embeds and the shifting-layout problem
HubSpot forms load asynchronously, so any page that renders a form inline will shift unless you reserve space for it. Set a min-height on the form wrapper that matches the rendered height, and the same for embedded videos and maps.
Replace autoplaying background video with a poster image and a click-to-play, or a short compressed loop capped at a few hundred kilobytes. Video is the second-biggest payload offender after images on HubSpot landing pages, as we found rebuilding Mistertango's mobile experience.
7. Re-measure, then protect the gains
Re-run the same five pages, on the same devices, and compare against the numbers you wrote down. Expect the image and asset-scoping work to deliver most of the improvement, and script cleanup to deliver the INP change.
Then make it durable: add an image size limit to your content guidelines, review new modules for global asset attachments before publishing, and check Core Web Vitals monthly. Performance is a maintenance habit, not a one-off project — which is why it is part of every HubSpot support and maintenance plan we run.
