Squarespace 7.1's own first-party scripts run synchronously and cannot be deferred from inside the platform3. The scripts you can control are the third-party ones you have added through Settings > Advanced > Code Injection — chat widgets, analytics layers beyond GA4, embedded social, marketing automation snippets. Adding async or defer attributes to those tags reduces main-thread blocking time and is the primary lever for fixing INP on Squarespace.
The audit is short — list every third-party script tag, decide which can defer, swap the attribute. Most Squarespace 7.1 INP problems resolve with this single intervention.
§01Control
What you can defer and what the platform locks down
Squarespace ships its own first-party JavaScript bundle that powers the editor, the live preview, the navigation, the carousel blocks, and other interactive elements. That bundle is loaded synchronously and cannot be deferred — there is no Squarespace setting to defer it, no Code Injection trick that overrides it, no plugin that disables it. What you control is the third-party scripts you have added: chat widgets (Intercom, Drift, Tidio), analytics beyond GA4 (Mixpanel, Heap, Hotjar), social embeds, marketing pixels, and any custom scripts pasted into Settings > Advanced > Code Injection. These are the scripts that benefit from async or defer.
What you control
Locked
Squarespace's own first-party scripts. Cannot be deferred. The platform overhead.
Async and defer both load the script in parallel with HTML parsing, so neither blocks first paint. The difference is when the script executes. async runs the script as soon as it finishes downloading, which can interrupt parsing. defer waits until parsing is done before running the script, in the order the scripts appear. For most third-party Squarespace add-ons — analytics, chat widgets, social embeds — defer is the safer default because the execution order is predictable. async is for scripts that have no dependencies and should run as soon as possible (Google Analytics is a common async case).
HTMLCode Injection — async vs defer attribute placement
<!-- async — runs as soon as it downloads, may interrupt parsing --><scriptasyncsrc="https://www.googletagmanager.com/gtag/js?id=G-XXXX"></script><!-- defer — waits for parsing to finish, runs in order --><scriptdefersrc="https://widget.intercom.io/widget/APP_ID"></script><scriptdefersrc="https://static.hotjar.com/c/hotjar-SITE_ID.js"></script>
The web.dev guidance1 is clear: for analytics and pixels, async is fine. For widgets that depend on the DOM or on other scripts, defer is safer because the execution order is preserved. A common Squarespace mistake is adding the async attribute to a chat widget script that needs the DOM to be ready — the widget mounts before the DOM has finished parsing, and the widget breaks visibly.
§03Audit
The third-party-script audit
Open Settings > Advanced > Code Injection. Look at the Header panel — every script tag pasted in there runs on every page. Make a list. For each script, decide: is it critical to first paint (almost never), does it need to run after DOM-ready (most analytics and widgets), can it defer entirely (true for most marketing pixels). Add async or defer to each tag. Save. Re-run PageSpeed Insights and check the INP improvement.
Lighthouse4 has a specific audit called 'Reduce JavaScript execution time' that flags scripts taking too long. The diagnostic names each script by URL and lists its parse, compile, and execute time. Use the list to prioritise — the slowest script gets the biggest INP improvement when deferred.
Common Squarespace 7.1 candidates for the audit:
Live chat widgets — Intercom, Drift, Tidio, Crisp. Always defer; never block first paint.
Analytics beyond GA4 — Mixpanel, Heap, Amplitude, Hotjar. All async-safe.
Marketing pixels — Meta, LinkedIn, TikTok, Pinterest. All async-safe.
Embedded social widgets — Twitter timelines, Instagram embeds. Defer or remove.
Custom CSS that loads JavaScript — rare, but check for @import rules pointing at JS-bearing libraries.
§04Pattern
The rebuilt script pattern
After the audit, the Header Code Injection panel should look something like the block below: every third-party script tag carries async or defer, the order is predictable, and inline code is wrapped in DOMContentLoaded if it has any dependencies. The page-level INP score should drop within one PSI re-run for the Lab Data and within four weeks for the Field Data (CrUX rolling window).
<!-- Analytics — async is fine, no DOM dependency --><scriptasyncsrc="https://www.googletagmanager.com/gtag/js?id=G-XXXX"></script><!-- Inline GA4 config — runs after async loads --><script>window.dataLayer = window.dataLayer || [];
functiongtag(){dataLayer.push(arguments);}
gtag('js', newDate());
gtag('config', 'G-XXXX');
</script><!-- Live chat — defer so it doesn't block --><scriptdefersrc="https://widget.intercom.io/widget/APP_ID"></script><!-- Heat-mapping — defer --><scriptdefersrc="https://static.hotjar.com/c/hotjar-SITE_ID.js"></script>
Re-run PSI after the audit. The Lighthouse 'Reduce JavaScript execution time' audit should pass or have far fewer items. The INP score in Lab Data should drop within seconds. Real-user INP via CrUX takes 4 weeks to update fully. If INP does not move and you have already done the audit, the remaining culprit is usually Squarespace's first-party bundle — which is the part you cannot defer, only Squarespace can.