JavaScript and web performance: why shipping less is faster

· 11 min read · Web Involved

Does JavaScript slow down your website?

Yes — more than any other resource on the web, and the reason is mechanical. Unlike an image, which only has to be decoded and painted, JavaScript must be downloaded, parsed, compiled and executed, and that execution runs on the main thread, the same thread that handles taps, clicks and scrolls. While the browser is busy with a script, it cannot respond to the user, which is why excessive JavaScript is the dominant cause of poor interaction responsiveness and the lab metric behind it. The single most effective performance move, then, is to ship less of it: the fastest JavaScript is the JavaScript you never send. The deeper point is that the three causes of JavaScript bloat — long tasks, large bundles and hydration — are architectural, not a build-setting you can tweak. A content site or storefront shipped as a full client-rendered app pays a heavy cost for nothing, and the fix is to send mostly HTML and add interactivity only where it is genuinely needed.

Why is JavaScript the most expensive resource?

Because of everything the browser has to do with it before it is useful. JavaScript is the most expensive resource type on the web: where an image only needs to be decoded and painted, a script must be downloaded, then parsed, then compiled, then executed — and every one of those steps consumes CPU time on the main thread (HyperWeb, 2026). That is the difference that catches teams out, because even a well-compressed bundle still has to be parsed and run, and parsing and execution are not free even on a fast connection (MDN, 2026).

The cost lands hardest where it is least visible to developers: on real phones. The same JavaScript task that finishes in about 100 milliseconds on a high-end desktop can take 700 to 800 milliseconds on a mid-range mobile device, which is why execution time, not network speed, is often the true bottleneck for the large share of global traffic on lower-powered hardware (SigNoz, 2026; Ask SEO Coach, 2026). A site that feels instant on the machine it was built on can be sluggish for the people actually using it.

How JavaScript hurts your Core Web Vitals

The damage concentrates in responsiveness. By default, JavaScript runs on the main thread, where the browser also calculates layout, paints pixels and handles user input — so when a script monopolises that thread, the page cannot react to a tap or click (DebugBear, 2026). Any task that holds the main thread for more than 50 milliseconds is a “long task,” and long tasks are what degrade Interaction to Next Paint, the Core Web Vital that measures responsiveness across the whole page lifecycle with a target under 200 milliseconds (HyperWeb, 2026).

The lab metric that predicts this is Total Blocking Time, and what it points to is unambiguous. TBT is almost exclusively a JavaScript execution problem — script parsing, compilation, execution, hydration and third-party tags — because browsers are optimised to parse HTML and CSS incrementally without locking the main thread (SigNoz, 2026). One writer calls TBT the “lost intent” metric: when a shopper clicks a call to action and nothing happens, you do not only lose the click, you lose the confidence behind it (PageVitals, 2026). Responsiveness, in other words, is mostly a JavaScript question.

The three causes of JavaScript bloat

A well-known breakdown traces excessive JavaScript to three bottlenecks. The first is long tasks — operations that monopolise the main thread and leave the interface unresponsive. The second is large bundle sizes — a bundle is the file containing your application code and its dependencies, and an oversized one is slow to download, expensive to parse and execute, and even hurts caching, because large files change more often and get re-downloaded (MDN, 2026). The third is hydration, and it is the one that surprises people most.

Hydration is the process of attaching JavaScript behaviour to server-rendered HTML, and it explains a strange experience: a page that appears instantly but ignores your clicks for a beat. Frameworks like React and Next.js deliver HTML from the server quickly, giving a fast First Contentful Paint, but the page stays non-interactive until the client-side JavaScript runs and wires up the event handlers and state — a CPU-intensive step that often creates a large long task right after the page becomes visible (SigNoz, 2026). The UI looks ready while quietly refusing input, which is among the most frustrating things a site can do.

The root cause is architectural, not a build flag

