稀土掘金技术社区 2024年11月02日
首页加载速度优化
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章围绕性能优化,特别是首页加载速度优化展开,涵盖资源加载优化和页面渲染优化两方面,包括多种具体的优化方法和技术。

🎯资源加载优化方面,涉及压缩资源、启用Gzip压缩、使用缓存、利用CDN、优化DNS解析、减少HTTP请求数、预加载和预获取、采用更高效图片格式、实现图片懒加载和路由懒加载等多种方法,并详细介绍了相应的Webpack配置及代码示例。

🎨页面渲染优化方面,包含优化CSS、使用CSS3动画替代JavaScript动画、将JavaScript放在页面底部、运用async和defer属性、减少和优化DOM操作、使用Virtual DOM、避免布局抖动、使用will-change提示浏览器优化、采用服务端渲染以及延迟加载资源等内容,并给出了具体的实现方式和代码片段。

📦在资源压缩方面,通过Webpack配置自动压缩HTML、CSS和JavaScript文件,还介绍了生成Gzip压缩文件的方法以及服务端配置强缓存的示例。

原创 Var985 2024-11-02 09:02 重庆

点击关注公众号,“技术干货”即使达!

要说面试的时候问到最多的问题,那性能优化绝对是躲不开的话题,基本每个公司面试我都遇到了相关问题,其中,首页加载速度优化又是其中最常问的问题,网上的文章比较零零散散,没有一个总结到十分满意的,于是自己便来总结一下

点击关注公众号,“技术干货” 及时达!


这张图是我发现的比较宝藏,比较全面的一张首页加载优化图,便以此图来进行相关总结

目录

一. 资源加载优化

    压缩资源

    启用Gzip压缩

    使用缓存

    使用内容分发网络 (CDN)

    使用HTTP/2

    优化DNS解析

    减少HTTP请求数

    预加载和预获取

    使用更高效的图片格式

    图片懒加载和路由懒加载


二. 页面渲染优化

    优化CSS

    使用CSS3动画代替JavaScript动画

    将JavaScript放在页面底部

    使用async和defer属性

    减少和优化DOM操作

    使用Virtual DOM

    避免布局抖动

    使用will-change提示浏览器优化

    使用服务端渲染 (SSR)

    延迟加载资源

资源加载优化

压缩资源

通过 Webpack 配置,可以自动压缩 HTML、CSS 和 JavaScript 文件。

// 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: {
        minimizetrue,
        minimizer: [
            new TerserPlugin(),
            new CssMinimizerPlugin()        ]    },
    plugins: [
        new HtmlWebpackPlugin({
            template'./src/index.html',
            minify: {
                collapseWhitespacetrue,
                removeCommentstrue,
                removeRedundantAttributestrue,
                useShortDoctypetrue            }        }),
        new MiniCssExtractPlugin({
            filename'styles.css'        })    ]};

启用Gzip压缩

通过 Webpack 配置,可以生成 Gzip 压缩文件。

//在请求时会带上该请求头,声明它支持的压缩算法Accept-Encoding: gzip, deflate, br
// webpack.config.js
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
    // 其他配置...
    plugins: [
        new CompressionPlugin({
            filename'[path][base].gz',
            algorithm'gzip',
            test/\.(js|css|html|svg)$/,
            threshold10240,
            minRatio0.8        })    ]};

使用缓存

服务端通过配置协商缓存和强缓存,来实现请求的缓存,这里以强缓存为例

// 设置强缓存
const express = require('express');
const path = require('path');
const app = express();
// 强缓存中间件
app.use((req, res, next) => {
    const options = {
        maxAge'1y'// 缓存一年
        immutabletrue    };
    // 设置 Cache-Control 头
    res.set('Cache-Control'`public, max-age=${options.maxAge}, immutable`);    next();});
