11. Design the frontend architecture for Instagram Stories.
Design the browser frontend for Instagram Stories, beginning by defining the user flow and the scope you will cover. Explain the page and component boundaries, story and viewer state, sequencing through a creator's items and between creators, image or video loading, progress timing, user controls, prefetching, and navigation persistence. Cover loading, empty, media-error, expired-story, offline or slow-network, background-tab, and resumed-session behavior; keyboard and screen-reader access; memory cleanup; analytics boundaries; and the browser-facing data contracts needed without expanding into unrelated storage internals.
At a high level, the frontend should let users open Stories, move through one creator’s items, continue to the next creator, and return to the feed without losing context. I would use the diagram’s CSR single-page design with an initial HTML shell, route-based code splitting, and a StoryViewer component tree. URL, local, shared, remote, and persisted browser state have separate jobs. Media is prefetched carefully. The main trade-off is smooth playback versus extra bandwidth and memory.
The goal is to make Instagram Stories feel fast and continuous in the browser. A user can enter from the Stories tray, an avatar, or a deep link. The main challenge is coordinating media playback, progress timing, navigation, network work, and saved position without wasting bandwidth or memory. I would explain the design through rendering, routes and components, state, data flow, failure handling, accessibility, and safe release controls.
- Should Stories work well on slow mobile networks and desktop browsers?
- How much offline viewing should the browser support?
- Should users resume the same Story after reopening the viewer?
- Are keyboard, screen-reader, RTL, and reduced-motion behaviors required?
- Can the browser prefetch a few upcoming Stories?
The browser gets static assets through the CDN and loads the HTML shell plus JavaScript from the web application path. I would use the diagram’s CSR single-page approach with hydration of the initial shell. After that, route changes stay inside the browser.
Route-based code splitting loads only JavaScript needed for the current route. The service worker can cache the shell, selected data, and media for offline use.
The main routes are /, /stories, /stories/:userId, and a not-found route. The Story Viewer Page contains StoryViewer, ProgressBar, MediaPlayer, TapZones, TopBar, ReplyBar, and ErrorBoundary.
URL state keeps userId, storyIndex, source, and ref. Local UI state keeps playing, muted, fullscreen, loading, error, reply, and progress values. Shared client state keeps activeUserId, storiesByUser, seenMap, theme, and accessibility preferences.
Remote data contains users, Story metadata, media URLs, and viewer interactions. IndexedDB keeps cached Stories. localStorage keeps preferences. sessionStorage keeps navigation state for session restore.
The tray uses GET /api/v1/feed/stories. Opening a creator uses GET /api/v1/stories/{userId}. Story data includes fields such as storyId, type, media URL, thumbnail URL, duration, timestamp, and seen state.
MediaPlayer loads image or video media from the Media CDN. The browser prefetches the next two or three Stories from the current creator and the first Story from following creators. When progress finishes, it moves to the next Story. After the creator ends, it can move to the next user’s first unseen Story.
Views use POST /api/v1/stories/view. Replies use POST /api/v1/stories/reply. Analytics uses POST /api/v1/analytics/event. Analytics is separate from viewer correctness.
Initial loading shows a skeleton. Partial data shows available Stories. An empty result shows the empty state. Media loading shows buffered progress. A media error can retry, skip, or use a fallback. An expired Story shows the expired state.
On slow or offline networks, cached Stories can remain available with an offline banner. When navigation makes an old request unnecessary, the browser should cancel that work when possible and ignore late results that no longer match the active Story. Background tabs pause playback and preserve position. Resumed sessions restore that position.
The viewer revokes object URLs after dismissal and releases media on unload. It also limits decoded frames to control memory.
The viewer uses ARIA roles, labels, live regions, visible focus, and a focus trap. Arrow keys move between Stories. Space or Enter controls playback. Escape exits. Responsive layouts support phones, tablets, and desktop screens. RTL layouts and locale-aware strings support different languages.
Client error reporting captures JavaScript errors and rejected work. Performance monitoring uses Core Web Vitals and custom metrics. Feature flags support gradual rollout, and a remote kill switch supports safe rollback.
The benefit is fast movement after the first page load. Code splitting keeps the first JavaScript smaller. Prefetching also makes the next Story feel faster. The downside is more network use and memory. Cached Stories help on slow or offline connections, but cached data may be older than the latest remote result. Saving navigation state improves resume behavior, but adds cleanup work. A service worker improves offline use, but has its own browser lifecycle. The design limits prefetching, releases media quickly, and respects Data Saver and reduced-motion settings.
The interviewer wants to see whether the candidate can turn a familiar product into clear frontend responsibilities. They are testing judgment about state ownership, media loading, navigation, browser storage, accessibility, failures, and memory. They also want clear trade-offs instead of a list of tools. A strong answer keeps remote systems as external boundaries and focuses on what the browser must do correctly.



