当前位置: 首页 > news >正文

前端常用的性能优化方案

目录

      • 性能分析工具
        • lighthouse
        • Webpack Bundle分析
      • 开发阶段
        • 按需引入
        • 路由懒加载
      • 打包阶段
        • 打包配置减少包体积
          • 配置压缩
          • 分包
        • 资源预加载/预请求
      • 部署阶段
        • 开启http2
        • 静态资源缓存
        • gzip压缩

性能优化主要在三个阶段进行:开发阶段、开发结束后的打包阶段、项目部署上线阶段

首先需要知道性能优化要达到的目的就是让页面加载更快,也就是需要让代码打包后的体积尽可能的小以及让资源请求时机分配更合理

在我独立开发的博客全栈项目也用到了性能优化,在项目开发结束后不进行优化直接部署上线后后台的lighthouse打分只有50多分,性能很差,白屏时间也长,经过一系列的优化后再次部署上线,前台lighthouse跑分100分,后台也有80多分,加载速度有了很大的提升。

前台lighthouse:

前台lighthouse.jpg

后台lighthouse:

后台lighthouse.jpg

性能分析工具

lighthouse

谷歌浏览器自带的开发者工具,在项目部署上线后可以f12找到lighthouse对项目进行跑分,lighthouse不仅能通过评分直观的看到项目的整体性能情况,还能提出项目的性能问题,可以依照提出的问题对项目进行优化

Webpack Bundle分析

webpack中提供了对打包的项目文件体积直观展示的插件webpack-bundle-analyzer,安装后在vue.config.js中配置,然后在执行了打包命令打包结束后就会自动打开浏览器展示打包的各文件体积,可以直观的看到哪些文件体积过大,也能看到哪些依赖包项目并没有用到却忘了移除,可以通过这个插件去优化项目的包体积

// vue.config.js配置
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {configureWebpack: {plugins: [new BundleAnalyzerPlugin()],},
}

效果图:

在这里插入图片描述

开发阶段

开发过程中按需引入、懒加载、请求合理化、代码精简等

按需引入

往往一个项目中需要用到很多的第三方依赖,而在开发中也许用不到依赖的所有方法和组件,这时候就需要对第三方依赖进行按需引入,只引入代码中需要用到的组件或方法,以减少打包时的包体积;比如项目中使用element组件库就尽量使用官网提供的按需引入的方法

路由懒加载

SPA中一个很重要的提速手段就是路由懒加载,当打开页面时才去加载对应文件,我们利用Vue的异步组件和webpack的代码分割(import())就可以轻松实现懒加载了。

但当路由过多时,请合理地用webpack的魔法注释对路由进行分组,太多的chunk会影响构建时的速度

    // 进入register页面时才会加载对应的路由组件{path: 'register',name: 'register',component: () => import(/* webpackChunkName: "user" */ '@/views/user/register'),}

在开发过程中也需要注意合理使用请求,网络请求也是性能优化的一方面,在项目开发过程中需要注意请求的时机,合理分配请求,去除无用请求等

打包阶段

打包配置减少包体积

webpack/vite打包阶段对代码进行压缩、图片压缩、分包、去除无用代码、资源预加载等操作让代码包体积减小以及合理分配资源请求,从而实现部署上线后缩短请求时间等

对webpack/vite进行配置也是性能优化中很重要的一环,通过合理的打包配置可以大幅减少项目包体积。

配置压缩

vue-cli配置图片压缩以及gzip压缩:

module.exports = {// 修改已有的plugins/loader时使用chainWebpackchainWebpack: config => {// 压缩图片// 需要 npm i -D image-webpack-loaderconfig.module.rule("images").use("image-webpack-loader").loader("image-webpack-loader").options({mozjpeg: { progressive: true, quality: 65 },optipng: { enabled: false },pngquant: { quality: [0.65, 0.9], speed: 4 },gifsicle: { interlaced: false },webp: { quality: 75 }});},// 添加新的plugins/loader以及webpack配置项时使用configureWebpackconfigureWebpack: config => {// 开启 gzip 压缩// 需要 npm i -D compression-webpack-pluginconst plugins = [];if (IS_PROD) {plugins.push(new CompressionWebpackPlugin({filename: "[path].gz[query]",algorithm: "gzip",test: productionGzipExtensions,threshold: 10240,minRatio: 0.8}));}config.plugins = [...config.plugins, ...plugins];}
}

