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

前言

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

本文以一个 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 仍然提示了一些后续优化方向,例如:

相关推荐
cfm_291410 小时前
Redis高并发缓存架构设计与性能优化实战
redis·缓存·性能优化
画江湖Test10 小时前
Redis 块的原理
数据库·redis·缓存·性能优化
侑虎科技11 小时前
Unity预计算辐照度全局光照PRTGI实践与拓展(上)
性能优化
数据库小学妹13 小时前
InnoDB内存架构解密:Buffer Pool与性能优化实战
数据库·经验分享·sql·性能优化·架构
ImTryCatchException13 小时前
Android 性能优化实战手册:从理论到落地的完整方法论
android·性能优化
zhiSiBuYu051714 小时前
用 OpenCLAW 重写 CUDA 内核:原理、实践与性能优化
性能优化
熬夜喝酒写代码17 小时前
Android性能分析之实操
性能优化
taocarts_bidfans18 小时前
外贸独立站系统性能优化实战:解决全球访问延迟与转化流失问题
性能优化·跨境电商·独立站·外贸独立站
六月雨滴18 小时前
Oracle 归档日志性能优化
数据库·oracle·性能优化
在繁华处19 小时前
Java从零到熟练(十):JVM基础与性能优化
java·jvm·性能优化