vue项目打包优化

首先第一步通过浏览器看首次加载的问题大小,时间跨度等方面入手

1. Coverage观察
Coverage是chrome开发者工具的一个新功能,从字面意思上可以知道它是可以用来检测代码在网站运行时有哪些js和css是已经在运行,而哪些js和css是还没有用到的,如图,这是我在打开csdn网页时,所显示的已运行和尚未运行的代码情况。

最右边显示的是我们加载的css和js文件数量,红色区域表示已运行的代码,而青色表示已加载但未运行的代码。可用来发现页面中尚未用到的js 和 css代码,你可以为用户只提供必要的代码,这样就可以提升页面的性能。这对于找出可以进行拆分的脚本以及延迟加载非关键脚本来说非常有用。
在这里插入图片描述

上面录制的数据中,最大的文件是 vendor.js,如果某个文件覆盖率低(即未使用代码比例很高),通常意味着用户加载了太多不必要的代码(要么真的是无用代码,要么是当前时点还没执行到的代码),有性能常识的同学不难推断出,这会导致页面的完全加载时间、或单页应用的启动时间变慢,在慢速网络下的性能损耗会尤其明显;此外,更多代码的解析、编译也就意味着更多的硬件资源消耗,在低端设备上也会存在明显的性能问题。
以 Coverage 数据为参考,我们能了解页面重无用代码的比例到底有多大。现实世界中,很多工程师可能是在遗留代码库上工作,并且遗留代码库存在的时间还很长,那么很可能这个代码库中存在大量的无用代码,但是谁也不敢删除他们,因为 JS 这门语言的动态性,你不能粗暴的把哪些看起来“没有被使用”的代码直接删掉,除非你很清楚所有的代码执行路径,很显然这对于大型应用或者遗留代码库来说是不现实的。
怎么移除死代码呢?我们可以依赖打包工具,比如 UglifyJS 在压缩代码时支持直接删除死代码的配置项。而 Webpack 2 中引入了 Tree Shaking 的特性,能够自动把项目中没有用到的代码从打包中去掉,但是这种优化仅限于被 export 的代码。总而言之,死代码要尽可能想办法去掉,Coverage 工具能提供一个判断基准。

2. webpack-bundle-analyzer:查看资源树

cnpm i webpack-bundle-analyzer
chainWebpack: config => {config.plugin('webpack-bundle-analyzer').use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)}

运行 npm run build --report
在这里插入图片描述

基本上可以看到整个项目包结构,接下来针对我们的项目开始进行瘦身减肥操作

1. productionSourceMap:false
如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建,如果特殊情况,生产环境上面报错了,为了方便定位问题,可以设置为true,他可以打包出一份源码出来,方便我们定位生产环境上面的问题。不过一般情况下是false

 productionSourceMap: process.env.NODE_ENV !== 'production', 

2. 路由懒加载

import ShowBlogs from '@/components/ShowBlogs'
routes:[ path: 'Blogs', name: 'ShowBlogs', component: ShowBlogs ]routes:[ path: 'Blogs',name: 'ShowBlogs',component: () => import('./components/ShowBlogs.vue')

3. 将打包的文件进行切割分包,方便加载的时候能多路加载

// 源(asset)和入口起点超过指定文件限制 会有警告 打包时可以 去掉这个提示config.performance = {// 入口起点的最大体积maxEntrypointSize: 5000000,// 生成文件的最大体积maxAssetSize: 3000000,// hints: 'warning',   // 超出大小之后的警告hints: false}

4. webpack ContextReplacementPlugin插件
如果项目里面涉及到momen locale zh-cn等可以通过webpack ContextReplacementPlugin插件
webpack 打包momentjs时会把所有语言包都打包,这样会使打包文件很大。此插件可以帮助我们只打包需要的语言包,大大减小打包文件大小。

 config.plugins.push(new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn/))

5.开启缓存,多线程编译

