Frontend Development 24 min read

Front‑End Performance Optimization: Loading‑Time and Runtime Techniques

This article explains why front‑end performance optimization is crucial for user retention and conversion, outlines loading‑time and runtime optimization categories, and provides practical techniques such as DNS prefetching, HTTP/2 adoption, resource compression, lazy loading, virtual lists, event delegation, and code‑level best practices with concrete code examples.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Front‑End Performance Optimization: Loading‑Time and Runtime Techniques

Why Performance Optimization Matters

Website performance directly influences user retention and conversion rates, making performance‑optimization skills an essential assessment point for front‑end developers.

Two Main Categories

Loading‑time optimization

Runtime optimization

Loading‑time Performance

Loading‑time optimization aims to make the page load faster, e.g., by reducing white‑screen time and first‑screen (first paint) time.

White‑screen Time Calculation

Placing a script before </head> allows you to capture the white‑screen duration:

<script>
    new Date().getTime() - performance.timing.navigationStart
</script>

First‑screen Time Calculation

Executing the same calculation inside the window.onload event yields the first‑screen time:

new Date().getTime() - performance.timing.navigationStart

Key Loading Optimizations

DNS prefetching – reduce DNS lookup latency (typically 20‑120 ms).

Use HTTP/2 – benefits include multiplexing, header compression, and server push.

Reduce the number of HTTP requests.

Compress and merge files (JS, CSS, HTML, images).

Server‑side rendering.

Serve static assets via CDN.

Resource caching to avoid duplicate loads.

DNS Prefetch Implementation

Inform the browser to pre‑resolve domains using meta tags or <link rel="dns-prefetch" href="..."> :

<meta http-equiv="x-dns-prefetch-control" content="on" />
<link rel="dns-prefetch" href="http://example.com" />
Note: Overusing dns‑prefetch can cause redundant DNS queries.

HTTP/2 Advantages

HTTP/2 provides faster parsing, multiplexed streams, header compression (HPACK), and optional server push, offering several times the loading speed of HTTP/1.1.

File Compression & Merging (Webpack Example)

Common webpack plugins for compression:

JS: UglifyPlugin

CSS: MiniCssExtractPlugin

HTML: HtmlWebpackPlugin

Images: image-webpack-loader

Extract common code with splitChunks :

optimization: {
  runtimeChunk: { name: 'manifest' },
  splitChunks: {
    cacheGroups: {
      vendor: {
        name: 'chunk-vendors',
        test: /[\\/]node_modules[\\/]/,
        priority: -10,
        chunks: 'initial'
      },
      common: {
        name: 'chunk-common',
        minChunks: 2,
        priority: -20,
        chunks: 'initial',
        reuseExistingChunk: true
      }
    }
  }
},

SVG Icons & Font Icons

Using vector‑based SVG or icon fonts yields tiny files, fast rendering, and easy styling (size, color).

On‑Demand Code Loading

Split each route into its own bundle and load it dynamically with import() . Use [contenthash] in filenames to enable long‑term caching:

output: {
  filename: '[name].[contenthash].js',
  chunkFilename: '[name].[contenthash].js',
  path: path.resolve(__dirname, '../dist')
},

Babel Runtime Optimization

Install @babel/plugin-transform-runtime and @babel/runtime to share helper functions instead of duplicating them in every compiled file.

"plugins": ["@babel/plugin-transform-runtime"]

Server‑Side Rendering (SSR)

SSR returns ready‑made HTML from the server, improving first‑paint speed and SEO at the cost of added server complexity.

Defer Loading of JavaScript

Place CSS in the <head> and JavaScript at the bottom of the page, or add the defer attribute to scripts to avoid blocking rendering.

CDN for Static Resources

Deploy assets to geographically distributed CDN nodes to shorten the physical distance between user and server, reducing latency.

Image Optimization

Sprite Sheets

Combine many small icons into a single sprite image and display portions via background‑position . Tools such as webpack‑spritesmith or gulp.spritesmith automate this.

Lazy Loading

Delay image loading until the element enters the viewport. Example HTML and JavaScript:

<img original-src="https://example.com/image.png" />
const img = document.querySelector('img');
img.src = img.getAttribute('original-src');

Libraries like lazysizes , verlok/lazyload , or tuupola/lazyload simplify this pattern.

Runtime Performance Optimization

Reduce Repaints & Reflows

Reflows (layout) are triggered by DOM changes that affect geometry; they always cause repaints, while repaints alone do not trigger reflows. Strategies include avoiding table layouts, batching read/write DOM operations, changing styles via a single class, and using position: absolute or fixed where possible.

// Bad – multiple reads/writes cause several reflows
div.style.left = div.offsetLeft + 1 + 'px';
div.style.top = div.offsetTop + 1 + 'px';
// Good – cache values, trigger only one reflow
var curLeft = div.offsetLeft;
var curTop = div.offsetTop;
div.style.left = curLeft + 1 + 'px';
div.style.top = curTop + 1 + 'px';

Avoid Page Jank

Browsers aim for 60 FPS (≈16.6 ms per frame). Any JavaScript or style work that exceeds this budget causes jank. Only the necessary steps (style → layout → paint → composite) are executed; avoiding unnecessary layout or paint work helps maintain smooth frames.

Long List Optimization

Render only visible items using virtual lists. Determine container size, item size, and render only the subset that falls within the viewport. Popular libraries: react-virtualized , vue-virtual-scroll-list , ngx-virtual-scroller .

Scroll Event Performance

Throttle or debounce scroll handlers to limit execution frequency. Throttling runs the handler at a fixed interval (e.g., every 300 ms); debouncing runs it after the user stops scrolling for a set delay.

Web Workers

Offload CPU‑intensive tasks to a background thread using Web Workers, communicating via postMessage and onmessage , thus keeping the UI thread responsive.

Code‑Level Tips

Event Delegation

// Good – single listener on parent
document.querySelector('ul').onclick = (event) => {
  const target = event.target;
  if (target.nodeName === 'LI') {
    console.log(target.innerHTML);
  }
};
// Bad – many listeners on each
document.querySelectorAll('li').forEach(e => {
  e.onclick = function() { console.log(this.innerHTML); };
});

If‑else vs. Switch

When many discrete cases exist, a switch statement typically evaluates faster than a chain of if‑else statements.

if (state == 0) { console.log('Pending'); }
else if (state == 1) { console.log('Learning'); }
// …

switch (state) {
  case 0: console.log('Pending'); break;
  case 1: console.log('Learning'); break;
  // …
}

Use Flexbox for Layout

Modern flexbox layouts generally perform better than older float‑based or table‑based layouts.

In summary, careful attention to loading strategies, resource handling, DOM manipulation patterns, and leveraging modern browser features can dramatically improve front‑end performance.

frontendPerformanceOptimizationJavaScriptwebRuntimeLoading
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.