Why 90s Websites Load Faster Than Modern React Apps – Lessons in Frontend Performance
The article compares the tiny, instantly‑rendered pages of the 1990s with today’s heavyweight React applications, showing how bundle size, JavaScript execution, and rendering pipelines create latency, and explains why modern tools still rely on classic performance principles to stay fast.
Cold Numbers
Typical 1990s websites were only 2–5 KB, far smaller than a high‑resolution photo you might upload today.
Modern React bundles start around 30 KB for the framework itself, plus your business code, styles, images, and a slew of npm dependencies.
A recent minimal todo app weighed 847 KB, comparable to the 2.39 MB installer of the original DOOM game.
90s Formula: Simple to “Violent”
The old site‑building process was straightforward:
Write some HTML
Add CSS if needed
Optionally include a tiny JavaScript for image rollovers
FTP upload
Done ✅
There was no build step, no bundling, no transpilation, and no virtual DOM. The browser simply read the HTML top‑to‑bottom and rendered it, making size the core performance factor.
GET /index.html (2.1 KB)
GET /style.css (0.8 KB)
GET /banner.gif (1.2 KB)
GET /background.jpg (3.1 KB)
Total: 4 requests / 7.2 KB / progressive renderingModern React Apps: Completely Different Species
A typical modern load sequence looks like this:
GET /index.html (1.2 KB)
GET /bundle.js (847 KB) <-- wait for this big chunk
GET /vendor.bundle.js (312 KB)
GET /runtime.bundle.js (23 KB)
GET /main.css (89 KB)
GET /fonts.woff2 (156 KB)
GET /api/initial-data (45 KB JSON)
Total: 7+ requests / ~1,473 KB / blank screen until JS runsLarge JavaScript bundles block rendering; downloading and executing ~1.5 MB of script can leave users staring at a blank page for hundreds of milliseconds, especially on mobile.
Beyond the delay, that JavaScript powers the entire runtime: state management, virtual‑DOM diffing, event system, routing, and real‑time data sync.
The Real Bottleneck: What Happens After Download
Size is only the first hurdle—execution is even more critical.
1990s sites required no client‑side computation; the HTML was already “drawn”. Modern React apps must:
Parse hundreds of KB of JS
Build a virtual DOM
Run component lifecycle methods
Compute initial state
Fetch data
Reconcile virtual DOM with real DOM
Apply styles and trigger layout
In one analysis, React’s first‑paint took ~50 ms, but waiting for the server added ~560 ms, plus another 200–500 ms for JS parsing/execution on mobile.
Why Do We Still Do This?
Don’t hastily discard <table> or inline styles. The web has evolved from static “electronic flyers” to full‑blown software running in the browser, enabling real‑time updates, complex state, smooth interactions, multi‑tab sync, Service Workers, and near‑native app experiences.
Trying to build Slack, Figma, or Google Docs with 1990s techniques is impossible; user expectations have fundamentally changed.
Performance “Cost and Benefit”
A site that loads in 1 second can achieve up to three times the conversion rate of a 5‑second site. This creates a tension: we want React’s interactivity but must also pull first‑paint speed back.
Thus a suite of performance engineering techniques emerged:
SSR (Server‑Side Rendering)
SSG (Static Site Generation)
Code splitting / lazy loading
Tree shaking to remove unused code
PWA caching strategies
Critical CSS inlining
Ironically, we add ever‑more complex build pipelines to retain modern capabilities while recapturing the “simple + fast” ethos of the past.
When “Simple” Still Rules
In many scenarios, the 1990s mindset remains unbeatable:
Blogs, documentation, marketing pages, and other content‑centric sites often don’t need React at all.
Static site generators like Hugo can deliver sub‑100 ms first‑paint while still providing responsive layouts, image optimization, content workflows, SEO friendliness, and form handling.
In short, the fastest React still can’t beat a well‑crafted static HTML page’s initial load—physics still wins.
Sweet Spot: Modern Tools, Classic Principles
Top‑performing modern sites essentially resurrect 1990s performance principles:
Reduce the initial bundle: aggressive code‑splitting, lazy‑load everything non‑critical.
Progressive rendering: show what you have as soon as possible, don’t wait for everything.
Efficient caching: proper cache headers and versioning for static assets.
Measure to improve: without metrics you can’t optimize.
Frameworks like Next.js, Gatsby, and SvelteKit strive to balance “React‑like developer experience” with “90s‑like performance”.
Conclusion
1990s sites were faster not because they were more advanced, but because their goal was simply to deliver content to the user as quickly as possible.
Modern React apps prioritize maintainability, interactivity, and complex features; performance incurs a cost, but the benefits are real.
The key is using the right tool for the right job—building a static “About Us” page with React is like driving a Ferrari to fetch a parcel: it works, but the overhead is unnecessary.
The real takeaway isn’t to revert to the 1990s, but to wield powerful tools judiciously and keep things simple when possible.
Often, the simplest solution is the best one.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Tech Enthusiast
Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
