LogoTRUONG PHAM
Home
Projects
Blogs
YouTube
Contact

Newsletter

Stay updated with technical artifacts and engineering insights.

LogoTRUONG PHAM

Building scalable software and sharing insights on technology & life.

Sitemap

  • Home
  • Projects
  • Blogs
  • YouTube
  • Contact

Connect

  • GitHub
  • LinkedIn
  • Email
  • YouTube

© 2024 TRUONG PHAM. © All rights reserved.

Privacy PolicyTerms of Service
Back
Blog #12: Don't bring the whole supermarket home just to buy a loaf of bread
50 FRONTEND LESSONS – HARD-EARNED EXPERIENCES

Blog #12: Don't bring the whole supermarket home just to buy a loaf of bread

To my early-career self, back when installing a 500kb library just to use one date formatting function was par for the course.

TP
Truong PhamSoftware Engineer
PublishedApril 12, 2024

Dear younger, "newbie" version of myself from years ago.

I remember how excited you were when you found a library that could solve the problem you were facing. When the boss asked to display time like "3 days ago", you immediately opened the terminal and typed: npm install moment. You thought it was fantastic because with exactly 2 lines of code, the problem was solved. You didn't care at all how much the node_modules folder was ballooning, or how many extra KB of data the user would have to download.

To you back then, "code that runs and the UI looks right" was an absolute victory. But my current self, who has tasted the bitterness of slow-loading sites and user complaints, wants to tell you why that approach is a fatal mistake.

1. Simple Analysis: The Supermarket Story

Imagine you want to buy a loaf of bread. Instead of walking to the bakery at the corner, you decide to... buy the entire supermarket, hire a fleet of trucks to transport all the goods in the supermarket to your front door just so you can take the loaf out to eat.

In programming, we call that ruining the Bundle Size. When you import moment from 'moment', you're forcing the user's browser to download the entire source code of that library, including hundreds of locale files from Arabic to Zulu that you'll never use.

2. Current Perspective: Why it's a Production Disaster?

Back then, your computer was strong and the network was fast, so you thought 500kb was nothing. But at production scale with millions of users:

  • Page Load Speed (LCP): On weak 3G, adding 500kb means users have to wait an extra 3-5 seconds to see the UI. They'll leave before they even see your beautiful "3 days ago."
  • Bandwidth Cost: If you have 1 million hits, that 500kb of waste turns into 500GB of wasted bandwidth for the server every month.
  • JavaScript Parsing Time: A cheap phone doesn't just download slowly; it also takes a lot of time to "read" and understand that massive volume of code. The browser will freeze (Main thread blocked) while it's trying to load your giant library.

3. Concrete Example: The lodash and moment trap

Your old self usually did this:

// Junior's way: Bring the whole supermarket home
import _ from 'lodash'; 
const result = _.cloneDeep(myData); // Downloads 70kb just to use 1 function

import moment from 'moment';
console.log(moment().fromNow()); // Downloads over 200kb (with all those locales)

Why is this a problem? Because build tools (like Webpack) sometimes aren't smart enough to know you only use a small part, so they'll "grab" everything into the final build.

Sustainable Approach (Modern Approach):

// Get exactly what you need (Tree-shaking friendly)
import cloneDeep from 'lodash/cloneDeep'; 

// Or better, use modern, lightweight libraries (like date-fns)
import { formatDistanceToNow } from 'date-fns';

// Or best: Use native Browser APIs
const relativeTime = new Intl.RelativeTimeFormat('en').format(-3, 'day'); 
// 0 extra bytes, maximum speed!

4. Comparison: "Doing it Fast" vs "Doing it Sustainably"

CriteriaDoing it Fast (Import the whole lot)Doing it Sustainably (Optimized)
Coding SpeedVery fast, works instantlyTakes an extra 5-10 minutes of research
Bundle SizeHeavy, hard to controlLightweight, optimized
MaintenanceEasily outdated, hard to upgradeSmall, compact components, easy to replace
User ExperienceFeels "laggy" upon enteringSmooth, instant

Juniors often choose the left column because it brings an instant sense of "task complete." But a Senior will choose the right column because they understand: Less code is a performance feature.

5. Practical Lesson from "Tuition Fees"

I once saw a project's build balloon to 5MB in just 6 months of development simply because every new person on the team installed a "utility" library based on personal preference. We had to spend a whole month just refactoring, removing each library one by one and replacing them with pure code. That was the most painful period because it didn't create new features—it was just cleaning up trash left behind by intellectual laziness from the start.

The biggest lesson I want you to remember is: Before installing any library, ask yourself if you can write it with 10 lines of pure code? If the answer is yes, write it yourself. If the answer is no, find a library that allows you to import only exactly what you need.

Never become a "drag-and-drop library programmer." Be an engineer who knows how to control every byte of data sent to the user.


Notes for my 23-year-old self.

Series • Part 12 of 50

50 FRONTEND LESSONS – HARD-EARNED EXPERIENCES

NextBlog #13: When optimization becomes a burden – Don't 'memo' everything you see
Blog #11: Don't wait until 'heavy web' to lose weight for your Bundle
07Blog #7: The 'Double' Nightmare – When React StrictMode tests your patience08Blog #8: Memory Trash – The price of forgetting to 'clean up' your Event Listeners09Blog #9: Safari – The new 'Internet Explorer' of the modern era?10Blog #10: Specificity War – When !important marks the start of a civil war11Blog #11: Don't wait until 'heavy web' to lose weight for your Bundle12Blog #12: Don't bring the whole supermarket home just to buy a loaf of breadReading13Blog #13: When optimization becomes a burden – Don't 'memo' everything you see14Blog #14: The Domino Effect – When one small change crashes the whole Render system15Blog #15: The 10,000-Row Lesson – When Table Virtualization saved my career16Blog #16: Misplaced Debounce – When a localized solution becomes a system burden17Blog #17: Images vs JS – The battle for priority in the Critical Path
TP

Written by Truong Pham

Software Engineer passionate about building high-performance systems and meaningful experiences.

Read more articles