惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Register - Security
The Register - Security
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
N
Netflix TechBlog - Medium
量子位
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
H
Help Net Security
D
Docker
D
DataBreaches.Net
T
Tailwind CSS Blog
阮一峰的网络日志
阮一峰的网络日志
B
Blog
博客园 - 聂微东
Apple Machine Learning Research
Apple Machine Learning Research
Google DeepMind News
Google DeepMind News
The Cloudflare Blog
F
Full Disclosure
GbyAI
GbyAI
F
Fortinet All Blogs
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
人人都是产品经理
人人都是产品经理
Recent Announcements
Recent Announcements
博客园 - Franky
MongoDB | Blog
MongoDB | Blog
有赞技术团队
有赞技术团队
博客园 - 叶小钗
小众软件
小众软件
V
Visual Studio Blog
月光博客
月光博客
Stack Overflow Blog
Stack Overflow Blog
The GitHub Blog
The GitHub Blog
Recorded Future
Recorded Future
J
Java Code Geeks
雷峰网
雷峰网
P
Privacy & Cybersecurity Law Blog
C
Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
AWS News Blog
AWS News Blog
Webroot Blog
Webroot Blog
美团技术团队
N
News | PayPal Newsroom
G
Google Developers Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
博客园_首页
V
Vulnerabilities – Threatpost

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
How React Works (Part 1)?Motivation Behind React Fiber: Time Slicing & Suspense
Sam Abaasi · 2026-05-02 · via DEV Community

Motivation Behind React Fiber: Time Slicing & Suspense

Series: How React Works Under the Hood
Level: Intermediate to Advanced
Prerequisites: Basic React knowledge. Bonus: if you've read How JavaScript Works — you'll feel right at home.


Introduction

You've used React. You've felt that lag — the input that stutters, the page that freezes for half a second, the animation that just doesn't feel right. But have you ever wondered why React had to completely rewrite its entire internal engine just to fix it?

In 2017, the React team announced React Fiber — a ground-up rewrite of React's internals. Not the API. Your JSX and components stayed the same. But the engine underneath, the thing that actually decides how and when work gets done, was thrown out and rebuilt from scratch.

To understand why Fiber was necessary — not just useful, but necessary — we need to start where the React team started. This entire article is grounded in Dan Abramov's talk at JSConf Iceland 2018. If you want to watch it alongside reading, here it is:

🎬 Dan Abramov — Beyond React 16 | JSConf Iceland 2018

Now let's get into it.


⚡ The Core Question

"With vast differences in computing power and network speed, how do we deliver the best user experience for everyone?"

This isn't a warm-up. It's the exact design challenge the React team was solving. Think about who uses your app:

  • A developer on a MacBook Pro with fiber internet
  • A user in rural Southeast Asia on a 3-year-old Android phone with a 3G connection
  • Someone on a mid-range laptop on a crowded café WiFi

React runs on all of these. And in 2017, it was doing a poor job of adapting to any of them. The problems fell into two distinct categories.

CPU/IO → solutions → Fiber


🖥️ CPU Problems — The Cost of Rendering

These are problems caused by expensive computation. When React updates your UI, it has to do real work: creating DOM nodes, calling render functions, reconciling old and new trees, applying changes to the DOM. On a powerful machine, this might take 5ms. On a low-powered mobile device, the exact same work might take 50ms or more.

CPU problems look like:

  • A complex chart re-rendering while you're typing
  • Mounting a large component tree on initial load
  • Re-rendering a long list when one item changes

🌐 IO Problems — The Cost of Waiting

These are problems caused by time spent waiting for things to arrive — data from an API, a JavaScript bundle from a CDN, an image. The code is fine. The device is fine. You're just waiting on the network.

IO problems look like:

  • Data-fetching waterfalls — fetch A, then B, then C, each blocking the next
  • Code splitting — loading a bundle before a page can render
  • Showing wrong loading states because data arrived faster or slower than expected

Both needed new solutions. And as we'll see, both solutions required the exact same capability from React's engine. But first — let's see the problem in action.


