How to Reduce JavaScript Bloat in Large Webflow Projects
Inventory every script on a large Webflow site, remove duplicates and dead tools, and load the rest only on pages that need them.

Is your Webflow site slow, costly or hard to find?
Send me your siteTo reduce JavaScript bloat in a large Webflow project, list every script the site loads, delete what has no owner, and load the rest only on pages that need it. Webflow's own runtime is a fixed cost. The bloat is almost always in what was added on top: site-wide custom code, Embed elements, Google Tag Manager and duplicate libraries.
Step 1: Find every script
Check each place scripts can live:
- Site settings > Custom code, head and footer
- Page settings > Custom code on static pages and CMS Collection templates
- Embed elements, including ones inside components
- Tags in your Google Tag Manager container
Then open the published site in Chrome DevTools, filter the Network tab by JS and sort by size. Lighthouse lists the worst files under "Reduce unused JavaScript". The Coverage panel shows how much of each file goes unused. Record each script's purpose, owner, location and the pages that need it. On a large project this register is the most useful performance document you have.
Step 2: Remove dead tools and duplicates
- Heatmaps and A/B testing snippets nobody uses
- Pixels for platforms you no longer advertise on
- A second copy of jQuery. Webflow already loads it, and another copy can break components.
- GA4 installed both in custom code and in GTM
- Two slider or animation libraries doing the same job
Remove on the staging domain first and test forms and key flows before publishing.
Step 3: Load scripts only where needed
A calculator or map used on one page belongs in that page's custom code. For a feature inside a component, load its library only when the element exists:
<script>
if (document.querySelector('[data-calc]')) {
var s = document.createElement('script');
s.src = 'https://cdn.example.com/calc.js';
document.body.appendChild(s);
}
</script>Add the data-calc attribute to the element in its settings panel.
Step 4: Stop scripts from blocking
Add defer to external scripts that depend on order or page content: it runs them in order after the HTML is parsed. Use async for standalone tools, which run as soon as they download. Load chat widgets on the first interaction:
<script>
var done = false;
function loadChat() {
if (done) return; done = true;
var s = document.createElement('script');
s.src = 'https://chat.example.com/widget.js';
document.body.appendChild(s);
}
['scroll','pointerdown','keydown'].forEach(function (e) {
addEventListener(e, loadChat, { once: true, passive: true });
});
</script>Step 5: Keep GTM and interactions lean
Tag Manager makes adding scripts easy, which is why containers grow. Delete paused tags and replace All Pages triggers with specific ones. Limit scroll interactions and large Collection lists too, since they add main-thread work.
Example: a hypothetical 500-page docs site loads a code highlighter and a search widget on every page, including the homepage. Moving each to the CMS template that uses it removes them from pages that never needed them.
Checklist
- Every script has an owner and purpose
- No second jQuery, one GA4 install
- Page-specific scripts out of Site settings
- External scripts use defer or async
- Chat delayed until interaction
- GTM triggers tightened
FAQ
Can I remove jQuery or webflow.js?
No. Interactions and native components depend on them.
How do I know it worked?
Compare Total Blocking Time in Lighthouse before and after, then watch INP in Search Console over four weeks.
Dealing with this on a live Webflow site? It is the kind of work I do in a Webflow audit. Send me your site and I will tell you what I would fix first.


.webp)