Explain Lazy Loading and Frontend Code Splitting
Company: Persistence
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Onsite
## Explain Lazy Loading and Frontend Code Splitting
A single-page application has grown until its initial JavaScript bundle delays interactivity. Explain lazy loading and code splitting, how they relate, and how you would introduce them without turning loading failures or layout instability into a worse user experience.
### Constraints & Assumptions
- The application has several routes, a large editor used by only some users, and images below the initial viewport.
- Some code is shared by many routes and should not be duplicated into every chunk.
- A requested chunk can be slow, missing after a deployment, or blocked by a transient network failure.
- Performance changes must be verified with user-facing measurements rather than bundle size alone.
### Part 1 — Explain Lazy Loading
Define lazy loading as a resource-loading policy. Apply it separately to below-the-fold media, route content, and an optional editor, and describe the trigger and fallback state for each.
#### What This Part Should Cover
- Deferring a resource until navigation, viewport proximity, or explicit interaction makes it useful.
- Appropriate placeholders and reserved layout space.
- Loading, error, retry, and cancellation behavior.
- Cases where eager loading or preloading is better for likely next actions.
```hint Name both the resource and its trigger
“Load later” is incomplete unless the answer says what is deferred and which event starts the load.
```
### Part 2 — Explain Code Splitting
Describe how build-time chunking and runtime dynamic imports reduce the initial JavaScript work. Choose route, feature, and shared-vendor boundaries for this application.
#### What This Part Should Cover
- The distinction between producing chunks and deciding when a chunk is requested.
- Stable shared chunks without excessive duplication.
- Avoidance of hundreds of tiny requests or one oversized common chunk.
- Deployment-safe chunk naming, caching, and recovery from a stale HTML document.
```hint Keep two decisions separate
One decision determines bundle boundaries; another determines when the browser fetches a resulting chunk.
```
### Part 3 — Roll Out and Measure the Change
Explain how you would find a useful boundary, test it, release it, and decide whether the change improved the experience.
#### What This Part Should Cover
- Bundle analysis and route-level dependency inspection.
- Lab and real-user measures for loading and interaction.
- Slow-network, cache-cold, navigation, and chunk-failure tests.
- Guardrails for error rate, layout shift, and delayed interaction after a lazy boundary.
```hint Measure the moment users care about
A smaller initial download can still be a regression if the first editor interaction now waits on a large cold chunk.
```
### What a Strong Answer Covers
- Defines lazy loading as timing and code splitting as packaging while showing how they work together.
- Selects boundaries from route and feature behavior rather than splitting every module.
- Includes accessible loading and failure states plus deployment and cache concerns.
- Validates the result with cold-cache, slow-network, and real-user evidence.
### Follow-up Questions
1. When would you preload the editor even though it is code-split?
2. How can a service worker or stale HTML produce a chunk-not-found failure after deployment?
3. Why can an overly large shared chunk erase route-splitting gains?
4. Which metric would reveal that parsing and execution, not transfer size, is the main bottleneck?
Quick Answer: Explain how lazy loading and code splitting can improve initial responsiveness in a large single-page application without harming later interactions. Candidates compare loading policy with bundle boundaries and address route and feature choices, shared chunks, placeholders, deployment failures, caching, and user-facing measurement.