vite配置图片压缩、gzip压缩、移除console.log:

    import { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'//引入gzip压缩import viteCompression from 'vite-plugin-compression'//压缩图片import viteImagemin from 'vite-plugin-imagemin'// https://vitejs.dev/config/export default defineConfig({//配置打包公共根路径base: "./",plugins: [vue(),//gzip压缩viteCompression({verbose: true,disable: false,threshold: 10240,algorithm: 'gzip',ext: '.gz',}),//图片压缩viteImagemin({gifsicle: {optimizationLevel: 7,interlaced: false},optipng: {optimizationLevel: 7},mozjpeg: {quality: 20},pngquant: {quality: [0.8, 0.9],speed: 4},svgo: {plugins: [{name: 'removeViewBox'},{name: 'removeEmptyAttrs',active: false}]}})],//生产环境配置build: {//移除console.logminify: 'terser', // 默认为esbuild,需要安装terser -DterserOptions: {compress: {// drop_console: true, // 生产环境移除console// drop_debugger: true // 生产环境移除debugger}}}})
分包

vue-cli3的默认优化是将所有npm依赖都打进chunk-vendor,但这种做法在依赖多的情况下导致chunk-vendor过大,可以在vue.config.js中配置分包策略,将第三方依赖包单独打包,避免打包后单一文件过大导致请求加载缓慢。

    optimization: isProd ? {splitChunks: {chunks: 'all',maxInitialRequests: Infinity, // 默认为3,调整为允许无限入口资源minSize: 20000, // 20K以下的依赖不做拆分cacheGroups: {vendors: {// 拆分依赖,避免单文件过大拖慢页面展示// 得益于HTTP2多路复用,不用太担心资源请求太多的问题name(module) {// 拆包const packageName = module.context.match(/[\/]node_modules[\/](.*?)([\/]|$)/)[1]// 进一步将Ant组件拆分出来,请根据情况来// const packageName = module.context.match(/[\/]node_modules[\/](?:ant-design-vue[\/]es[\/])?(.*?)([\/]|$)/)[1]return `npm.${packageName.replace('@', '')}` // 部分服务器不允许URL带@},test: /[\/]node_modules[\/]/,priority: -10,chunks: 'initial'}}},runtimeChunk: { name: entrypoint => `runtime-${entrypoint.name}` }} : {}
  1. vue inspect > output.js --mode production 可以查看最终配置
  2. 分包这块需要根据实际情况做对应处理,才能取得比较好的效果,总之多看文档多试就对了
资源预加载/预请求
标签的rel属性的两个可选值。Prefetch,预请求,是为了提示浏览器,用户未来的浏览有可能需要加载目标资源,所以浏览器有可能通过事先获取和缓存对应资源,优化用户体验。Preload,预加载,表示用户十分有可能需要在当前浏览中加载目标资源,所以浏览器必须预先获取和缓存对应资源。

Prefetch、Preload在某些场景下可以有效优化用户体验。

Vue-Cli3默认会使用preload-webpack-plugin对chunk资源做preload、prefetch处理,入口文件preload,路由chunk则是prefetch。

一般来说不需要做特别处理,如果判断不需要或者需要调整在vue.config.js中配置即可

部署阶段

服务器部署项目用nginx开启http2、静态资源缓存、资源压缩等减少项目包的请求时间和次数等

项目部署阶段借助nginx也可以对项目性能进行优化。

开启http2

http2有着多路复用和头部信息压缩的特性,项目开启http2可以同时处理多个请求,加快请求时间,开启http2之前需要给项目开启https,具体怎么开启https以及http2可以看我这篇文章:网站使用nginx部署ssl证书开启https(开启http2)

静态资源缓存

nginx还可以配置静态资源缓存,对项目的静态资源配置缓存后在资源第一次请求后会将资源缓存下来,后续就可以直接使用缓存,在缓存到期之前都不会再次请求该静态资源,可以加快资源获取时间

#静态资源缓开启缓存location ~ .*.(gif|jpg|jpeg|png|bmp|swf)${# 这里同样需要反向代理,不然请求路径会是haixtx.cn:82,会出现404proxy_pass http://114.55.75.3:8000;expires 30d;}location ~ .*.(js|css)?${proxy_pass http://114.55.75.3:8000;expires 12h;}
gzip压缩

nginx也可以配置gzip压缩,HTTP协议中用头部字段Accept-EncodingContent-Encoding对「采用何种编码格式传输正文」进行了协定,请求头的Accept-Encoding会列出客户端支持的编码格式。当响应头的Content-Encoding指定了gzip时,浏览器则会进行对应解压

一般浏览器都支持gzip,所以Accept-Encoding也会自动带上gzip,所以我们需要让资源服务器在Content-Encoding指定gzip,并返回gzip文件

    #开启和关闭gzip模式gzip on;#gizp压缩起点,文件大于1k才进行压缩gzip_min_length 1k;# gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间gzip_comp_level 6;# 进行压缩的文件类型。gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript ;# nginx对于静态文件的处理模块,开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩gzip_static on# 是否在http header中添加Vary: Accept-Encoding,建议开启gzip_vary on;# 设置gzip压缩针对的HTTP协议版本gzip_http_version 1.1;

虽然上面配置后Nginx已经会在响应请求时进行压缩并返回Gzip了,但是压缩操作本身是会占用服务器的CPU和时间的,压缩等级越高开销越大,所以我们通常会一并上传gzip文件,让服务器直接返回压缩后文件,所以还需要在项目打包阶段配置gzip,具体配置上面已经讲过了

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Pandas行列变换指南:数据重塑的艺术
  • LeetCode刷题笔记 | 3 | 无重复字符的最长子串 | 双指针 | 滑动窗口 | 2025兴业银行秋招笔试题 | 哈希集合
  • 连接未来:幂简集成引领API新时代
  • 大数据技术原理-Hadoop的安装
  • c++ 初始值设定项列表(initializer_list)
  • 大模型日报 2024-08-03
  • 解决电脑缺少.NET组件?手把手教你轻松解决
  • Go语言实现多协程文件下载器
  • 【Java 第六篇章】泛型
  • 聚鼎科技:装饰画怎么做盈利更快
  • C# 实现改造 GooFlow 流程图插件与数据库应用的结合
  • Linux系统性能调优实战:从基础到进阶的全方位指南
  • 【C++修炼之路 第七章】模拟实现 list 类模板
  • redis面试(四)ZSet数据结构
  • JavaScript输出数据的方法?
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • Babel配置的不完全指南
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • Java基本数据类型之Number
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • Node + FFmpeg 实现Canvas动画导出视频
  • passportjs 源码分析
  • PAT A1092
  • redis学习笔记(三):列表、集合、有序集合
  • Vim 折腾记
  • vue:响应原理
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 京东美团研发面经
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 我看到的前端
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • #Z2294. 打印树的直径
  • #大学#套接字
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (1)Hilt的基本概念和使用
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (zt)最盛行的警世狂言(爆笑)
  • (代码示例)使用setTimeout来延迟加载JS脚本文件
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (六)vue-router+UI组件库
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (三)c52学习之旅-点亮LED灯
  • (学习日记)2024.01.19
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .NET 反射 Reflect
  • .net 设置默认首页
  • .NET/C#⾯试题汇总系列:⾯向对象
  • .NET6实现破解Modbus poll点表配置文件
  • .NET导入Excel数据
  • .net对接阿里云CSB服务
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • .NET应用架构设计:原则、模式与实践 目录预览