BRUCE_FEBRUCE_FE

EN/CH Mode

BRUCE_FE JS Interview Notes - Complete Analysis of Code Splitting and Dynamic Import

Deep dive into code splitting and dynamic imports in frontend optimization techniques, including implementation methods, performance comparisons, and complete answers to common interview questions.

ๅฝฑ็‰‡็ธฎๅœ–

Lazy to read articles? Then watch videos!

Basic Concepts

Code Splitting is a technique for optimizing frontend application performance that allows splitting JavaScript bundles into smaller chunks, loading them only when needed instead of loading all code at once.

Dynamic Import is the primary method for implementing code splitting, allowing programs to dynamically load modules at runtime rather than loading all modules when the application starts.

// Traditional way - Load all at once
import { heavyFunction } from './heavyModule';

// Dynamic import - Load on demand
button.addEventListener('click', async () => {
  const { heavyFunction } = await import('./heavyModule');
  heavyFunction();
});

Why do we need Code Splitting?

Problem Scenario

Imagine an e-commerce website with pages for home, product list, shopping cart, checkout, and admin dashboard. Without code splitting:

  • 1. Users download the entire application's JS code when visiting the homepage
  • 2. Including pages they might never visit (like admin dashboard)
  • 3. Long initial load time, affecting user experience

Benefits Comparison

Without Code SplittingWith Code Splitting
Single large JS bundle (2-5MB+)Multiple small JS bundles (200-500KB)
Long initial load timeShort initial load time
Delayed page displayQuick page display
High bandwidth usageOn-demand loading, optimized bandwidth

Implementation Methods

1. Route-based Code Splitting

// Implementation with React Router + React.lazy
import { Suspense, lazy } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

// Lazy load page components
const Home = lazy(() => import('./pages/Home'));
const Shop = lazy(() => import('./pages/Shop'));
const Cart = lazy(() => import('./pages/Cart'));

function App() {
  return (
    <BrowserRouter>
      <Suspense fallback={<div>Loading...</div>}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/shop" element={<Shop />} />
          <Route path="/cart" element={<Cart />} />
        </Routes>
      </Suspense>
    </BrowserRouter>
  );
}

2. Component-based Code Splitting

import { lazy, Suspense, useState } from 'react';

// Lazy load heavy component
const HeavyChart = lazy(() => import('./components/HeavyChart'));

function Dashboard() {
  const [showChart, setShowChart] = useState(false);
  
  return (
    <div>
      <button onClick={() => setShowChart(true)}>
        Show Chart
      </button>
      
      {showChart && (
        <Suspense fallback={<div>Loading chart...</div>}>
          <HeavyChart />
        </Suspense>
      )}
    </div>
  );
}

Dynamic Import Principles

Dynamic Import is an ECMAScript feature that uses the import() function to dynamically load modules:

  • 1. Returns a Promise object
  • 2. Asynchronously loads specified modules
  • 3. Loads only when needed, doesn't block the main thread
  • 4. Supports conditional loading
// Conditional dynamic loading
function loadModule(condition) {
  if (condition) {
    import('./moduleA.js')
      .then(module => {
        module.doSomething();
      })
      .catch(error => {
        console.error('Module loading failed:', error);
      });
  } else {
    import('./moduleB.js')
      .then(module => {
        module.doSomethingElse();
      });
  }
}

Relationship between Dynamic Import and Lazy Loading

  • 1. Dynamic Import is a language-level feature that provides the ability to load modules on demand
  • 2. Lazy Loading is a design pattern that uses Dynamic Import to implement deferred loading
  • 3. Lazy Loading can be used not only for code splitting but also for resources like images and videos

๐Ÿ”ฅ Common Interview Questions

(1) What's the difference between Code Splitting and Dynamic Import?

Answer: Code Splitting is an optimization technique aimed at splitting code into multiple chunks. Dynamic Import is a method to implement Code Splitting, using import() syntax to dynamically load modules at runtime. Their relationship is: Code Splitting is the goal, Dynamic Import is the tool.

Next.js 15 Bundle Size Comparison:

ใ€Without Code Splittingใ€‘
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                       โ”‚
โ”‚  Main Bundle (1.2MB)                                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”‚
โ”‚  โ”‚ Page Base Code  โ”‚ Chart Lib       โ”‚ Other Deps    โ”‚โ”‚
โ”‚  โ”‚ (200KB)         โ”‚ (600KB)         โ”‚ (400KB)       โ”‚โ”‚
โ”‚  โ”‚                 โ”‚ Including D3.js  โ”‚               โ”‚โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ”‚
โ”‚                                                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  Initial Load: 1.2MB (Download all even if chart not viewed)


ใ€With Code Splittingใ€‘
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                               โ”‚  โ”‚                   โ”‚
โ”‚  Main Bundle (600KB)          โ”‚  โ”‚  Chart Chunk     โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”‚  โ”‚  (600KB)         โ”‚
โ”‚  โ”‚ Page Base   โ”‚ Other Deps  โ”‚โ”‚  โ”‚  - Chart Lib     โ”‚
โ”‚  โ”‚ Code        โ”‚ (400KB)     โ”‚โ”‚  โ”‚  - D3.js         โ”‚
โ”‚  โ”‚ (200KB)     โ”‚             โ”‚โ”‚  โ”‚  - Related Deps  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ”‚  โ”‚                  โ”‚
โ”‚                               โ”‚  โ”‚                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  Initial Load: 600KB               On-demand: +600KB
  (50% reduction in initial load)

(2) When should we use Code Splitting?

Answer: The following scenarios are particularly suitable for code splitting:

Application ScenarioWhy Code Splitting is Needed
Large Single Page Applications (SPA)Loading all JS at once in SPAs leads to long initial load times
Applications with many third-party librariesThird-party libraries are usually large, can be loaded on demand after splitting
Websites with complex admin featuresRegular users don't need to load admin-related code
Features that are large but rarely usedFeatures like charts and editors are only used in specific scenarios, no need to load initially
Applications needing first-screen load optimizationAfter splitting, critical path code can be loaded first, improving first-screen speed

(3) What challenges might arise when implementing Code Splitting and how to address them?

Answer:

  1. 1. Load failure handling: Use try/catch or catch method in Promise to handle load failure
  2. 2. Load state: Use React Suspense or custom loading indicator
  3. 3. Repeat loading: Use Webpack SplitChunksPlugin to extract shared code
  4. 4. Cache issue: Configure appropriate cache strategy and file name hashing
  5. 5. Preload key modules: Use <link rel="preload"> to preload important resources