【性能优化】电商网站性能优化:路由懒加载/图片懒加载/图片压缩/打包分析

前言

在前端项目中,性能优化是一个完整的分析过程。通常需要先通过浏览器开发者工具定位问题,再根据资源类型选择合适的优化方案,最后通过构建结果和性能工具验证优化效果。

本文以一个 Vue3 电商项目为例,记录常见的前端性能优化思路,包括:

  • 使用 Network 分析资源加载情况
  • 使用路由懒加载减少首屏 JS 体积
  • 使用图片懒加载减少非首屏图片请求
  • 使用 WebP 优化本地大图体积
  • 使用 rollup-plugin-visualizer 分析打包产物
  • 使用 Lighthouse 验证优化效果

项目技术栈:

Vue3 Vite Vue Router Pinia Element Plus Axios


一.使用 Network 分析页面资源

Chrome DevTools 的 Network 面板是前端性能分析中最常用的工具之一。

Network 面板中可以重点关注以下信息:

  • 请求数量
  • 资源体积
  • JS/CSS/图片大小
  • DOMContentLoaded时间:此时HTML解析完成,DOM树构建完成
  • Load时间:页面主要资源加载完成
  • Finish时间:Network面板中所有请求结束
  • Initiator:请求来源

对于电商项目来说,图片资源 通常占比较大。如果页面主体已经加载完成,但Finish 时间仍然很长,往往说明后续还有大量图片资源在继续加载。

在前端项目中,电商网站常常有很多的图片加载,导致首屏加载速度很慢,为此要进行优化,提高用户体验。

优化前的性能(使用谷歌浏览器无痕模式,进入网站首页的加载情况):

项目打包后体积:

JS包比较大,可以用路由懒加载降低首屏资源体积

通过network可以看到加载数据的时长

  • 101个请求:页面一共请求了 101 个资源,包括 HTML、JS、CSS、图片、接口等。
  • 已传输 37.1 MB:浏览器实际从网络下载了 37.1MB,偏大。
  • DOMContentLoaded 3.68 秒:HTML 解析完成,JS 基本开始接管页面。
  • 加载时间4.06 秒:页面 load 事件完成时间。
  • 完成用时24.10 秒 :Network 里所有请求基本结束的时间。

二.路由懒加载

在 Vue 单页应用中,如果所有页面组件都通过静态 import 导入,打包时可能会被合并到较大的主 JS 文件中。

用户进入首页时,即使没有访问登录页、购物车页、结算页,也会提前下载这些页面的代码。

我们可以将路由组件改为动态 import

javascript 复制代码
const Home = () => import('@/views/Home/index.vue')
const Detail = () => import('@/views/Detail/index.vue')

使用动态导入后,Vite 会自动进行代码分割 ,将不同页面拆分为独立 chunk。用户访问某个路由时,才加载对应页面的代码。

javascript 复制代码
 children:[
      {
        path:'',//默认子路由(默认二级路由),当访问/时该路由也会被渲染展示,与/路由同时展示
        component:Home
      },
     
      {
        path:'detail/:id',//动态路由参数
        component:Detail
      },
      {
        path:'cartlist',
        component:CartList
      }
    ]

优化前主 JS 为 409.35KB,gzip 后 147.68KB;优化后主 JS 为 125.18KB,gzip 后 49.11KB,首屏需要下载的 JS 明显减少。

主 JS 包从 409.35 kB 降到 125.18 kB ,gzip 后从 147.68 kB 降到 49.11 kB

npm run build:

npm run preview:(筛选js)

二.图片懒加载

电商项目中商品图片数量较多,如果所有图片都在页面初始化时加载,会增加首屏网络压力。

图片懒加载的核心思路是:

  • 图片没有进入视口时,不加载真实图片
  • 图片进入视口后,再设置真实src

项目里使用自定义指令,用vueuse里封装好的 useIntersectionObserver监听器来监听图片是否进入视图,如果图片进入视图,才把图片真正的地址赋给src。

javascript 复制代码
//定义懒加载插件
import { useIntersectionObserver } from '@vueuse/core'
import loadingImg from '@/assets/images/loading.gif'

export const lazyPlugin = {
  install(app){
    //懒加载指令逻辑
    app.directive('img-lazy',{
      mounted(el,binding){
        el.src = loadingImg
        //el:指令绑定的元素 img
        //binding:binding.value 指令等于号后面绑定的表达式的值 图片url
        const { stop } = useIntersectionObserver(
          el,
          ([entry]) => {
            if(entry.isIntersecting){
              //图片进入视口区域
              el.src = binding.value
              stop()
            }
          }
        )
      }
    })
  }
}

