#JavaScript #EventLoop Most developers think they understand the JavaScript event loop. Very few understand how it can quietly break their app. Let’s talk about Microtask Starvation 👇 In JavaScript, the event loop roughly follows this cycle: 1. Execute a macrotask (script, timer, I/O) 2. Drain ALL microtasks 3. The browser may render 4. Repeat The critical rule? 👉 𝑴𝒊𝒄𝒓𝒐𝒕𝒂𝒔𝒌𝒔 𝒂𝒓𝒆 𝒂𝒍𝒘𝒂𝒚𝒔 𝒇𝒖𝒍𝒍𝒚 𝒅𝒓𝒂𝒊𝒏𝒆𝒅 𝒃𝒆𝒇𝒐𝒓𝒆 𝒕𝒉𝒆 𝒆𝒗𝒆𝒏𝒕 𝒍𝒐𝒐𝒑 𝒎𝒐𝒗𝒆𝒔 𝒐𝒏. Now here’s where things go wrong. What is Microtask Starvation? Microtask starvation happens when microtasks keep scheduling more microtasks… …and the queue never becomes empty. function loop() { Promise.resolve().then(loop); } loop(); This creates an infinite stream of microtasks. Since the event loop must finish all microtasks before continuing: ❌ setTimeout callbacks are delayed indefinitely ❌ UI updates don’t happen ❌ User interactions feel ignored ❌ Your app appears frozen Because the event loop never proceeds to the next macrotask. 𝗪𝗵𝘆 𝘁𝗵𝗶𝘀 𝗺𝗮𝘁𝘁𝗲𝗿𝘀? Microtasks (Promises, async/await) feel lightweight, so they’re easy to overuse. But they run before the event loop continues to the next task, which means they can block: 1. Rendering 2. User interactions 3. Timers And no, the browser won’t step in and save you. It will keep executing your microtasks exactly as instructed. 𝗛𝗼𝘄 𝘁𝗼 𝗮𝘃𝗼𝗶𝗱 𝗶𝘁? You need to yield control back to the event loop. await new Promise(r => setTimeout(r, 0)); or setTimeout(fn, 0); This schedules a macrotask and allows the browser to continue processing rendering and events. 𝗧𝗵𝗲 𝘁𝗮𝗸𝗲𝗮𝘄𝗮𝘆 If your UI freezes while “nothing heavy is happening,” there’s a good chance you’ve accidentally created a microtask loop.
Microtask Starvation: The Silent App Killer
More Relevant Posts
-
Frontend Development Practice – Counter Web App 🔢 #30daysofcode challenge #day5 Built a simple interactive Counter web app using HTML, CSS, Bootstrap, and JavaScript. This project helped me understand how to handle user interactions and dynamically update UI elements in real time. Focused on DOM manipulation and event handling to control and style the counter based on its value. Key Highlights: ✅ Implemented increment, decrement, and reset functionality ✅ Practiced DOM manipulation using document.getElementById() ✅ Dynamically updated text using textContent ✅ Applied conditional styling (green, red, black) based on counter value ✅ Strengthened understanding of event handling in JavaScript #NxtWave #30daysoflearning #coding #JavaScript #HTML #CSS #Bootstrap #FrontendDevelopment #WebDevelopment #LearningByDoing #TechBeginners
To view or add a comment, sign in
-
🚨 The most common React anti-pattern beginners ignore 👀 Using index as a key. It looks simple. It removes the warning. It seems perfectly fine… But it can quietly break your UI 😵 React needs a unique key to identify each item in a list. Without proper keys, React compares items by POSITION (index), not by actual identity. That leads to: ❌ Unnecessary re-renders ❌ Wrong component updates ❌ Input values jumping between items ❌ Broken animations ❌ Lost focus in input fields ❌ Weird and hard-to-debug UI bugs Example 👇 Current List: • Bruce • Clark New List: • Diana • Bruce • Clark React thinks: ❌ Bruce changed to Diana ❌ Clark changed to Bruce ❌ New Clark added Instead of simply: ✅ Add Diana only This is exactly why index as key is considered an anti-pattern. Because index represents POSITION, not the actual item. And when items are: • added • removed • sorted • filtered • reordered …the index changes, and React gets confused. ✅ Best Solution: Use stable unique keys like: key={user.id} Now React understands: ✔ Bruce is still Bruce ✔ Clark is still Clark ✔ Diana is the new item Only the necessary UI updates happen 🚀 When is index okay? Only if ALL are true: ✔ List is completely static ✔ No adding/removing items ✔ No sorting/filtering ✔ No reordering Example: • Days of week • Months • Static menu items Best Practice Priority: 🥇 key={id} 🥈 key={uniqueString} 🥉 key={index} (only if static) Rule of Thumb 📌 If the list can change, NEVER use index as key. Small concept. Massive frontend impact. This is one of those React lessons that saves you from hours of debugging later 💯 Have you ever faced weird UI bugs because of wrong keys? 👇 #ReactJS #FrontendDevelopment #WebDevelopment #JavaScript #ReactDeveloper #CodingJourney #LearnToCode #SoftwareDevelopment #FrontendEngineer #100DaysOfCode
To view or add a comment, sign in
-
-
💡 Understanding a subtle React concept: Hydration & “bailout” behavior One interesting nuance in React (especially with SSR frameworks like Next.js) is how hydration interacts with state updates. 👉 Hydration is the process where React makes server-rendered HTML interactive by attaching event listeners and syncing state on the client. When a page is server-rendered, the initial HTML is already in place. During hydration, React attaches event listeners and syncs the client state with that UI. Here’s the catch 👇 👉 If the client-side state matches what React expects, it may skip updating the DOM entirely. This is due to React’s internal optimization often referred to as a “bailout”. 🔍 Why this matters In cases like theme handling (dark/light mode): If the server renders a default UI (say light mode ☀️) And the client immediately initializes state to dark mode 🌙 React may still skip the DOM update if it doesn’t detect a meaningful state transition 👉 Result: UI can temporarily reflect the server version instead of the actual state. 🧠 Conceptual takeaway A more reliable pattern is: ✔️ Start with an SSR-safe default (consistent with server output) ✔️ Then update state after hydration (e.g., in a layout effect) This ensures React sees a real state change and updates the UI accordingly. 🙌 Why this is fascinating It highlights how deeply optimized React is — sometimes so optimized that understanding its internal behavior becomes essential for building predictable UI. Grateful to the developer community for continuously sharing such insights that go beyond surface-level coding. 🚀 Key idea In SSR apps, correctness isn’t just about what state you set — it’s also about when React observes the change. #ReactJS #NextJS #FrontendDevelopment #WebDevelopment #JavaScript #Learning
To view or add a comment, sign in
-
-
Most developers use `useMemo()` because they heard it improves performance. But here’s the truth: `useMemo` is not for making your app “faster” magically. It is for avoiding unnecessary work. Imagine your component renders again and again because some state changes. Every render means: * functions run again * calculations run again * arrays/objects get recreated again And sometimes that becomes expensive. Example: You have a list of 10,000 products and you are filtering or sorting them on every render. Without `useMemo`, even if only a button color changes, the filtering logic runs again. const filteredProducts = products.filter(product => product.price > 1000 ) Now imagine this runs on every render. That is unnecessary work. With `useMemo`: const filteredProducts = useMemo(() => { return products.filter(product => product.price > 1000) }, [products]) Now React stores the previous result and only recalculates when `products` changes. That stored value is called memoization. Memoization = remembering the previous result so you don’t have to calculate it again. Why use `useMemo`? ✅ Prevent expensive calculations from running again ✅ Avoid unnecessary re-renders in child components ✅ Improve performance when dealing with large lists, sorting, filtering, heavy computations What problem does it solve? Without `useMemo`: * Slow UI * Lag while typing/searching * Heavy calculations on every render * Child components re-render because new object/array references are created. So if you pass it to a child component, React thinks it changed every time. const user = useMemo(() => ({ name: "Durgesh" }), []) Now the reference stays the same. But there’s a catch 👇 Do NOT use `useMemo` everywhere. `useMemo` itself has a cost. For simple calculations, just write normal code. Rule of thumb: 👉 Use `useMemo` only when: * the calculation is expensive * the value is passed to memoized child components * re-rendering is causing performance issues Don’t optimize first. Measure first. Then optimize. That’s what good React developers do. #react #javascript #webdevelopment #frontend #reactjs #useMemo #performance #coding
To view or add a comment, sign in
-
-
Most developers use `useMemo()` because they heard it improves performance. But here’s the truth: `useMemo` is not for making your app “faster” magically. It is for avoiding unnecessary work. Imagine your component renders again and again because some state changes. Every render means: * functions run again * calculations run again * arrays/objects get recreated again And sometimes that becomes expensive. Example: You have a list of 10,000 products and you are filtering or sorting them on every render. Without `useMemo`, even if only a button color changes, the filtering logic runs again. const filteredProducts = products.filter(product => product.price > 1000 ) Now imagine this runs on every render. That is unnecessary work. With `useMemo`: const filteredProducts = useMemo(() => { return products.filter(product => product.price > 1000) }, [products]) Now React stores the previous result and only recalculates when `products` changes. That stored value is called memoization. Memoization = remembering the previous result so you don’t have to calculate it again. Why use `useMemo`? ✅ Prevent expensive calculations from running again ✅ Avoid unnecessary re-renders in child components ✅ Improve performance when dealing with large lists, sorting, filtering, heavy computations What problem does it solve? Without `useMemo`: * Slow UI * Lag while typing/searching * Heavy calculations on every render * Child components re-render because new object/array references are created. So if you pass it to a child component, React thinks it changed every time. const user = useMemo(() => ({ name: "Durgesh" }), []) Now the reference stays the same. But there’s a catch 👇 Do NOT use `useMemo` everywhere. `useMemo` itself has a cost. For simple calculations, just write normal code. Rule of thumb: 👉 Use `useMemo` only when: * the calculation is expensive * the value is passed to memoized child components * re-rendering is causing performance issues Don’t optimize first. Measure first. Then optimize. That’s what good React developers do. #react #javascript #webdevelopment #frontend #reactjs #useMemo #performance #coding
To view or add a comment, sign in
-
-
🚨 JavaScript Memory Leaks — The Silent Performance Killer Ever had your app slow down over time… without any obvious reason? Chances are, you’re dealing with a memory leak. Let’s break it down 👇 🧠 What is a Memory Leak? A memory leak happens when your application keeps holding references to objects that are no longer needed, preventing JavaScript’s garbage collector from cleaning them up. Think of it like: 👉 Renting rooms in a hotel… but never checking out. ⸻ 🔥 Common Causes of Memory Leaks in JavaScript 1️⃣ Global Variables name = "Tanmay"; // Oops, accidentally global These stay in memory for the entire lifecycle of your app. ⸻ 2️⃣ Forgotten Timers & Intervals setInterval(() => { console.log("Running..."); }, 1000); If not cleared, they keep running forever. ⸻ 3️⃣ Detached DOM Elements let element = document.getElementById("btn"); document.body.removeChild(element); // Still referenced → not garbage collected ⸻ 4️⃣ Closures Holding References function outer() { let largeData = new Array(1000000).fill("🔥"); return function inner() { console.log("Still holding largeData"); }; } Closures can unintentionally “trap” memory. ⸻ 5️⃣ Event Listeners Not Removed window.addEventListener("resize", handleResize); If not removed, they stick around even when not needed. ⸻ ⚡ Why It Matters? • Slower performance 🐢 • Increased memory usage 📈 • Crashes in long-running apps 💥 ⸻ 🛠️ How to Prevent Memory Leaks ✔ Use let / const (avoid accidental globals) ✔ Clear timers → clearInterval, clearTimeout ✔ Remove event listeners when done ✔ Nullify unused references ✔ Use tools like Chrome DevTools → Memory tab ⸻ 💡 Pro Tip (Easy Memory Hook): 👉 “If something is STILL REFERENCED, it’s STILL IN MEMORY.” ⸻ As developers, we often optimize algorithms… But ignoring memory is like fixing speed on a car with a leaking fuel tank. 💬 Have you ever debugged a tricky memory leak? Share your story! #JavaScript #WebDevelopment #Frontend #Performance #CodingTips #SoftwareEngineering
To view or add a comment, sign in
-
🚀 “I built a Todo App… to understand JavaScript — not to finish it.” Sounds simple. But this one decision changed how I see frontend development. Most people build projects to ship. I built this one to understand why things work the way they do. 👉 Here’s what clicked when I went deeper: 🧠 Every click is queued — not instant The Event Loop decides when your code runs, not you. That’s why your UI doesn’t freeze—even with multiple actions. ⚡ Search smarter, not harder Debouncing with setTimeout + clearTimeout: ✔ Fewer unnecessary executions ✔ Better performance ✔ Clear understanding of Web APIs in action 🔁 Less code, more efficiency Event Delegation changed everything: ✔ One listener instead of many ✔ Cleaner logic ✔ Scales effortlessly 📦 The moment it all made sense Microtasks vs Macrotasks: • Promises → higher priority • setTimeout → lower priority ✔ Finally understood execution order in JavaScript 🎯 What this project really taught me: ✔ Async JS isn’t magic—it’s structured ✔ The browser + JS engine work as a system ✔ Smooth UI is a result of smart scheduling 🔥 The shift most developers miss: Don’t build projects just to complete them. Build them to uncover how things actually work. 💬 If you’ve built a project that changed how you think—what was it? Let’s learn from each other 👇 #JavaScript #EventLoop #FrontendDevelopment #WebDevelopment #CodingJourney #LearnInPublic #SoftwareEngineering #AsyncJavaScript
To view or add a comment, sign in
-
🔹 Understanding Controlled Components in React 🔹 When working with forms in React, one concept you must master is controlled components. 👉 A controlled component is an input element (like <input>, <textarea>, or <select>) whose value is controlled by React state instead of the DOM. 💡 Why use controlled components? Single source of truth (React state) Easier validation and debugging Better control over user input Enables dynamic UI behavior 🧠 Basic Example: import { useState } from "react"; export default function Form() { const [name, setName] = useState(""); return ( <div> <input type="text" value={name} onChange={(e) => setName(e.target.value)} /> <p>You typed: {name}</p> </div> ); } ⚙️ How it works: React state (name) holds the input value value prop binds state to input onChange updates state on every keystroke 🚀 Pro Tips: Always initialize state (avoid undefined) Use one state object for multiple inputs Handle forms with reusable handlers Combine with validation logic for better UX 📌 Controlled vs Uncontrolled: Controlled → React manages state Uncontrolled → DOM manages state (ref is used) Mastering controlled components is the foundation for building powerful forms in React applications 💪 #ReactJS #FrontendDevelopment #WebDevelopment #JavaScript #ReactTips #Coding
To view or add a comment, sign in
-
⚛️ Most React developers fix the symptom. Here's how to fix the cause. Stale closures in useState aren't a beginner mistake — they're a design decision you need to understand. This pattern silently breaks in production: const [filters, setFilters] = useState(initialFilters); useEffect(() => { const interval = setInterval(() => { fetchData(filters); // always reads initial filters // never the updated ones }, 3000); return () => clearInterval(interval); }, []); // empty deps = stale closure trap The fix most devs reach for: → Add filters to the dependency array → Now the interval resets every time filters change → Race conditions start appearing The actual fix: const filtersRef = useRef(filters); useEffect(() => { filtersRef.current = filters; }, [filters]); useEffect(() => { const interval = setInterval(() => { fetchData(filtersRef.current); // always fresh }, 3000); return () => clearInterval(interval); }, []); // stable interval, no race conditions 💡 What's happening under the hood: Every render creates a new closure. useRef gives you a mutable box that lives outside the render cycle — so your async callbacks always read the latest value without triggering re-renders. This is the difference between knowing React's API and understanding React's model. Have you run into stale closures in a production app? What was the context? #ReactJS #JavaScript #FrontendArchitecture #WebDevelopment #SoftwareEngineering
To view or add a comment, sign in
-
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development