config.optimization.minimizer.push(new UglifyJsPlugin({uglifyOptions: {warnings: false,cache: true, // 开启缓存parallel: true, // 开启多线程编译compress: {drop_console: true,pure_funcs: ['console.log']}}}))

6. 对打包文件进行切割,控制加载文件个数,缓存已经打包的文件,避免重复打包

config.optimization.splitChunks({chunks: 'all', // async异步代码分割 initial同步代码分割 all同步异步分割都开启minSize: 30000, // 字节引入的文件大于30kb才进行分割// maxSize: 50000,         //50kb,尝试将大于50kb的文件拆分成n个50kb的文件minChunks: 1, // 模块至少使用次数maxAsyncRequests: 5, // 同时加载的模块数量最多是5个,只分割出同时引入的前5个文件maxInitialRequests: 3, // 首页加载的时候引入的文件最多3个automaticNameDelimiter: '~', // 缓存组和生成文件名称之间的连接符name: true, // 缓存组里面的filename生效,覆盖默认命名cacheGroups: {// 缓存组,将所有加载模块放在缓存里面一起分割打包common: {// 默认打包模块priority: 1,reuseExistingChunk: true // 模块嵌套引入时,判断是否复用已经被打包的模块// filename: 'common.js'},vendors: {test: /[\\/]node_modules[\\/]/,priority: 2// filename: 'vendors.js'}}})

7. 关闭Prefetch
因为vuecli 3默认开启prefetch(预先加载模块),提前获取用户未来可能会访问的内容
在首屏会把这十几个路由文件,都一口气下载了
所以我们要关闭这个功能,在vue.config.js中设置

// 移除 preload 插件 (去除默认预加载)config.plugins.delete('preload')
config.plugins.delete('prefetch')

8. 针对图片进行优化,大于10kb的正常加载,小于10kb的进行baseurl转换,可以提升浏览器初始化加载的效率

// 编译图片config.module.rule('images').test(/\.(png|jpeg|gif|jpg)$/).use('url-loader').loader('url-loader').options({limit: 1024 * 10, // 小于10k的图片采用baseurl,大于和等于10k的就正常打包成图片name: 'static/[name].[ext]'})

9. 针对css是否开始source map

 sourceMap: process.env.NODE_ENV === 'production', // 是否为 CSS 开启 source map。设置为 true 之后可能会影响构建的性能

10. 配置babel.config.js文件进行按需加载

 plugins: ["@babel/plugin-proposal-optional-chaining", // 可选链 ?.'@babel/plugin-proposal-nullish-coalescing-operator',  //空值合并 ??["import",{libraryName: ["ant-design-vue"],libraryDirectory: "es",style: "css"},]]

下面是整个vue.config.js的配置代码

const path = require('path')
const CompressionPlugin = require('compression-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
// const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
const webpack = require('webpack')
// const { options } = require('less')function resolve(dir) {return path.join(__dirname, dir)
}module.exports = {outputDir: 'dist', // 目录的内容在构建之前会被清除// qiankuan打包时放开// 多入口配置// pages: {//   index: {//     entry: 'src/main.js',//     template: 'public/index.html',//     filename: 'index.html',//   }// },publicPath: '/', //根路径 cli3.0以上使用publicPath替代baseUrzl,解决build后找不到静态资源的问题productionSourceMap: process.env.NODE_ENV !== 'production', // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。lintOnSave: process.env.NODE_ENV !== 'production', //生产构建时禁用 eslint-loader,它的有效值为 'warning' | 'default' | 'error'assetsDir: 'assets', // 放置生成静态资源的目录configureWebpack: config => {// console.log(process.env.NODE_ENV, '--------')config.plugins.push(new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn/))// 生产环境取消 console.logif (process.env.NODE_ENV === 'production') {// config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true// 为生产环境修改配置config.mode = 'production'// 源(asset)和入口起点超过指定文件限制 会有警告 打包时可以 去掉这个提示config.performance = {// 入口起点的最大体积maxEntrypointSize: 5000000,// 生成文件的最大体积maxAssetSize: 3000000,// hints: 'warning',   // 超出大小之后的警告hints: false}config.plugins.push(new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn/))config.optimization.minimizer.push(new UglifyJsPlugin({uglifyOptions: {warnings: false,cache: true, // 开启缓存parallel: true, // 开启多线程编译compress: {drop_console: true,pure_funcs: ['console.log']}}}))// config.output = {}}},chainWebpack: config => {// 移除prefetch插件,此插件是用来告诉浏览器在页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容//因为vuecli 3默认开启prefetch(预先加载模块),提前获取用户未来可能会访问的内容在首屏会把这十几个路由文件,都一口气下载了config.plugins.delete('prefetch')config.resolve.alias.set('@$', resolve('src')).set('@api', resolve('src/api')).set('@assets', resolve('src/assets')).set('@comp', resolve('src/components')).set('@views', resolve('src/views'))// .set('@ant-design/icons/lib/dist$', resolve('src/icons.js'))config.optimization.splitChunks({chunks: 'all', // async异步代码分割 initial同步代码分割 all同步异步分割都开启minSize: 30000, // 字节引入的文件大于30kb才进行分割// maxSize: 50000,         //50kb,尝试将大于50kb的文件拆分成n个50kb的文件minChunks: 1, // 模块至少使用次数maxAsyncRequests: 5, // 同时加载的模块数量最多是5个,只分割出同时引入的前5个文件maxInitialRequests: 3, // 首页加载的时候引入的文件最多3个automaticNameDelimiter: '~', // 缓存组和生成文件名称之间的连接符name: true, // 缓存组里面的filename生效,覆盖默认命名cacheGroups: {// 缓存组,将所有加载模块放在缓存里面一起分割打包common: {// 默认打包模块priority: 1,reuseExistingChunk: true // 模块嵌套引入时,判断是否复用已经被打包的模块// filename: 'common.js'},vendors: {test: /[\\/]node_modules[\\/]/,priority: 2// filename: 'vendors.js'}}})// 移除 preload 插件 (去除默认预加载)config.plugins.delete('preload')// 移除 prefetch 插件 (去除默认预加载)config.plugins.delete('prefetch')// 生产环境,开启js\css压缩if (process.env.NODE_ENV === 'production') {// 查看线上打包文件大小config.plugin('webpack-bundle-analyzer').use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)config.plugin('compressionPlugin').use(new CompressionPlugin({test: /\.(js|css|less)$/, // 匹配文件名threshold: 10240, // 对超过10k的数据压缩deleteOriginalAssets: false, // 不删除源文件algorithm: 'gzip',minRatio: 0.8}))}// 更改配置// 配置 webpack 识别 markdown 为普通的文件config.module.rule('markdown').test(/\.md$/).use().loader('file-loader').options({name: 'img/[name].[hash:8].[ext]',esModule: false // 这里设置为false}).end()// 编译vxe-table包里的es6代码,解决IE11兼容问题config.module.rule('vxe').test(/\.js$/).include.add(resolve('node_modules/vxe-table')).add(resolve('node_modules/vxe-table-plugin-antd')).end().use().loader('babel-loader').end()// 编译图片config.module.rule('images').test(/\.(png|jpeg|gif|jpg)$/).use('url-loader').loader('url-loader').options({limit: 1024 * 10, // 小于10k的图片采用baseurl,大于和等于10k的就正常打包成图片name: 'static/[name].[ext]'})},css: {sourceMap: process.env.NODE_ENV === 'production', // 是否为 CSS 开启 source map。设置为 true 之后可能会影响构建的性能// extract: {//   ignoreOrder: true //process.env.NODE_ENV === 'production' // 在生产环境下默认就是true的,在开发环境下为false,而且如果在开发环境下改为true的话,热更新就不好使了// },loaderOptions: {less: {modifyVars: {/* less 变量覆盖,用于自定义 ant design 主题 */'primary-color': '#F5222D','link-color': '#F5222D','border-radius-base': '4px'},javascriptEnabled: true}}},devServer: {// 设置让浏览器 overlay 同时显示警告和错误overlay: {warnings: true,errors: true},port: 10086,proxy: {/* 注意:jeecgboot前端做了改造,此处不需要配置跨域和后台接口(只需要改.env相关配置文件即可)issues/3462 很多人此处做了配置,导致刷新前端404问题,请一定注意 */[process.env.VUE_API_FIX]: {// target: process.env.VUE_APP_API_BASE_URL,target: 'http://172.16.1.211:10081',ws: false,changeOrigin: true}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/139831.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

WEB使用VUE3实现地图导航跳转

我们在用手机查看网页时可以通过传入经纬度去设置目的地然后跳转到对应的地图导航软件,如果没有下载软件则会跳转到下载界面 注意: 高德地图是一定会跳转到一个新网页然后去询问用户是否需要打开软件百度和腾讯地图是直接调用软件的这个方法有缺陷&…

【c#-Nuget 包“在此源中不可用”】 Nuget package “Not available in this source“

标题c#-Nuget 包“在此源中不可用”…但 VS 仍然知道它吗? (c# - Nuget package “Not available in this source”… but VS still knows about it?) 背景: 今日从公司svn 上拉取很久很久以前的代码,拉取下来200报错,进一步发…

【机器学习】文本多分类

声明:这只是浅显的一个小试验,且借助了AI。使用的是jupyter notebook,所以代码是一块一块,从上往下执行的 知识点:正则删除除数字和字母外的所有字符、高频词云、混淆矩阵 参考:使用python和sklearn的中文文本多分类…

资源分享 | 情绪脑电研究公开数据集

SEED SEED数据集是由上海交大类脑计算与机器智能研究中心(BCMI)开发的。该数据集是基于脑电的情绪分类任务而设计的数据集。该数据集记录了15名被试在观看积极、中性和消极情绪电影片段时的EEG信号,每个视频片段的时间为3-5分钟。每个参与者重复采集三天&#xff0…

多分类中混淆矩阵的TP,TN,FN,FP计算

关于混淆矩阵,各位可以在这里了解:混淆矩阵细致理解_夏天是冰红茶的博客-CSDN博客 上一篇中我们了解了混淆矩阵,并且进行了类定义,那么在这一节中我们将要对其进行扩展,在多分类中,如何去计算TP&#xff0…

IDEA中创建Java Web项目方法1

以下过程使用IntelliJ IDEA 2021.3 一、File-> New -> Project... 1. 项目类型中选择 Java Enterprise 项目 2. Name:填写自己的项目名称 3. Project template:选择项目的模板,Web application。支持JSP和Servlet的项目 4. Applica…

Nginx location 精准匹配URL = /

Location是什么? Location是Nginx中的块级指令(block directive),通过配置Location指令块,可以决定客户端发过来的请求URI如何处理(是映射到本地文件还是转发出去)及被哪个location处理。 匹配模式 分为两种模式&…

位段 联合体 枚举

Hello好久不见,今天分享的是接上次结构体没有分享完的内容,这次我们讲讲位段 枚举和联合体的概念以及他们的用法。 2.1 什么是位段 位段的声明和结构是类似的,有两个不同: 1.位段的成员必须是 int、unsigned int 或signed int 。 …

微信开放平台第三方开发,实现代小程序备案申请

大家好,我是小悟 微信小程序备案整体流程总共分为五个环节:备案信息填写、平台初审、工信部短信核验、通管局审核和备案成功。 服务商可以代小程序发起备案申请。在申请小程序备案之前,需要确保小程序基本信息已填写完成、小程序至少存在一个…

com.google.gson.internal.LinkedTreeMap cannot be cast to XXX

起因是在对google商品做本地缓存时,上线后发现的bug 刚开始非常自信,debug没问题线上有问题,大概率就是混淆文件没有添加keep,于是本地添加对SDK中类的keep,本地打包release验证,不出意外还是崩溃 仔细看…

C语言指针变量的引用距离

本段代码&#xff0c;测试&#xff0c;C的函数传参中&#xff0c;形参是基础类型参数和地址参数&#xff0c;对于实参的值影响。 #include <stdio.h> add(int a,int b){a;b;printf("add副本a%d\n",a);printf("add副本b%d\n",b);printf("副本ca…

Interceptor的使用场景:拦截请求中的租户信息,注入到租户上下文中

业务场景 在SaaS环境中&#xff0c;租户是最重要的隔离业务数据的属性了&#xff0c;在自己的项目体系环境中&#xff0c;租户id能保证有值。但有个特殊场景&#xff0c;某些特殊权限的账号需要修改指定租户的内容&#xff0c;也即前端会携带租户信息过来&#xff0c;并且内部涉…

在github上设置不同分支,方便回滚

在github上设置不同分支&#xff0c;方便回滚 步骤可能出现的问题couldnt find remote ref gpuVersion1. 确保您处于正确的分支2. 添加并提交更改&#xff08;如果还未进行&#xff09;3. 推送本地分支到远程仓库4. 验证操作 步骤 之前在github上上传了一个项目代码&#xff0c…

【马蹄集】—— 数论专题:筛法

数论专题 目录 MT2213 质数率MT2214 元素共鸣MT2215 小码哥的喜欢数MT2216 数的自我MT2217 数字游戏 MT2213 质数率 难度&#xff1a;黄金    时间限制&#xff1a;1秒    占用内存&#xff1a;256M 题目描述 请求出 [ 1 , n ] \left[1,n\right] [1,n] 范围内质数占比率。…

Unity的AB包相关

1、打包 在这个界面左边右键&#xff0c;CreateNewBundle 将要打包的模型制作成预设体 在下面勾选 选好平台路径&#xff0c;点击Build 2、加载AB包 public class ABTest : MonoBehaviour {// Start is called before the first frame updatevoid Start(){//加载AB包AssetB…

识别准确率达 95%,华能东方电厂财务机器人实践探索

摘 要&#xff1a;基于华能集团公司大数据与人工智能构想理念&#xff0c;结合东方电厂实际工作需要&#xff0c;财务工作要向数字化、智能化纵深推进&#xff0c;随着财务数字化转型和升级加速&#xff0c;信息化水平不断提升&#xff0c;以及内部信息互联互通不断加深&#x…

深入探析NCV7356D1R2G 单线CAN收发器各项参数

NCV7356D1R2G深力科是一款用于单线数据链路的物理层器件&#xff0c;能够使用多种具碰撞分解的载波感测多重存取 (CSMA/CR) 协议运行&#xff0c;如博世控制器区域网络 (CAN) 2.0 版。此串行数据链路网络适用于不需要高速数据的应用&#xff0c;低速数据可在物理介质部件和微处…

【用unity实现100个游戏之12】unity制作一个俯视角2DRPG《类星露谷物语》资源收集游戏demo

文章目录 前言加快编辑器运行速度素材(1)场景人物(2)工具 一、人物移动和动画切换二、走路灰尘粒子效果探究实现 三、树木排序设计方法一方法二 四、绘制拿工具的角色动画五、砍树实现六、存储拾取物品引入Unity 的可序列化字典类 七、实现靠近收获物品自动吸附八、树木被砍掉的…

视频编解码器H.264和H265有什么区别?

对于大型视频文件来说&#xff0c;视频编解码器至关重要&#xff0c;它可以将文件压缩为较小的尺寸&#xff0c;从而可以更轻松地存储和加快传输速度。而两种最常用的编解码器是H.264和H.265&#xff0c;那么它们两者之间有什么区别&#xff0c;哪一个更好呢&#xff1f; 1. 什…

手摸手图解 CodeWhisperer 的安装使用

CodeWhisperer 是亚⻢逊出品的一款基于机器学习的通用代码生成器&#xff0c;可实时提供代码建议。 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术&#xff0c;观点…