Frontend Performance Optimization: Common Issues and Solutions for Large‑Scale Projects
Large‑scale front‑end projects suffer from oversized bundles, unnecessary listeners, deep cloning, and mutable state, causing latency and crashes; the article explains how to diagnose these problems with Chrome DevTools and Webpack tools and resolves them through bundle splitting, tree‑shaking, memoisation, immutable patterns, and caching.
As front‑end applications grow, performance problems become critical, especially in large, complex projects where a small data dependency can cause page jank or crashes.
The article, based on the evolution of the Quick BI data‑visualisation platform, summarises common front‑end performance issues and provides practical solutions.
Typical causes
Oversized resource bundles (tens of megabytes) leading to long download times on weak networks and slow parsing.
Unnecessary data‑flow listeners (e.g., hooks + redux patterns) that trigger re‑renders even when only a small part of the state changes.
Heavy use of _.cloneDeep or similar deep‑clone utilities that duplicate large objects.
Mutable data that is hard to trace, causing unpredictable re‑renders.
These issues manifest as increased first‑paint latency, higher CPU usage, and in extreme cases browser crashes.
Diagnosis tools
Chrome DevTools Network tab to inspect bundle size.
Chrome DevTools Performance flame graph to locate long‑running tasks.
Webpack stats (via webpack --profile --json > ./build/stats.json ) and webpack-bundle-analyzer to visualise module composition.
Chrome Coverage to identify dead code.
React Profiler to count component renders.
Example of a large bundle analysis command:
webpack --profile --json > ./build/stats.json
webpack-bundle-analyzer ./build/stats.jsonRemediation strategies
1. Bundle analysis and splitting
Use splitChunks in Webpack 4 (or later) to create shared chunks and limit parallel requests. Example configuration:
module.exports = {
//...
optimization: {
splitChunks: {
chunks: 'async',
minSize: 20000,
minRemainingSize: 0,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
automaticNameDelimiter: '~',
enforceSizeThreshold: 50000,
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
};Ensure third‑party libraries larger than 400 KB are loaded asynchronously (dynamic import() ).
2. Tree‑shaking and side‑effect handling
Mark packages as side‑effect‑free in package.json ( "sideEffects": false ) or configure module.rules accordingly. Avoid export * as … syntax which can break tree‑shaking.
3. Reduce unnecessary data‑flow listeners
Wrap components with React.memo and memoise expensive calculations with useMemo or React.useMemo . Example:
const Foo = () => { // 1. React.memo can avoid re‑render when props unchanged
const result = calc(); // 2. Move heavy logic into useEffect or useMemo
return
; // 3. useMemo around render output if needed
};4. Avoid deep cloning of large objects
Replace _.cloneDeep with more selective copying or immutable libraries that share unchanged sub‑structures. Example of a problematic clone:
// a.tsx
export const a = {
name: 'a',
};
// b.tsx
import { a } = b;
saveData(_.cloneDeep(a)); // deep clone before persistingConsider custom immutable helpers that only clone the parts that actually change.
5. Detect and control mutable data
Use Object.freeze during debugging to surface illegal mutations:
const obj = {
prop: 42
};
Object.freeze(obj);
obj.prop = 33; // Throws in strict modeOr employ a proxy‑based watcher:
const a = { b: { c: { d: 123 } } };
watchObject(a);
const c = a.b.c;
c.d = 0; // Prints: Modify: "a.b.c.d"These techniques reveal where a property is read, written, and the call stack that performed the change.
6. Cache expensive results
Store computation results in WeakMap or similar caches to avoid repeated work.
Overall, the article stresses a “performance‑first” mindset: keep bundles small, eliminate dead code, minimise mutable state, and leverage memoisation and caching throughout the React/Redux stack.
Amap Tech
Official Amap technology account showcasing all of Amap's technical innovations.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.