🎬 The Demo That Changed Everything

The best way to feel this problem is to see it. Jump to 2:57 in Dan's talk — this is the moment the demo lands.

The app: an input field at the top, a detailed chart below. The rule: the more characters you type, the more detailed the chart gets. Both updates — the input and the chart — happen at the same time.

The Demo That Changed Everything

Watch the input. There's a clear delay between pressing a key and seeing the character appear. The browser is so busy computing the chart that it can't process keystrokes fast enough. The thread is blocked for the entire duration of the render — which might be 50, 80, even 100ms — and the user feels every millisecond of it.

Dan put the root problem precisely:

"The underlying problem is that the update is big and synchronous — once React starts rendering, it cannot stop."

This is visible directly in the React source code. In synchronous mode, the work loop looks like this:

// From React source — synchronous mode
function workLoopSync() {
  while (workInProgress !== null) {
    performUnitOfWork(workInProgress);
  }
}

Enter fullscreen mode Exit fullscreen mode

workLoopSync vs workLoopConcurrent

It's a plain while loop with no exit condition other than finishing everything. Once React starts, it runs to completion. There is no way to pause it from the outside.


🩹 The Attempted Fix: Debouncing

The most natural workaround: instead of updating the chart on every keystroke, wait until the user pauses typing, then do one big update.

debounced version — input is responsive but chart lags, feels disconnected

Better? A little. But it has three real problems.

1. It's not adaptive to the device. Debouncing uses a fixed delay — say 300ms. If the user's machine is powerful enough to render instantly, they still wait 300ms. If it's slow, 300ms might not even be enough time for the render to finish without freezing.

2. It still locks up when it fires. Try enabling CPU throttling in DevTools (4–6x slowdown, simulating a low-end phone). Even with debouncing, the moment the update fires, the browser locks up completely. You've moved the jank — not eliminated it.

3. It doesn't help with mounting. Debouncing can delay an update, but when you first mount a large component tree, there's nothing to debounce. React mounts it all at once, synchronously. During that time, nothing in the page is interactive — click events don't register, animations freeze.

The problem isn't when the update fires. It's that the update is synchronous and uninterruptible when it does.


💡 What If React Could Pause?

What if React could start rendering the chart update, notice that a keystroke arrived, pause the render, handle the keystroke immediately, then resume from exactly where it stopped?

The total amount of work is identical. But the experience is completely different — because users get immediate feedback on their input while the expensive work finishes quietly in the background.

To understand why this requires a completely new engine, we need to talk about frames.


🎞️ The 16ms Frame Budget

Browsers aim to run at 60 frames per second. The math:

1000ms ÷ 60 frames ≈ 16.67ms per frame

Enter fullscreen mode Exit fullscreen mode

Every ~16ms, the browser needs to execute JavaScript, recalculate styles, lay out the page, and paint pixels to the screen. If JavaScript takes more than ~16ms in a continuous burst, the browser misses that frame. You see jank — stuttering, freezing, lag.

frame budget — one long sync task drops frames vs sliced work fits each frame

Old React had no awareness of this budget at all. A single render could take 100ms and React would march through it, never yielding control, never letting the browser breathe.


⏱️ Time Slicing

Time Slicing is React's solution to the CPU problem.

The core idea: instead of doing all rendering in one continuous chunk, React slices that work into small pieces and checks between each piece whether something more urgent has arrived. This is exactly what the concurrent version of the work loop does differently:

// From React source — concurrent mode
function workLoopConcurrent() {
  while (workInProgress !== null && !shouldYield()) {
    performUnitOfWork(workInProgress);
  }
}

Enter fullscreen mode Exit fullscreen mode

Spot the difference from workLoopSync: !shouldYield(). After every single unit of work, React asks the Scheduler: "Is it time to yield?"

Here's the actual shouldYield logic from the React Scheduler source:

function shouldYieldToHost() {
  const timeElapsed = getCurrentTime() - startTime;
  if (timeElapsed < frameInterval) {
    return false; // still have budget — keep working
  }
  return true; // time's up — yield to the browser
}

