<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/i-reduced-our-react-bundle-by-70-without-removing-a-single-feature-szhhzvcpd" -->

---
title: I Reduced Our React Bundle by 70% Without Removing a...
description: A developer reduced a React app's JavaScript bundle from 2.4MB to 710KB (70% reduction) without removing features, improving Lighthouse score from 54 to 91 and...
canonical: https://daily.dev/posts/i-reduced-our-react-bundle-by-70-without-removing-a-single-feature-szhhzvcpd
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: I Reduced Our React Bundle by 70% Without Removing a Single Feature | daily.dev
og:description: A developer reduced a React app's JavaScript bundle from 2.4MB to 710KB (70% reduction) without removing features, improving Lighthouse score from 54 to 91 and...
og:url: https://daily.dev/posts/i-reduced-our-react-bundle-by-70-without-removing-a-single-feature-szhhzvcpd
og:image: https://api.daily.dev/og/posts/sZhHZvCPD.png
og:image:alt: I Reduced Our React Bundle by 70% Without Removing a Single Feature
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# I Reduced Our React Bundle by 70% Without Removing a Single Feature

**[Medium](https://daily.dev/sources/medium_js)** · 14 min read · 18 upvotes · 3 comments

## Summary

A developer reduced a React app's JavaScript bundle from 2.4MB to 710KB (70% reduction) without removing features, improving Lighthouse score from 54 to 91 and time-to-interactive from 4.1s to 1.3s. The key optimizations were: route-based code splitting with React.lazy (saving ~680KB from initial load), replacing Moment.js with Day.js (saving ~280KB), fixing Lodash imports to use per-function imports (saving ~65KB), lazy loading heavy components like charts and PDF viewers (saving ~220KB), swapping heavy npm packages for lighter alternatives like native fetch over axios (saving ~180KB), enabling proper tree shaking via tsconfig and sideEffects config (saving ~85KB), and converting images to WebP with lazy loading. The post also covers gotchas like SSR incompatibility with React.lazy, Suspense boundary placement, and duplicated dependencies after code splitting.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://navanathjadhav.medium.com/i-reduced-our-react-bundle-by-70-without-removing-a-single-feature-b8d0051c0611>

## Questions this post answers

### How do I reduce my React app's JavaScript bundle size without cutting features?

Combine route-based code splitting with React.lazy and Suspense, replace moment.js with day.js or date-fns, fix lodash imports to per-function imports, lazy-load heavy non-route components like charts and PDF viewers, swap axios for native fetch, and enable proper tree-shaking via ESNext modules and sideEffects config. One real case cut a bundle from 2.4MB to 710KB, a 70% reduction, over three days of work.

_daily.dev surfaces practical bundle-optimization writeups for developers chasing faster load times without feature cuts._

### How much bundle size can I save by replacing moment.js with day.js?

Moment.js typically ships around 296KB gzipped including unused locale files, while day.js provides a near-identical API in about 2KB gzipped, since it mirrors Moment's method signatures closely. A migration covering date formatting, time-ago calculations, date parsing, and day arithmetic can take roughly 2 hours and save around 280KB in one reported case. Moment's own maintainers now recommend against using it in new projects.

_developers weighing date library migrations can track real-world day.js versus moment.js tradeoffs via daily.dev._

### Why doesn't tree shaking work in my JavaScript bundle even though I only import specific functions?

Tree shaking fails when tsconfig sets module to CommonJS instead of ESNext, because require() calls are dynamic and can't be statically analyzed; it also fails without a sideEffects: false flag in package.json, which tells the bundler unused exports are safe to remove. Barrel files that re-export everything from a folder (like an index.ts exporting a 180KB chart component) can silently pull in code you never use, even through unrelated imports from the same barrel.

_daily.dev helps developers debugging tree-shaking and barrel-file bloat compare fixes others have tried._

## Community discussion

Top comments from developers on daily.dev.

**@yaireo** · 2 upvotes

> You can further optimize your fonts by removing unused glyphs (and unused weights for non-variable fonts).
>
> I would also get rid of ancient `lodash` and replace it with `es-toolkit`

**@sachchidanand** · 0 upvotes

> Insightful, will think on this

**@krunaldhimmar** · 0 upvotes

> helpgul!!

## Similar posts on daily.dev

- [A complete guide to React performance optimization](https://daily.dev/posts/a-complete-guide-to-react-performance-optimization-zei2krfdt) · LogRocket · 3 upvotes · 0 comments
- [Fixing Server Component Bundle Leaks in Next.js](https://daily.dev/posts/fixing-server-component-bundle-leaks-in-next-js-a3htgnywf) · SitePoint · 1 upvotes · 0 comments
- [Optimizing Our Build Times by Migrating from Webpack to Rspack](https://daily.dev/posts/optimizing-our-build-times-by-migrating-from-webpack-to-rspack-j4os8uopj) · Yelp Engineering · 0 upvotes · 0 comments
- [adam bien's blog](https://daily.dev/posts/adam-bien-s-blog-psooywbzi) · Adam Bien · 0 upvotes · 0 comments
- [I Built the Same App 10 Times: Evaluating Frameworks for Mobile Performance](https://daily.dev/posts/i-built-the-same-app-10-times-evaluating-frameworks-for-mobile-performance-f3ogjp3kp) · Hacker News · 28 upvotes · 3 comments

---

Tags: [#webdev](https://daily.dev/tags/webdev), [#react](https://daily.dev/tags/react)

[View this post on daily.dev](https://daily.dev/posts/i-reduced-our-react-bundle-by-70-without-removing-a-single-feature-szhhzvcpd)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"I Reduced Our React Bundle by 70% Without Removing a Single Feature","url":"https://daily.dev/posts/i-reduced-our-react-bundle-by-70-without-removing-a-single-feature-szhhzvcpd","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/i-reduced-our-react-bundle-by-70-without-removing-a-single-feature-szhhzvcpd"},"datePublished":"2026-07-21T08:48:35.214Z","dateModified":"2026-09-13T20:54:06.041Z","description":"A developer reduced a React app's JavaScript bundle from 2.4MB to 710KB (70% reduction) without removing features, improving Lighthouse score from 54 to 91 and...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/6253e4280713f951a21ea1b84ab8deea?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/6253e4280713f951a21ea1b84ab8deea?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Medium","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Medium","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/medium","url":"https://daily.dev/sources/medium_js"},"commentCount":3,"discussionUrl":"https://daily.dev/posts/i-reduced-our-react-bundle-by-70-without-removing-a-single-feature-szhhzvcpd","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":18},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":3}],"keywords":"webdev,react","timeRequired":"PT14M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Medium","item":"https://daily.dev/sources/medium_js"},{"@type":"ListItem","position":3,"name":"I Reduced Our React Bundle by 70% Without Removing a Single Feature"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/i-reduced-our-react-bundle-by-70-without-removing-a-single-feature-szhhzvcpd","comment":[{"@type":"Comment","text":"You can further optimize your fonts by removing unused glyphs (and unused weights for non-variable fonts).\nI would also get rid of ancient lodash and replace it with es-toolkit","datePublished":"2026-07-22T10:24:08.279Z","dateModified":"2026-07-22T10:24:42.286Z","url":"https://daily.dev/posts/sZhHZvCPD#c-NSXfWVn1A","author":{"@type":"Person","name":"Yair Even Or","url":"https://daily.dev/yaireo","image":"https://avatars.githubusercontent.com/u/845031?v=4"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":2}},{"@type":"Comment","text":"Insightful, will think on this","datePublished":"2026-07-29T07:19:12.283Z","url":"https://daily.dev/posts/sZhHZvCPD#c-C5M7KYl9S","author":{"@type":"Person","name":"Sachchidanand Chitnis","url":"https://daily.dev/sachchidanand","image":"https://media.daily.dev/image/upload/s--QUfblGFP--/f_auto/v1782972312/avatars/avatar_1EhzrM1K8RjvlbJPwRfP6?_a=BAMAMicg0"}},{"@type":"Comment","text":"helpgul!!","datePublished":"2026-07-29T11:44:27.059Z","url":"https://daily.dev/posts/sZhHZvCPD#c-IboDSXdGK","author":{"@type":"Person","name":"krunal dhimmar","url":"https://daily.dev/krunaldhimmar","image":"https://lh3.googleusercontent.com/a/ACg8ocLibFizZf6R9SdBl-zTGV_4iKTbC09iQdCfXeq8LyUbTVDaKz4=s96-c"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/i-reduced-our-react-bundle-by-70-without-removing-a-single-feature-szhhzvcpd#faq","mainEntity":[{"@type":"Question","name":"How do I reduce my React app's JavaScript bundle size without cutting features?","acceptedAnswer":{"@type":"Answer","text":"Combine route-based code splitting with React.lazy and Suspense, replace moment.js with day.js or date-fns, fix lodash imports to per-function imports, lazy-load heavy non-route components like charts and PDF viewers, swap axios for native fetch, and enable proper tree-shaking via ESNext modules and sideEffects config. One real case cut a bundle from 2.4MB to 710KB, a 70% reduction, over three days of work. daily.dev surfaces practical bundle-optimization writeups for developers chasing faster load times without feature cuts."}},{"@type":"Question","name":"How much bundle size can I save by replacing moment.js with day.js?","acceptedAnswer":{"@type":"Answer","text":"Moment.js typically ships around 296KB gzipped including unused locale files, while day.js provides a near-identical API in about 2KB gzipped, since it mirrors Moment's method signatures closely. A migration covering date formatting, time-ago calculations, date parsing, and day arithmetic can take roughly 2 hours and save around 280KB in one reported case. Moment's own maintainers now recommend against using it in new projects. developers weighing date library migrations can track real-world day.js versus moment.js tradeoffs via daily.dev."}},{"@type":"Question","name":"Why doesn't tree shaking work in my JavaScript bundle even though I only import specific functions?","acceptedAnswer":{"@type":"Answer","text":"Tree shaking fails when tsconfig sets module to CommonJS instead of ESNext, because require() calls are dynamic and can't be statically analyzed; it also fails without a sideEffects: false flag in package.json, which tells the bundler unused exports are safe to remove. Barrel files that re-export everything from a folder (like an index.ts exporting a 180KB chart component) can silently pull in code you never use, even through unrelated imports from the same barrel. daily.dev helps developers debugging tree-shaking and barrel-file bloat compare fixes others have tried."}}]}
```

