Q197: Code Splitting, Prefetching and Loading Strategy
What Interviewers Want To Evaluate
This question checks whether you can load code at the right time. Interviewers want route splitting, component splitting, dynamic imports, prefetching, preload, Suspense, loading states, network priority, cache behavior, and avoiding both over-eager and too-late loading.
Senior answers should describe strategy by user intent.
Short Interview Answer
Code splitting breaks JavaScript into chunks so users do not download every feature up front. Prefetching loads likely future code at lower priority, while preloading loads critical current resources earlier. Good loading strategy follows user intent: load current-route essentials immediately, prefetch likely next routes or interactions, dynamically import heavy rare features, and show stable loading UI for anything that can wait.
Detailed Interview Answer
Loading strategy has a simple goal:
load what the user needs now
prepare what the user is likely to need next
delay what the user may never use
This is more useful than splitting randomly.
Route Splitting
Most modern frameworks split by route.
That means /practice/javascript should not necessarily ship the same code as /questions/[slug].
Route splitting is the first level of protection.
But route splitting alone may not be enough when one route contains several heavy optional features.
Component Splitting
Component-level dynamic import is useful for heavy delayed features.
Examples:
rich code editor
chart library
map
video player
PDF viewer
admin report
large syntax highlighter
rare settings panel
Do not split tiny components just to split them. Every chunk has overhead.
Dynamic Import Example
const HeavyEditor = lazy(() => import("./HeavyEditor"));
function PracticePage() {
return (
<Suspense fallback={<EditorSkeleton />}>
<HeavyEditor />
</Suspense>
);
}
The loading boundary should match the delayed feature.
Prefetching
Prefetching loads likely future resources before the user asks.
Good candidates:
next route linked in viewport
next step in wizard
details page after hover
practice console after user opens practice section
latest question after homepage load
Prefetching should not compete with critical current-page work.
Preloading
Preload is for resources needed for the current page soon.
Examples:
LCP image
critical font
critical CSS
important route chunk in a known transition
Preloading too much can hurt performance by stealing bandwidth from truly critical resources.
Suspense and Loading UI
Code-split UI needs good fallback design.
Good fallback:
matches final size
keeps stable shell visible
does not shift layout
explains pending state when needed
does not block unrelated UI
Bad fallback makes code splitting feel broken.
Cache Behavior
Chunks should be cacheable.
Hashed filenames let browsers reuse unchanged chunks across deployments.
But frequent changes to shared chunks can reduce cache value.
Review:
vendor chunk stability
shared component churn
route-specific chunk ownership
long-term caching headers
deployment invalidation behavior
Over-Splitting
Too many chunks can hurt.
Costs:
extra requests
waterfalls
more coordination
late loading gaps
harder debugging
cache fragmentation
Split meaningful heavy boundaries, not every file.
Under-Splitting
Under-splitting ships too much up front.
Signs:
large initial JS
unused route features loaded immediately
heavy libraries on simple pages
slow hydration
poor mobile startup
Bundle analysis reveals this.
Common Mistakes
A common mistake is dynamically importing the LCP content.
Another mistake is preloading too many resources.
Another mistake is adding lazy boundaries with poor skeletons.
Another mistake is ignoring hover or viewport prefetch opportunities.
Another mistake is splitting without measuring the waterfall.
Senior Trade-Offs
Loading strategy balances startup speed and later interaction smoothness.
The right answer depends on user behavior.
Measure current route cost and next-action likelihood before choosing eager, prefetch, or lazy loading.
Debugging Workflow
When loading feels slow:
inspect network waterfall
identify critical resources
check chunk sizes
check lazy chunk timing
check prefetch behavior
check Suspense fallback
verify cache headers
remove over-eager code
preload only critical resources
measure field impact
Interview Framing
Define splitting, prefetching, and preloading. Then explain current need, likely next need, delayed features, Suspense fallback, and trade-offs.
Revision Notes
Loading strategy should follow user intent and resource priority.
Key Takeaways
Split by meaningful user paths, not arbitrary component boundaries.
Follow-Up Questions
- What is code splitting?
- How is prefetch different from preload?
- When should dynamic imports be used?
- Why not dynamically import LCP content?
- What makes a good loading fallback?
- What is over-splitting?
- What is under-splitting?
- How do cache headers matter?
- How does route behavior guide prefetching?
- How do you inspect loading waterfalls?
How I Would Answer This In A Real Interview
I would say I load current-route essentials immediately, prefetch likely next interactions, and dynamically import heavy rare features with stable Suspense fallbacks. I would validate the strategy with bundle analysis, network waterfalls, cache behavior, and field metrics.