Here is the part that changes how you should think about the problem. The root causes of JavaScript bloat are architectural — shipping a full client-rendered single-page app that requires the entire rendering engine to be sent to the browser — and fixing them means changing architectural defaults, not tuning build configurations (Kunal Ganglani, 2026). The pointed way to put it: building a dashboard with real-time updates genuinely needs client-side interactivity, but building a content site, a storefront or a marketing page while shipping a full SPA means paying a massive JavaScript tax for nothing (Kunal Ganglani, 2026).

The fix is not to abandon any particular framework; it is to stop defaulting to full client-side rendering when the page does not require it. One documented migration moved a React single-page app to a hybrid server-and-client model and cut the initial JavaScript payload by 62%, improving Largest Contentful Paint by over a second on mobile — same features, same interface, dramatically less JavaScript (Kunal Ganglani, 2026). When the heavy lifting moves to the server, the browser receives HTML instead of a set of instructions for building HTML.

Ship HTML, hydrate only the islands

The architectural answer most relevant to ordinary websites is islands. Islands architecture means building a page as a sea of static content with small, independent islands of interactivity, each of which loads its own JavaScript, which sharply reduces the overall hydration cost (MDN, 2026). In practice that means shipping HTML for everything but shipping JavaScript only for the parts users actually interact with — and often only when they interact — which reduces main-thread load dramatically and improves responsiveness without sacrificing the interactivity that matters (Ask SEO Coach, 2026).

Related techniques extend the same idea. Partial or progressive hydration prioritises the most important components and defers the rest; resumability, in newer frameworks, resumes the server-rendered state instead of rebuilding it, so that at times almost no JavaScript is sent during load and the rest is fetched only on interaction (MDN, 2026). All of them serve one principle that the 2026 performance consensus keeps returning to: reduce the amount of JavaScript you ship before you try to make it run faster, because that is the highest-impact move available (Ask SEO Coach, 2026).

Trim what you do ship

Once the architecture is right, the remaining JavaScript still deserves discipline. Code splitting and dynamic imports let you ship the minimum needed for the first paint and load the rest on demand, while tree shaking removes code paths you never use (Landskill, 2026). You cannot trim what you cannot see, so a bundle analyser such as source-map-explorer or webpack-bundle-analyzer is the starting point — it routinely reveals duplicate dependencies, unused modules from large libraries, and polyfills for browser features that no longer need them (HyperWeb, 2026).

Two habits pay off repeatedly. Replace heavy packages with lean ones — the standard example is swapping Moment.js, around 289KB, for date-fns at roughly 12KB or Day.js at about 2KB (Sesame Disk, 2026). And prefer native browser features over JavaScript shims wherever possible: Intersection Observer, CSS scroll snapping and native lazy loading replace libraries that used to be necessary, and polyfills can be loaded conditionally only for the browsers that lack a feature (Ask SEO Coach, 2026). Every dependency you remove is code the browser no longer has to fetch and run.

Govern third-party scripts like infrastructure

The scripts you did not write are often the worst offenders. Third-party tags — analytics, A/B testing, personalisation, chat widgets — frequently dominate main-thread time and quietly regress responsiveness, so they should be governed like infrastructure: require a justification for each one, audit them quarterly, lazy-load where possible, and remove vendors that do not earn their cost (Ask SEO Coach, 2026). A useful budget from one practitioner is to allow third-party scripts no more than 100KB compressed and 200 milliseconds of main-thread time on initial load, and to make something else give way when a new tool exceeds it (Kunal Ganglani, 2026). Where a tool offers a server-side API, moving it off the client eliminates its browser JavaScript entirely.

There is a second reason to keep dependencies few, beyond speed. Every package you add expands your supply-chain attack surface: in September 2025, attackers compromised 18 npm packages carrying 2.6 billion weekly downloads, exploiting exactly the sprawling dependency graphs that bloated front-ends accumulate (Sesame Disk, 2026). A leaner build is both a faster one and a smaller target, which is part of why a site with zero third-party scripts is easier to keep both quick and secure.

How do you measure it?

