
Third Party Scripts
- 1 installs
- 73.4k repo stars
- Updated June 18, 2026
- thedaviddias/frontendchecklist
Audits third-party scripts and applies async, defer, lazy-loading, or self-hosting to cut the seconds they add to page load.
About
Optimizes third-party script loading, the leading cause of slow sites, by choosing async, defer, or lazy-load per script. A developer uses it when auditing slow loads and heavy assets.
- Use async for independent scripts, defer for DOM-dependent ones
- Lazy-load non-critical scripts and consider self-hosting
Third Party Scripts by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,914 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thedaviddias/frontendchecklist --skill third-party-scriptsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 73.4k |
| Last updated | June 18, 2026 |
| Repository | thedaviddias/frontendchecklist ↗ |
What it does
Audits third-party scripts and applies async, defer, lazy-loading, or self-hosting to cut the seconds they add to page load.
Files
Optimize third-party script loading
Third-party scripts are the #1 cause of slow websites—unoptimized loading can add 2-5 seconds to your page load time.
Quick Reference
- Use async for independent scripts (analytics, ads)
- Use defer for DOM-dependent scripts (chat widgets, social)
- Lazy-load non-critical scripts after page load
- Consider self-hosting critical third-party scripts
Check
Analyze third-party scripts on this page to ensure they use async/defer and don't block rendering.
Fix
Add async or defer attributes to third-party scripts and consider lazy loading non-critical scripts.
Explain
Explain the performance impact of third-party scripts and strategies to minimize their blocking effect.
Code Review
Review the routes, assets, and loading behavior that affect Optimize third-party script loading. Flag exact files, requests, or rendering steps that add unnecessary network, CPU, or layout cost, and describe the measurement method used to confirm the issue.
---
For full implementation details, code examples, and framework-specific guidance, see references/rule.md.
Rule page: https://frontendchecklist.io/en/rules/performance/third-party-scripts
Optimize third-party script loading
Load third-party scripts asynchronously to prevent blocking the main thread and improve page performance.
Priority: high · Difficulty: intermediate · Time: 20 min
--- Third-party scripts are often the most expensive JavaScript on the page and the least under your control. The right strategy is usually not "load it faster", but "load it later, conditionally, or not at all".
Code Examples
#
Never Block the Head with Optional Vendors
<!-- Bad: parser-blocking third parties -->
<head>
<script src="https://analytics.example.com/track.js"></script>
<script src="https://chat.example.com/widget.js"></script>
<script src="https://reviews.example.com/embed.js"></script>
</head>
<!-- Better: independent scripts do not block parsing -->
<head>
<script src="https://analytics.example.com/track.js" async></script>
<script src="https://reviews.example.com/embed.js" defer></script>
</head>Load Optional Vendors on Intent
<button id="open-chat">Chat with support</button>
<script>
const chatButton = document.querySelector('#open-chat')
chatButton.addEventListener('click', async () => {
chatButton.disabled = true
chatButton.textContent = 'Loading chat...'
const script = document.createElement('script')
script.src = 'https://chat.example.com/widget.js'
script.async = true
document.head.appendChild(script)
}, { once: true })
</script>Use a Facade for Heavy Embeds
<button class="video-facade" data-video-id="abc123">
<img src="/thumbnails/abc123.jpg" alt="Play product demo">
<span>Play video</span>
</button>
<script>
document.querySelector('.video-facade').addEventListener('click', async (event) => {
const target = event.currentTarget
const iframe = document.createElement('iframe')
iframe.width = '560'
iframe.height = '315'
iframe.src = `https://www.youtube.com/embed/${target.dataset.videoId}?autoplay=1`
iframe.title = 'Product demo'
iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'
target.replaceWith(iframe)
}, { once: true })
</script>React Idle or Interaction Loading
function useThirdPartyScript(src: string, loadOn: 'idle' | 'interaction') {
useEffect(() => {
const loadScript = () => {
const script = document.createElement('script')
script.src = src
script.async = true
document.head.appendChild(script)
}
if (loadOn === 'idle') {
if ('requestIdleCallback' in window) {
requestIdleCallback(loadScript)
} else {
setTimeout(loadScript, 1500)
}
return
}
document.addEventListener('click', loadScript, { once: true })
return () => document.removeEventListener('click', loadScript)
}, [src, loadOn])
}Why It Matters
- Network contention: vendor scripts can crowd out CSS, fonts, and hero media during the most sensitive part of the load.
- Main-thread blocking: even
asyncscripts still need parsing and execution time, which can hurt Total Blocking Time and INP. - Unclear business value: many integrations run for every visitor even though only a fraction ever use them.
- Compound cost: a single embed may bring extra JavaScript, images, fonts, cookies, and follow-up network requests.
Choose the Loading Strategy by Business Criticality
Use PageSpeed Insights or a trace to decide which vendors really belong in the initial route, because the right strategy depends on the measured cost of each script, not just on how important the integration feels.
| Vendor type | Recommended strategy | Why |
|---|---|---|
| Bot detection, consent, critical fraud checks | Load before or around interactivity only if the page truly cannot function without it | These may be required for legal or security reasons |
| Analytics and tag managers | async, defer, or framework afterInteractive | Important, but rarely worth blocking first paint |
| Chat, reviews, social embeds, maps, video players | Idle, visibility, or interaction-triggered loading | Most users do not need them on first paint |
| Ads and experimentation tools | Load after critical content, and only where business requirements justify the cost | These often carry large execution and network overhead |
Framework Examples
Next.js
return (
<>
</>
)
}Common Mistakes
- Treating every vendor as critical: most third parties should not compete with LCP resources.
- Using `async` as a complete fix: download order may improve, but execution cost remains.
- Loading chat, video, or review widgets for every visitor: these are usually better behind idle, visibility, or interaction.
- Skipping reserved space for deferred embeds: lazy-loading without dimensions can cause CLS.
- Ignoring removal: sometimes the correct optimization is deleting or replacing the integration.
Practical Budgets
- Keep blocking third-party scripts at
0for normal content pages. - Keep pre-interactive third parties to the small set that is legally or functionally required.
- Treat any single third-party script above roughly
100 KBtransferred or any long task above50msas a candidate for deferment, facades, or removal.
Verification
Re-check the page with Lighthouse or a third-party-code trace after every vendor change so you can confirm the route actually got lighter.
Automated Checks
- Inspect the network waterfall and confirm optional third parties start after critical CSS, fonts, and LCP resources, not before them.
- Record a performance trace and verify third-party execution does not create long tasks above roughly
50msduring the initial route load. - Measure the page on a throttled mobile profile and confirm LCP, TBT, and INP improve or at least do not regress after the loading changes.
Manual Checks
- Confirm interaction-triggered or idle-loaded vendors still work correctly when invoked and do not shift layout unexpectedly.