The Question
FE DesignScalable Social Media Feed Design
Design a high-performance, infinite-scrolling social media feed similar to Twitter. Focus on solving the challenges of DOM node bloat, maintaining 60fps scroll performance with rich media (images/video), implementing optimistic UI for user engagements (likes/shares), and handling real-time data synchronization without disrupting the user's scroll position. Discuss your approach to data fetching, virtualization, and state management for a seamless cross-platform experience.
React
TanStack Query
Zustand
Tailwind CSS
TypeScript
Virtualization
SSR
IndexedDB
Questions & Insights
Clarifying Questions
What is the expected scale of the feed in terms of items and media complexity?
Assumption: Thousands of tweets per session with varying media types (text, images, video) requiring high-performance virtualization.
Should the feed support real-time updates (new tweets popping up)?
Assumption: Yes, via a "See new Tweets" toast notification to avoid shifting the user's scroll position unexpectedly.
What are the primary target platforms?
Assumption: Mobile-first responsive web, targeting modern browsers with a focus on low-end device performance.
Does the feed require offline support?
Assumption: Basic "read-only" offline support for the last cached feed using local persistence.
Crash Strategy
Core Bottleneck: Rendering a massive list of complex items (Tweets) leads to DOM nodes explosion, causing scroll jank and memory leaks.
Progressive Strategy:
Virtualization Strategy: Implement windowing to ensure only visible items (plus a small buffer) exist in the DOM.
Data Orchestration: Build a robust infinite scroll hook that manages cursor-based pagination and deduplication of incoming tweets.
Performance Optimization: Utilize content-visibility and image lazy-loading to keep the main thread free during rapid scrolling.
State Management: Decouple the feed data (Domain) from the UI state (Presentation) to allow for optimistic updates (e.g., liking a tweet).
Elite Bonus Points
Adaptive Loading: Detect network speed (Network Information API) to serve lower-resolution images or disable video autoplay for users on 3G.
Render-as-you-fetch: Use Suspense and prefetching for the next page of tweets before the user reaches the bottom of the current list.
Layout Instability Prevention: Use aspect-ratio boxes for media placeholders to prevent Cumulative Layout Shift (CLS) as images load.
Design Breakdown
Requirements
Functional Requirements:
Display a chronological list of tweets.
Infinite scroll (cursor-based).
Tweet interactions (Like, Retweet, Reply).
Simple Tweet Composer at the top of the feed.
Real-time notification for new incoming tweets.
Non-Functional Requirements:
Performance: 60 FPS scrolling on mid-tier mobile devices.
Scalability: Handle 10,000+ items in the data store without UI lag.
Accessibility: Full keyboard navigation and screen reader support (ARIA live regions for new tweets).
Responsiveness: Fluid layout from 320px to 1200px.
Design Summary
Concise Summary: A virtualized, high-performance feed utilizing cursor-based pagination and optimistic UI updates for interactions.
Major Components:
FeedVirtualizer: Manages the windowing logic to render only visible Tweet components.
TweetCard: A memoized component handling rich media display and interaction logic.
FeedController: A hook-based orchestrator managing API calls, pagination state, and caching.
InteractionStore: Manages optimistic updates for likes/retweets to ensure zero-latency feedback.
CUJ Walkthrough:
User opens the app;
FeedController fetches the first page; FeedVirtualizer renders the first 5-10 tweets.User scrolls;
FeedVirtualizer calculates offsets; FeedController triggers the next page fetch when the threshold is met.User clicks 'Like';
InteractionStore updates the local UI immediately while the API call runs in the background.Simplicity Audit: This architecture uses a standard "Data-Down, Actions-Up" flow with virtualization. It avoids over-engineering global state by keeping feed data localized to the feed feature.
Architecture Decision Rationale:
Why virtualization? Necessary for any infinite scroll to prevent DOM bloat.
Requirement Satisfaction: Meets performance goals via windowing and accessibility goals via semantic HTML and ARIA roles.
System Diagram
Architecture Deep Dive
Presentation Layer
Component Hierarchy: The
App Shell provides the navigation; Main Layout defines the feed's max-width and centering. Feed Page hosts the Feed Virtualizer, which maps data to Tweet Card leaf components.Interaction Layer:
Tweet Card uses event delegation for actions. Input validation for the composer is handled client-side. Animations for "new tweet" toasts use CSS transforms for GPU acceleration.Rendering Layer: Hybrid approach. Initial feed can be SSR-ed for SEO/LCP, but subsequent pages are CSR. Virtualization is the core engine, using
React Window or TanStack Virtual.UI Frameworks / Tools: Tailwind CSS for atomic styling (keeping CSS bundle small), Headless UI for accessible components.
Application Layer
Data Fetching Layer: Uses
TanStack Query for cursor-based infinite scroll. It handles stale-while-revalidate caching and automatic retries.State Management Layer: Global state is minimal.
Interaction Store (Zustand) tracks optimistic IDs to highlight liked/retweeted items before the server confirms.Routing & Navigation: Basic SPA routing. The URL acts as a filter state (e.g.,
/home vs /explore).Domain Layer
Business Rules: Logic to calculate "Tweet Age" or "Engagement Ratios." Independent of the UI framework.
Entities / Models:
Tweet entity maps API DTOs (Data Transfer Objects) to a frontend-friendly format (e.g., converting UTC strings to Date objects).Infrastructure Layer
API / Network: RESTful endpoints with cursor tokens. Axios interceptors handle Auth headers.
Storage:
IndexedDB (via Dexie) or LocalStorage stores the last 20 tweets for instant "offline" first-paint on revisit.Wrap Up
Wrap-up
Trade-offs: Virtualization makes "Find in page" (Cmd+F) difficult; we compensate by providing a custom search or accepting the browser limitation for the sake of 60fps.
Optimization: We use
priority hints on the first 3 images in the feed to improve LCP.Future-proofing: The decoupled Domain layer allows us to switch from REST to GraphQL with minimal changes to the Presentation layer.