Measure responsiveness in two places. In the field, track Interaction to Next Paint, the metric real users feel; in the lab, watch Total Blocking Time as an early-warning signal you can catch before it reaches production (PageVitals, 2026). Because the same workload behaves very differently across devices, always validate under mobile emulation with about 4× CPU throttling — a page that stays responsive under that constraint will almost always be fine on desktop (SigNoz, 2026).

Then make the discipline structural rather than occasional. Put a bundle analyser in your build pipeline and set a performance budget that fails the build when JavaScript exceeds it, no exceptions, so regressions are caught before they ship (Sesame Disk, 2026). And keep the cheapest optimisation in mind, the one practitioners reach for first: the fastest wins usually come from deleting or delaying something, not from rewriting the site (PageVitals, 2026).

How we build

Our stack is this argument turned into a default. We build with an islands architecture and ship almost no JavaScript — static HTML with tiny, independent islands of interactivity only where a page genuinely needs them — and we run zero third-party scripts, which removes the single biggest source of main-thread blocking before it can exist. Because there is no full client-side app to hydrate, there is no hydration long task, no multi-megabyte bundle, and no period where the page looks ready but ignores input, so responsiveness is good by default rather than something we tune afterward.

The honest version of our pitch is that most sites are paying a large performance cost for capability they do not use, and a content or marketing site simply does not need a full application framework to display its content. Shipping less JavaScript is also why our pages are easy for machines to read, since the words are in the HTML rather than waiting behind a script — the same root cause behind our pillar on whether your website is readable by AI. JavaScript is one of the three payloads that decide your speed; the other two are covered in our guides on optimizing images and self-hosting fonts, and all three sit under the larger picture in our pillar on Core Web Vitals and site speed, which is the place to go next.

Frequently asked

Does JavaScript slow down a website?
More than any other resource type, yes. Unlike an image, which only needs to be decoded and painted, JavaScript has to be downloaded, parsed, compiled and executed — and that execution happens on the main thread, the same thread that handles user input. While the browser is busy running JavaScript, it cannot respond to taps, clicks or scrolls, which is why excessive JavaScript is the main cause of poor interaction responsiveness. The most effective fix is to ship less of it, because the fastest JavaScript is the JavaScript you never send.
How much does JavaScript affect Core Web Vitals?
Heavily, especially the responsiveness metrics. Interaction to Next Paint (INP), which targets under 200 milliseconds, and Total Blocking Time (TBT), its lab counterpart, are almost entirely a function of JavaScript execution. Any task that occupies the main thread for more than 50 milliseconds is a 'long task' that blocks input. HTML and CSS rarely cause these problems because browsers parse them incrementally, so when responsiveness is poor, the cause is usually scripts — first-party bundles, framework hydration, or third-party tags.
What is hydration and why is it slow?
Hydration is the process of attaching JavaScript behaviour to server-rendered HTML — wiring up event handlers and rebuilding application state in the browser. It is why a page can appear instantly (a fast First Contentful Paint) yet ignore clicks for a moment: the HTML is visible, but the page is not interactive until the JavaScript bundle has hydrated it, which is CPU-intensive and often creates a long task right after the page becomes visible. Frameworks that default to full client-side hydration pay this cost on every page.
What is islands architecture?
Islands architecture means rendering a page as mostly static HTML with small, independent 'islands' of interactivity that each load their own JavaScript only when needed. Instead of shipping one large bundle to make the whole page interactive, you ship HTML for everything and JavaScript only for the parts users actually interact with — a search box, a menu, a form. This dramatically reduces main-thread work and improves responsiveness without giving up interactivity where it matters. Astro is a common framework built around this model.
Do I need a JavaScript framework for my website?
Often not. A dashboard with real-time updates genuinely needs client-side interactivity, but a content site, a marketing page or a storefront usually does not — shipping a full client-rendered single-page app to display what is essentially a document means paying a large JavaScript cost for nothing. The question is not whether to use React or any specific tool, but whether to default to full client-side rendering when the page does not require it. For most sites, server-rendered HTML with a little interactivity is faster and simpler.