// 将静态文件托管到 public 目录
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}`);});

使用内容分发网络 (CDN)

通过 Webpack 配置,将静态资源路径指向 CDN。

output: { 
filename'[name].[contenthash].js',
path: __dirname + '/dist',
publicPath'https://cdn.example.com/' // 指向你的 CDN 地址 },

使用HTTP/2

启用 HTTP/2 需要在服务器配置中完成,Webpack 本身不直接支持 HTTP/2 配置。

# Nginx 配置server {    listen 443 ssl http2;    server_name example.com;    # SSL 配置}

优化DNS解析

在 HTML 中添加 DNS 预获取。

<link rel="dns-prefetch" href="//example.com">

减少HTTP请求数

通过 Webpack 配置,合并文件和使用图片精灵,同时我们可以将一些小图片转为base64格式(虽然会减少请求,但是转为base64资源体积会变大一点,所有不推荐进行大图片base64处理)

// webpack.config.js
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
module.exports = {
    // 其他配置...
    module: {
        rules: [            {
                test/\.svg$/,
                use: ['svg-sprite-loader']            }        ]    },
    plugins: [
        new SpriteLoaderPlugin()    ]};

预加载和预获取

使用 Webpack 插件进行预加载和预获取。

// webpack.config.js
const PreloadWebpackPlugin = require('preload-webpack-plugin');
module.exports = {
    // 其他配置...
    plugins: [
        new PreloadWebpackPlugin({
            rel'preload',
            as'script',
            include'allChunks'        })    ]};

使用更高效的图片格式

通过 Webpack 配置,使用现代图片格式,如 WebP(但是得注意浏览器兼容性)。

// webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
    // 其他配置...
    module: {
        rules: [            {
                test/\.(jpe?g|png|gif|svg)$/i,
                type'asset',
                use: [                    {
                        loader: ImageMinimizerPlugin.loader,
                        options: {
                            minimizerOptions: {
                                plugins: [
                                    ['imagemin-webp', { quality75 }]                                ]                            }                        }                    }                ]            }        ]    }};

图片懒加载和路由懒加载

通过IntersectionObserver API和自定义指令来实现图片懒加载,路由懒加载即用vue的动态路由@import引入即可

export default {    inserted(el) {
        const loadImage = () => {
            const imageElement = el.tagName === 'IMG' ? el : el.querySelector('img');            
            if (imageElement) {                imageElement.src = imageElement.dataset.src;
                imageElement.onload = () => el.classList.add('loaded');            }        };
        const handleIntersect = (entries, observer) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {                    loadImage();                    observer.unobserve(el);                }            });        };
        const options = {
            rootnull,
            threshold0.1        };
        const observer = new IntersectionObserver(handleIntersect, options);        observer.observe(el);    }};

页面渲染优化

优化CSS

将 CSS 外链放在页面顶部,因为这样可以确保页面在加载时尽快应用样式,从而避免样式闪烁(FOUC,Flash of Unstyled Content)并提升用户体验。

<!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 外链放在页面顶部 -->
    <link rel="stylesheet" href="styles/main.css">
    <link rel="stylesheet" href="styles/theme.css">
</head>
</html>

使用CSS3动画代替JavaScript动画

使用 CSS3 动画而不是 JavaScript 动画(原理:transform等css3属于是独立的图层,不会影响其他图层,而且使用GPU加速),以减少重排和重绘。

.box {
    transition: transform 0.5s, opacity 0.5s;}
.box:hover {
    transformtranslateX(100px);
    opacity0.5;}

将JavaScript放在页面底部

将 JavaScript 文件放在 <body> 标签的底部(现代浏览器支持async和defer后就不需要了)

<body>
    <!-- Content -->
    <script src="bundle.js"></script>
</body>

使用async和defer属性

使用 asyncdefer 属性加载外部 JavaScript 文件。

<script src="bundle.js" async></script>
<!-- 或者 -->
<script src="bundle.js" defer></script>

减少和优化DOM操作

减少不必要的 DOM 操作,合并多次操作为一次。

// Before
element.style.width = '100px';
element.style.height = '100px';
// After
element.style.cssText = 'width: 100px; height: 100px;';

使用Virtual DOM

使用虚拟 DOM 技术(如 React)减少直接操作 DOM 带来的开销。

// 使用 React 示例
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>
    );}

避免布局抖动

在操作 DOM 和样式时,避免可能导致重排的操作,对样式进行统一处理

// 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;';

使用will-change提示浏览器优化

使用 will-change 属性可以提示浏览器即将发生的变化,使浏览器提前进行优化。

.box {
    will-change: transform, opacity;}

使用服务端渲染 (SSR)

使用服务端渲染技术提前生成 HTML 内容,减少客户端渲染的负担。

// 使用 Next.js 进行 SSR 示例
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './App';
const html = renderToString(<App />);

延迟加载资源

延迟加载图片和非关键 CSS、JavaScript 文件。

<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>

点击关注公众号,“技术干货” 及时达!


阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

性能优化 资源加载 页面渲染
相关文章