在模板中使用:

javascript 复制代码
<img v-img-lazy="item.picture" alt="" />

优化前,页面初始化时图片请求数量多,部分非首屏商品图片也会提前请求。优化后,将首页新鲜好物、分类浮层、商品列表等非首屏图片统一改为自定义懒加载指令。

刷新后不滚动时,图片请求为 43 个,传输约 1.67MB;滚动页面后,图片请求增加到 54 个,传输增加到 3.76MB,说明非首屏图片是在进入视口后才开始加载。

图片懒加载后network数据。

三.图片压缩

图片懒加载解决的是"什么时候加载",但不能减少图片本身体积。

接口返回的图片资源前端不适合直接改,但是一些本地的图片我们可以进行压缩成其他格式减小体积。 比如登录页背景图 png 改成 webp 格式 ,通常 WebP 会比 PNG/JPG 小很多,尤其适合网页背景图。可以使用在线工具进行格式转换,比如Squoosh。网址:https://squoosh.app/

将png图片转换为webp图片使用。

四.打包体积分析

npm run build 可以看到构建产物大小,但无法直观看到每个 chunk 内部由哪些模块组成。

此时可以使用 rollup-plugin-visualizer 生成打包分析报告,用于观察 bundle 内部组成。

如何使用rollup-plugin-visualizer?

1.npm install rollup-plugin-visualizer -D

2.修改 vite.config.js(在 vite.config.js 中按需开启)

javascript 复制代码
import { visualizer } from 'rollup-plugin-visualizer'

export default defineConfig(({ mode }) => ({
  plugins: [
    vue(),
    mode === 'analyze' && visualizer({
      filename: 'dist/stats.html',
      open: true,
      gzipSize: true,
      brotliSize: true
    })
  ].filter(Boolean)
}))

3. 在 package.json 中添加分析命令

javascript 复制代码
{
  "scripts": {
    "build:analyze": "vite build --mode analyze"
  }
}

4.运行分析 npm run build:analyze

5.成功后会生成 dist/stats.html

从分析结果可以看到,项目主要由 Vue 核心、vue-router、Pinia、axios、@vueuse/core、Element Plus 以及业务页面代码组成。路由懒加载后,Home、Detail、Login、CartList、Checkout、Pay 等页面已经被拆分为独立 chunk,说明代码分割生效。

同时,Element Plus 相关组件如 button、input、checkbox、popover、dialog 等也以按需方式进入构建产物,没有把整个组件库一次性打进主包。

六.Lighthouse 性能验证

优化完成后,可以使用Lighthouse 对页面进行测试。

指标含义:

  • FCP:首次内容绘制,表示用户第一次看到页面内容的时间
  • LCP:最大内容绘制,通常与首屏大图或主要内容有关
  • TBT:总阻塞时间,反映 JS 是否长时间阻塞主线程
  • CLS:布局偏移,反映页面加载过程中是否发生明显抖动
  • Speed Index:页面视觉加载速度

从结果来看,页面首屏展示速度较快,JS 没有明显阻塞,布局也较稳定。

Lighthouse 仍然提示了一些后续优化方向,例如:

相关推荐
Aolith15 小时前
我是怎么把个人论坛首页性能从80分优化到100分的(附踩坑全记录)
vue.js·性能优化
likerhood15 小时前
ConcurrentHashMap详细讲解(java)
java·开发语言·性能优化
H Journey1 天前
C++性能优化
c++·性能优化
布吉岛的石头1 天前
ClickHouse性能优化:OLAP数据库实战,让查询飞起来
数据库·clickhouse·性能优化
天天进步20151 天前
魔音漫创源码解析:性能优化: Electron 环境下的图片管理与文件系统协议处理优化
javascript·性能优化·electron
solo_992 天前
使用Perfetto debug trace查看超时slice
性能优化
黄俊懿2 天前
复合索引设计指南:最左前缀 & 字段排座次
数据库·sql·mysql·adb·性能优化·dba·db
源远流长jerry2 天前
Linux 网络性能优化:从应用到内核
linux·运维·服务器·网络·网络协议·性能优化
ChaITSimpleLove2 天前
优化 WSL2 性能:为 Docker 和 K8s 定制高效内存配置指南
docker·容器·性能优化·kubernetes·wsl2·windows开发·pwsh