Comprehensive Guide to Homepage Load Speed Optimization
This article provides a thorough, English-language guide to optimizing homepage loading speed, covering resource loading techniques, page rendering improvements, and practical Webpack, Nginx, and browser APIs with code examples for developers seeking performance gains.
When asked about performance optimization in interviews, homepage load speed is a common topic. This article summarizes a comprehensive set of techniques for optimizing the loading and rendering of a web page's home page.
Table of Contents
Resource Loading Optimization
Page Rendering Optimization
Resource Loading Optimization
Compress Assets
Use Webpack to automatically compress HTML, CSS, and JavaScript files.
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin(),
new CssMinimizerPlugin()
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
useShortDoctype: true
}
}),
new MiniCssExtractPlugin({
filename: 'styles.css'
})
]
};Enable Gzip Compression
Configure Webpack to generate Gzip files and ensure the client sends the appropriate Accept‑Encoding header.
// Request header example
Accept-Encoding: gzip, deflate, br // webpack.config.js
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
// other configuration ...
plugins: [
new CompressionPlugin({
filename: '[path][base].gz',
algorithm: 'gzip',
test: /\.(js|css|html|svg)$/,
threshold: 10240,
minRatio: 0.8
})
]
};Use Caching
Set strong cache headers on the server (example using Express).
// express server with strong cache
const express = require('express');
const path = require('path');
const app = express();
app.use((req, res, next) => {
const options = { maxAge: '1y', immutable: true };
res.set('Cache-Control', `public, max-age=${options.maxAge}, immutable`);
next();
});
app.use(express.static(path.join(__dirname, 'public'), { maxAge: '1y' }));
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});Use a CDN
Point static asset URLs to a CDN via Webpack's publicPath.
output: {
filename: '[name].[contenthash].js',
path: __dirname + '/dist',
publicPath: 'https://cdn.example.com/' // your CDN address
},Use HTTP/2
Enable HTTP/2 at the server level (example Nginx configuration).
# Nginx configuration
server {
listen 443 ssl http2;
server_name example.com;
# SSL configuration ...
}Optimize DNS Resolution
Add DNS pre‑fetch links in HTML.
<link rel="dns-prefetch" href="//example.com">Reduce HTTP Requests
Combine files, use image sprites, and optionally inline small images as base64.
// webpack.config.js
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
module.exports = {
// other configuration ...
module: {
rules: [{ test: /\.svg$/, use: ['svg-sprite-loader'] }]
},
plugins: [new SpriteLoaderPlugin()]
};Preload and Prefetch
Use the preload‑webpack‑plugin to hint the browser about critical resources.
// webpack.config.js
const PreloadWebpackPlugin = require('preload-webpack-plugin');
module.exports = {
// other configuration ...
plugins: [
new PreloadWebpackPlugin({ rel: 'preload', as: 'script', include: 'allChunks' })
]
};Use Efficient Image Formats
Convert images to modern formats such as WebP via image‑minimizer‑webpack‑plugin.
// webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
// other configuration ...
module: {
rules: [{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
use: [{
loader: ImageMinimizerPlugin.loader,
options: {
minimizerOptions: {
plugins: [['imagemin-webp', { quality: 75 }]]
}
}
}]
}]
}
};Lazy Load Images and Routes
Implement image lazy loading with IntersectionObserver and route lazy loading with Vue dynamic imports.
export default {
inserted(el) {
const loadImage = () => {
const img = el.tagName === 'IMG' ? el : el.querySelector('img');
if (img) {
img.src = img.dataset.src;
img.onload = () => el.classList.add('loaded');
}
};
const handleIntersect = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
loadImage();
observer.unobserve(el);
}
});
};
const options = { root: null, threshold: 0.1 };
const observer = new IntersectionObserver(handleIntersect, options);
observer.observe(el);
}
};Page Rendering Optimization
Optimize CSS
Place CSS links in the document head to avoid Flash of Unstyled Content (FOUC).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Example Page</title>
<!-- CSS placed at the top -->
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="styles/theme.css">
</head>
</html>Use CSS3 Animations Instead of JavaScript
Leverage GPU‑accelerated CSS transitions to reduce layout recalculations.
.box {
transition: transform 0.5s, opacity 0.5s;
}
.box:hover {
transform: translateX(100px);
opacity: 0.5;
}Place JavaScript at the Bottom
Move script tags before the closing tag (modern browsers can use async/defer).
<body>
<script src="bundle.js"></script>
</body>Use async and defer
Load external scripts with async or defer attributes.
<script src="bundle.js" async></script>
<!-- or -->
<script src="bundle.js" defer></script>Reduce and Optimize DOM Operations
Batch style changes to a single cssText assignment.
// Before
element.style.width = '100px';
element.style.height = '100px';
// After
element.style.cssText = 'width: 100px; height: 100px;';Use Virtual DOM
Adopt frameworks like React to minimize direct DOM manipulation.
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}Avoid Layout Thrashing
Combine multiple style changes into a single cssText assignment.
// Before
element.style.margin = '10px';
element.style.padding = '20px';
element.style.border = '1px solid #000';
// After
element.style.cssText = 'margin: 10px; padding: 20px; border: 1px solid #000;';Use will-change Hint
Inform the browser about upcoming changes to enable optimizations.
.box {
will-change: transform, opacity;
}Server‑Side Rendering (SSR)
Generate HTML on the server (example with Next.js / React).
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './App';
const html = renderToString(<App />);Lazy Load Resources
Defer non‑critical images and CSS/JS until needed.
<img src="image.jpg" loading="lazy" alt="Lazy loaded image">
<script>
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'non-critical-styles.css';
document.head.appendChild(link);
</script>Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
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.