Enter fullscreen mode Exit fullscreen mode

Each task is given about 5ms. When that time is up, React pauses. The browser gets a chance to handle user input and paint. Then React resumes from exactly where it left off.

The result:

async version — input updates instantly on every keystroke, chart renders gradually in background

The input updates immediately on every keystroke. The chart still renders — it just does so across multiple frames instead of one big block. The total work is the same. The experience is night and day.

Dan described the properties precisely at JSConf Iceland:

"We've built a generic way to ensure that high-priority updates don't get blocked by a low-priority update, called time slicing. If my device is fast enough, it feels almost like it's synchronous; if my device is slow, the app still feels responsive. It adapts to the device thanks to the requestIdleCallback API. Notice that only the final state was displayed — the rendered screen is always consistent and we don't see visual artifacts of slow rendering causing a janky user experience."

Three properties to lock in:

  • Feels synchronous on fast devices — slices are so small and fast you never notice them
  • Feels responsive on slow devices — high-priority work (keystrokes) always gets through
  • Only the final state is shown — no intermediate render states flash on screen

🌿 The Git Metaphor

Dan used a metaphor in his talk that makes prioritization intuitive.

Without time slicing, React is like working directly on main. An urgent bug comes in mid-feature — you can't fix it. You have to finish the feature first.

With time slicing, React works like a proper branching workflow. You start on a feature branch — the low-priority chart render. An urgent task arrives — a keystroke. You handle it on main first, then rebase your feature branch on top when you're done.

React does the rebasing automatically. The low-priority render continues from where it stopped, now applied on top of the most current state. You never think about it.

Git branch metaphor — sync vs async prioritization

⏳ Suspense

If Time Slicing solves the CPU side, Suspense solves the IO side.

Dan introduced it this way:

"We've built a generic way for components to suspend rendering while they load async data, which we call suspense. You can pause any state update until the data is ready, and you can add async loading to any component deep in the tree without plumbing all the props and state through your app and hoisting the logic."

The concept: instead of manually managing loading states with isLoading flags and scattered useEffect fetches, a component can declare that it's waiting and React handles the rest.

function MovieDetails({ id }) {
  // If data isn't cached yet, this suspends — throws a Promise
  const movie = movieCache.read(id);
  return <div>{movie.title}</div>;
}

<Suspense fallback={<Spinner />}>
  <MovieDetails id={42} />
</Suspense>

Enter fullscreen mode Exit fullscreen mode

Internally, when a component suspends, it throws a Promise. React catches it at the nearest <Suspense> boundary, shows the fallback, and retries the render when the Promise resolves. We'll go deep on the exact mechanics — including how this connects to algebraic effects — in Part 4.

Suspense mechanism — throw Promise, catch at boundary, retry on resolve

What's powerful is how it adapts to network conditions:

"On a fast network, updates appear very fluid and instantaneous without a jarring cascade of spinners that appear and disappear. On a slow network, you can intentionally design which loading states the user should see and how granular or coarse they should be, instead of showing spinners based on how the code is written. The app stays responsive throughout."

And the key point Dan closed with:

Suspense demo — navigating the app while a subtree loads in background, no spinner waterfall

"Importantly, this is still the React you know. This is still the declarative component paradigm that you probably like about React."

The mental model for you as a developer doesn't change. The engine underneath does.


🔗 The Common Thread: Interrupting

Here's what ties both features together.

Time Slicing and Suspense look completely different — one is about CPU, one is about IO. But they share one fundamental requirement:

React needs to be able to interrupt what it's doing and resume it later.

  • Time Slicing: interrupt to yield within the 16ms frame budget
  • Suspense: interrupt to wait for async data

Same capability. This is exactly why React needed Fiber.

The old React engine used JavaScript's native call stack to track all rendering work. And the native call stack has a hard limitation: you cannot pause it from the outside. Once a stack of function calls starts executing, it runs to completion. There is no JavaScript API to say "stop here, do something else, resume from this exact frame."

Matheus Albuquerque explained the solution beautifully in his React Summit 2022 talk:

