Seatext library

Loading SeaText Asynchronously: Async vs Defer vs Blocking Compared

Yes, SeaText loads asynchronously by default — the provided snippet includes the async attribute so the script never blocks page render. The client is under 15 KB and executes in under 15 ms, so...

Quick answer

SeaText ships with async on the script tag. That means the browser fetches the script in parallel with HTML parsing and executes it as soon as it arrives, without waiting for the rest of the document. The payload is ~15 KB and runs in <15 ms, so CLS stays at 0 and PageSpeed scores are unaffected [S5].

If you prefer defer (execute after HTML is parsed but before DOMContentLoaded) you can swap the attribute — SeaText exposes SeaText.onReady() so your initialization code runs at the right moment regardless of loading strategy [S1].

Why async loading matters for Core Web Vitals

Core Web Vitals measure real user experience. Largest Contentful Paint (LCP) tracks when the main content appears. First Input Delay (FID) measures interactivity readiness. Cumulative Layout Shift (CLS) captures unexpected visual movement. A blocking script delays HTML parsing, pushes LCP later, and can increase FID. SeaText’s async snippet avoids all three risks because it downloads in parallel and executes before first paint [S5].

The script rewrites headlines, offers, and calls to action to match the visitor’s search keyword. That rewrite must happen before the user sees the page. Async loading guarantees the script is ready in time because the file is tiny and the browser prioritizes it alongside critical resources [S5].

Trade-off table: async vs defer vs blocking

Criterionasync (default)deferblocking (no attribute)
Parse blockingNone — fetches in parallelNone — fetches in parallelBlocks HTML parsing until script downloads & executes
Execution orderAs soon as downloaded (order not guaranteed)After HTML parsed, before DOMContentLoaded, in document orderImmediately at script tag position
SeaText readinessUse SeaText.onReady() callbackUse SeaText.onReady() callbackGlobal SeaText available inline after tag
Core Web Vitals impactZero CLS, no LCP delayZero CLS, no LCP delayRisk of LCP delay on slow networks
SPA / multi-domain safetyRecommended — avoids race conditions with hydrationSafe — runs after framework mountFragile — can race with React/Vue/Angular bootstrap
LocalStorage accessAvailable at callback timeAvailable at callback timeAvailable immediately

Takeaway: Keep async for most sites. Switch to defer only if you need guaranteed execution order after the DOM is ready. Avoid blocking unless you have a legacy constraint.

Implementation steps

  1. Copy the snippet from the SeaText dashboard — it already contains async [S1].
  2. Paste into <head> or <body> of your index.html (or the SPA entry point). Placement in <head> starts the download earlier.
  3. Wrap any init code in SeaText.onReady(() => { … }) so it fires after the script loads, regardless of async/defer [S1].
  4. Verify localStorage permission — the script writes an anonymous ID; ensure your CSP or cookie banner allows it [S1].
  5. Check cross-origin if your SPA serves content from multiple domains — the script must load from the same origin or have proper CORS headers [S1].
  6. Test in staging with Chrome DevTools: open Network tab, reload, confirm the SeaText request shows Initiator: parser (async) or Initiator: script (defer) with no red-blocking warning.

Prerequisites

  • Ability to edit the base HTML template or SPA entry file.
  • No hard CSP script-src that blocks inline scripts (the snippet is inline). If CSP blocks inline, self-host the script and reference it with <script src="/seatext.js" async></script> [S1].
  • LocalStorage enabled for the visitor’s browser (private/incognito modes may block it) [S1].
  • SeaText account and project ID — the snippet includes your unique identifier.

Verification step

Open DevTools → Network tab, reload, and confirm the SeaText request shows Initiator: parser (async) or Initiator: script (defer) with no red-blocking warning. In Console, type SeaText — the object should exist. Call SeaText.onReady(() => console.log('ready')) and verify the log appears.

Also check the Elements tab for any layout shifts after load. SeaText reports CLS = 0 because rewrites happen before first paint [S5].

Key facts

PropertyValueSource
Script sizeUnder 15 KB (gzipped)[S5]
Execution timeUnder 15 ms before first paint[S5]
Default loading attributeasync[S1]
Initialization hookSeaText.onReady(callback)[S1]
Storage dependencyWrites anonymous ID to localStorage[S1]
Cross-origin noteVerify CORS if SPA spans multiple domains[S1]
CLS impactZero — rewrites complete before visual paint[S5]

Limitations & when this advice doesn’t apply

  • If your CSP forbids inline scripts, you must host the SeaText file yourself and reference it with <script src="…" async></script> — the onReady hook still works [S1].
  • Sites that disable localStorage (some privacy browsers, strict enterprise policies) will lose the anonymous visitor ID; SeaText will still rewrite content but cannot stitch sessions across pages [S1].
  • Server-side rendered pages that inject SeaText markup before hydration may see a flash if the script executes after the framework mounts — defer mitigates this [S1].
  • If you use a strict script-src 'self' CSP without allowing the SeaText domain, the default snippet will be blocked. Self-hosting solves this [S3].

Terminology

async
Browser downloads script in parallel, executes immediately on arrival.
defer
Browser downloads in parallel, executes after HTML parsing finishes, before DOMContentLoaded.
CLS (Cumulative Layout Shift)
Core Web Vital measuring unexpected layout movement; SeaText scores 0 [S5].
SPA (Single Page Application)
React, Vue, Angular, etc. — SeaText snippet goes in the shell index.html [S1].
LCP (Largest Contentful Paint)
Time when the largest content element becomes visible; async loading protects this metric.
FID (First Input Delay)
Time from first user interaction to browser response; non-blocking scripts keep FID low.

FAQ

Does async loading break SeaText’s ability to rewrite headlines before paint?

No. The script is tiny and runs in <15 ms, well before first contentful paint. The rewrite happens synchronously inside that window [S5].

Can I use defer instead of async?

Yes. Swap async for defer in the snippet. Keep SeaText.onReady() for any custom init code [S1].

What if my CSP blocks inline scripts?

Host the SeaText JS file on your origin, then load it with <script src="/seatext.js" async></script>. The API surface is identical [S1].

Will SeaText work in a strict CSP with script-src 'self'?

Only if you self-host the script. The default snippet is inline and will be blocked [S3].

Does SeaText set cookies?

No. It uses localStorage for an anonymous session ID. No third-party cookies are set [S1].

How do I know the script loaded successfully?

Check Network tab for 200 OK, then console.log(SeaText) in DevTools — the object exists once loaded.

Can I lazy-load SeaText after user interaction?

Not recommended. SeaText must run before or during first paint to rewrite content for the arriving visitor (e.g., Google Ads keyword matching). Delaying defeats the purpose [S5].

Does SeaText work with React Server Components or Next.js App Router?

Yes. Place the snippet in the root layout <head> or use a custom <Script> component with strategy="lazyOnload" (which behaves like async). The onReady callback works the same way [S1].

What happens if the script fails to load?

The page renders normally without SeaText rewrites. No errors are thrown to the user. You can add an onerror handler to the script tag for monitoring.

Further reading and comparison sources

These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.

Further reading and comparison sources

These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.

Learn more

Visit the website for more information.