Skip to main content

Design a News Feed (Frontend)

Concepts: Virtualization (Windowing), Infinite Scroll, Intersection Observer API, Optimistic Updates, State Management, Real-Time Updates (WebSocket/SSE), Image Lazy Loading, Skeleton Screens

Requirements

Functional Requirements

RequirementDescription
Display postsRender posts with text, images, and videos
Infinite scrollLoad additional content as user scrolls
Real-time updatesDisplay new posts without page refresh
InteractionsSupport like, comment, and share actions
Responsive designAdapt layout to different screen sizes

Non-Functional Requirements

RequirementTarget
Initial load< 2 seconds
Scroll performance60 FPS
Memory usage< 200MB on mobile devices

Component Architecture

Loading diagram...

State Management

State structure: The feed state maintains a normalized data structure with posts stored in a Map (keyed by ID for O(1) lookups), a postIds array maintaining display order, hasMore boolean for pagination, isLoading for loading states, a cursor for pagination, and a newPostsCount for unread post notifications.

Actions: The state handles fetching posts (start, success, error states), adding new posts from real-time updates, and updating individual posts for optimistic updates.

State PropertyPurpose
postsNormalized post data for O(1) lookups
postIdsMaintains display order
cursorEnables cursor-based pagination
newPostsCountTracks unread posts for notification

Infinite Scroll Implementation

Intersection Observer triggers data fetching when the user scrolls near the bottom.

Implementation approach: Create a custom hook that maintains a ref to an IntersectionObserver. The hook returns a callback ref to attach to the last element in the list. When the last element enters the viewport and more content is available, trigger the loadMore function. Disconnect and recreate the observer when dependencies change to prevent stale closures.

ConfigurationPurpose
rootMarginTrigger before element enters viewport
thresholdPercentage of element visibility required

Virtual Scrolling

Virtual scrolling renders only visible items, reducing DOM node count.

Implementation approach: Track the scroll position and calculate which items are visible based on item height and viewport size. Maintain start and end indices for the visible range, adding buffer items above and below. The outer container maintains the full height (total items multiplied by item height) to preserve correct scrollbar behavior. Use CSS transforms to position the visible items correctly within the container. On scroll events, recalculate the visible range and update state.

ApproachDOM NodesMemory Usage
Render allO(n)High
Virtual scrollingO(viewport)Constant

Real-Time Updates

WebSocket connection receives new posts without polling.

Implementation approach: Establish a WebSocket connection when the component mounts. Listen for incoming messages, parse the JSON data, and dispatch an action to update state with the new post. Close the connection on component unmount to prevent memory leaks.

New post indicator: Render a clickable indicator showing the count of new posts when count is greater than zero. Clicking the indicator loads the new posts into the feed.

Update StrategyDescription
Show indicatorDisplay count of new posts; user clicks to load
Auto-prependInsert new posts at top automatically
HybridAuto-update if scrolled to top; show indicator otherwise

Optimistic Updates

Optimistic updates provide immediate feedback before server confirmation.

Implementation approach: When the user performs an action (such as liking a post), immediately dispatch the state change to update the UI. Then make the API call asynchronously. If the API call succeeds, no further action is needed since the UI is already correct. If the API call fails, dispatch a reverting action to restore the previous state and display an error message to the user.

ScenarioBehavior
SuccessUI already updated; no additional action
FailureRevert to previous state; display error

Performance Considerations

AreaTechnique
Memory managementUnmount off-screen video players
Image loadingLazy load with placeholder; use srcset for responsive images
AccessibilityKeyboard navigation; screen reader announcements
Offline supportCache feed data in IndexedDB or localStorage
Error handlingRetry failed requests; display error states

Design Trade-offs

DecisionOptionsConsiderations
PaginationCursor vs offsetCursor handles insertions/deletions correctly
State normalizationNested vs flatFlat structure enables efficient updates
Virtual scrolling libraryreact-window vs customLibrary handles edge cases; custom offers flexibility
Real-time transportWebSocket vs SSEWebSocket for bidirectional; SSE for server-push only