"We can think of the Fiber architecture as a React-specific call stack model that gives full control over scheduling of what should be done. And a Fiber itself is basically a stack frame for a given React component."

And crucially — unlike native stack frames, Fibers are just plain JavaScript objects. React can create them, inspect them, pause them, delete them, and resume them whenever it wants. Sam Galson put the key insight in one sentence:

"Fiber is a reimplementation of the stack, specialized for React components. The advantage of reimplementing the stack is that you can keep stack frames in memory and execute them however — and whenever — you want."

native JS call stack (opaque, uninterruptible

This gives us React's internal pipeline, as described by jser.dev:

  • Trigger — something changes (setState, event). React registers the work.
  • Schedule — the Scheduler, a priority queue, decides when and in what order work happens.
  • Render — React walks the Fiber tree and figures out what changed. This phase is interruptible. This is where Time Slicing and Suspense live.
  • Commit — React applies changes to the real DOM. Synchronous. Cannot be interrupted.

React 4 phases — Trigger → Schedule → Render → Commit

Fiber makes the Render phase interruptible. Everything else follows from that.


🗺️ What's Coming in This Series

This was the why. The rest of the series is the how — each part built around one problem and one solution.

Part Title Core story
Part 2 Why React Had to Build Its Own Execution Engine JS call stack can't pause → React builds Fiber + Scheduler
Part 3 How React Finds What Actually Changed Re-rendering everything is too slow → the Reconciler + keys
Part 4 The Idea That Makes Suspense Possible Algebraic effects → how Suspense and ErrorBoundary actually work
Part 5 The React Lifecycle From the Inside When useEffect and useLayoutEffect fire and why
Part 6 How State Actually Works useState, useRef, dispatch, and the commit state phase
Part 7 The Trap of Vibe Coding useCallback What causes re-renders — before reaching for memo and useCallback
Part 8 Server Components & Hydration: The Real Story How React moved rendering to the server — and what it cost
Part 9 The Complete Picture: From a Keystroke to a Pixel Every layer of React working together as one system

🎬 Watch These Talks

This article is a distillation. The primary sources are worth your time — here's what to watch and why:

Dan Abramov — Beyond React 16 | JSConf Iceland 2018 (33 min)
The talk this entire article is based on. Key moments: the demo at 2:57, the async version revealed at 6:10, the Git metaphor at 8:16, and the Suspense demo from 15:40.

Matheus Albuquerque — Inside Fiber: the In-Depth Overview | React Summit 2022 (27 min)
The deepest walkthrough of FiberNode internals I've found. Start at 2:11 for the Fiber-as-call-stack explanation that directly connects to Part 2 of this series.

Sam Galson — Magic in the web: coroutines, continuations, fibers | React Advanced London (~30 min)
The computer science behind React's approach — coroutines, continuations, algebraic effects, and why Fiber is the shape it is. Essential background for Parts 2 and 3.


🙏 Sources & Thanks

A huge thank you to everyone whose work made this article possible:

  • Dan Abramov — for Beyond React 16 and for the Git metaphor that makes Time Slicing click
  • Matheus Albuquerque — for the clearest explanation of FiberNode internals at React Summit 2022. Transcript via gitnation.com
  • Sam Galson — for connecting React to the wider CS theory of fibers, coroutines, and continuations. Full article: Continuations, coroutines, fibers, effects (YLD Blog)
  • Sophie Alpert & the React teamSneak Peek: Beyond React 16 (React Blog) — the official writeup with Dan's exact quotes
  • jser.dev — the best source-level analysis of React internals on the internet. The workLoopSync, workLoopConcurrent, shouldYieldToHost, and the 4-phase model in this article all come from JSer's series — especially the overview, the scheduler breakdown, and the Lanes deep dive
  • Lydia Hallie — for in-row and non-in-row fetching explanations and for the JavaScript visualizations that shaped this series' style

Part 2 is next — JavaScript's call stack is why React couldn't do any of this. Here's what React built instead. 🔧


Tags: #react #javascript #webdev #tutorial