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

webpack性能优化

文章目录

    • 1. 性能优化-分包
    • 2. 动态导入
    • 3. 自定义分包
    • 4. Prefetch和Preload
    • 5. CDN加载配置
    • 6. CSS的提取
    • 7. terser压缩
      • 7.1 Terser在webpack中配置
      • 7.2 css压缩
    • 8. Tree Shaking 消除未使用的代码
      • 8.1 usedExports 配置
      • 8.2 sideEffects配置
      • 8.3 CSS实现Tree Shaking
    • 9. Scope Hoisting作用域提升
    • 10 webpack对文件进行压缩

webpack性能优化

  • webpack的性能优化较多,可以对其进行分成两类:

    • 打包后的结果,上线时的性能优化。(比如分包处理、减小包体积、CDN服务器等)
    • 优化打包速度,开发或者构建时优化打包速度。(比如exclude、cache-loader等)
  • 但是在大多数情况下webpack都帮我们做好了该有的性能优化:

    • 比如配置mode为production或者development时,默认webpack的配置信息;
    • 但是我们也可以针对性的进行自己的项目优化;

1. 性能优化-分包

  • 主要的目的是将代码分离到不同的bundle中,之后我们可以按需加载,或者并行加载这些文件;

  • 比如默认情况下,所有的JavaScript代码(业务代码、第三方依赖、暂时没有用到的模块)在首页全部都加载,就会影响首页的加载速度;

  • 代码分离可以分出更小的bundle,以及控制资源加载优先级,提供代码的加载性能

  • Webpack中常用的代码分离有三种:

    • 入口起点:使用entry配置手动分离代码;
    • 防止重复:使用Entry Dependencies或者SplitChunksPlugin去重和分离代码;
    • 动态导入:通过模块的内联函数调用来分离代码;
  • 多入口起点
    在这里插入图片描述
    上面代码就是多入口,打包出来后可以看到代码进行了分离
    在这里插入图片描述

  • 但是当上面的的index.jsmain.js都依赖相同的库 axios 这时打包就会把axios打包到每一次文件中,显然是不符合要求的。

  • 这时我们就需要让他们共享axios依赖

	// entry: './src/index.js',//  对象配置多入口//  打包时需要注意出口entry: {index: { import: './src/index.js', dependOn:'shared'},main: { import: './src/main.js', dependOn: 'shared' },// 配置共享打包依赖shared: ['axios']},output: {path: path.resolve(__dirname, './build'),// filename: 'bundle.js',// 出口配置动态获取namefilename: "[name].bundle.js",clean: true},
  • 打包后
    在这里插入图片描述

2. 动态导入

  • 在ECMAScript语法中的导入是通过 import() 语法来完成

  • 例如在首屏渲染时,加载所有的路由会很慢,包也会很大

    • 我们希望在代码运行过程中来加载它(比如判断一个条件成立时加载);
    • 因为我们并不确定这个模块中的代码一定会用到,所以最好拆分成一个独立的js文件;
    • 这样可以保证不用到该内容时,浏览器不需要加载和处理该文件的js代码;
    • 这个时候我们就可以使用动态导入;
    1. 新建router路由
      在这里插入图片描述
  1. main.js中用 import 导入
const btn1 = document.createElement('button')
const btn2 = document.createElement('button')
btn1.textContent = '关于路由'
btn2.textContent = '主页面路由'
document.body.append(btn1)
document.body.append(btn2)
btn1.onclick = function () {import('./router/about')
}
btn2.onclick = function () {import('./router/home.js')
}
  1. 打包后
    在这里插入图片描述
  • 这时我们就可以按需加载这些文件了,并且首屏加载时,包的体积也会很小,速度大大提高
  • 在webpack中,也可以通过动态导入获取到一个对象或者调用方法
  • 真正导出的内容,在该对象的default属性中,所以我们需要做一个简单的解构;
    在这里插入图片描述
  • 上面代码打包后的名字src_router_home_js_bundle.js ,我们不能见名知意
  • 因此动态导入的文件也可以命名:
    • 因为动态导入通常是一定会打包成独立的文件的,所以并不会在cacheGroups中进行配置;
    • 那么它的命名我们通常会在output中,通过 chunkFilename 属性来命名;
	output: {clean: true,path: path.resolve(__dirname, './build'),filename: "[name].bundle.js",// 分包进行命名chunkFilename: "[name]_chunk.js"},
  • 但是,也会发现默认情况下我们获取到的 [name] 是和id的名称保持一致
  • 我们希望修改name的值,可以通过magic comments(魔法注释)的方式;
btn1.onclick = function () {import(/* webpackChunkName: "about" */'./router/about').then(res=>{res.about()})
}

在这里插入图片描述

  • 同时import使用最多的也是路由懒加载
const btn2 = document.createElement('button')
btn2.textContent = '主页面路由'
const component = document.createElement('div')
component.innerHTML='hello component'
btn2.onclick = function () {import('./router/home.js').then(() => {document.body.appendChild(component)})
}document.body.append(btn2)

3. 自定义分包

  • 当直接引入第三方库时,并不会对第三方进行分包,因此就需要splitChunk
  • splitChunk可以自定义分包,它底层是使用SplitChunksPlugin来实现的:
    • 该插件webpack已经默认安装和集成, 只需要提供SplitChunksPlugin相关的配置信息即可;
  • Webpack提供了SplitChunksPlugin默认的配置,同时也可以手动来修改它的配置:
    • 比如默认配置中,chunks仅仅针对于异步(async)请求,我们也可以设置为all
	// chunks 默认值是async ,只对异步进行分包// 可以设置成all进行分包optimization: {splitChunks: {chunks: 'all'}},
  • axios分包后的代码
    在这里插入图片描述
  • 注意上面的分包会把所有的第三方库都会分到一个包中
  • 自定义配置解析
    • Chunks:
      • 默认值是async
      • all表示对同步和异步代码都进行处理
    • minSize:
      • 拆分包的大小, 至少为minSize;
      • 如果一个包拆分出来达不到minSize,那么这个包就不会拆分;
    • maxSize:
      • 将大于maxSize的包,拆分为不小于minSize的包;
    • cacheGroups:
      • 用于对拆分的包就行分组,比如一个lodash在拆分之后,并不会立即打包,而是会等到有没有其他符合规则的包一起来打包;
      • test属性:匹配符合规则的包;
      • name属性:拆分包的name属性;
      • filename属性:拆分包的名称,可以自己使用placeholder属性;
  • 如果进行继续拆分可以参考webpack官网
	// chunks 默认值是async ,只对异步进行分包// 可以设置成all进行分包optimization: {splitChunks: {chunks: "all",// 当一个包大于指定的大小时, 继续进行拆包// maxSize: 20000,minSize: 20000,   // 将包拆分成不小于minSize的包 这个默认值是20kb// 自己对需要进行拆包的内容进行分包cacheGroups: {utils: {test: /utils/,filename: "[id]_utils.js"},vendors: {// /node_modules/// window上面 /\// mac上面 /test: /[\\/]node_modules[\\/]/,filename: "[id]_vendors.js"}}},},
  • 同时因为环境不同生成的打包前缀id也不同
    在这里插入图片描述
  • 因此optimization.chunkIds可以配置
    • optimization.chunkIds配置用于告知webpack模块的id采用什么算法生成
    • 有三个比较常见的值:
      • natural:按照数字的顺序使用id;
      • named:development下的默认值,一个可读的名称的id;
      • deterministic:确定性的,在不同的编译中不变的短数字id
    • 注意在webpack4中是没有这个值的;
      • 那个时候如果使用natural,那么在一些编译发生变化时,就会有问题;
  1. 开发过程中,我们推荐使用named;
  2. 打包过程中,我们推荐使用deterministic
	optimization: {// 设置生成的chunkId的算法// development: named// production: deterministic(确定性)// webpack4中使用: naturalchunkIds: 'deterministic',// runtime的代码是否抽取到单独的包中(早Vue2脚手架中)// 主要是对模块进行解析、加载、模块信息相关的代码runtimeChunk: {name: "runtime"},
}
  • 具体优化(Optimization)的代码参考官网

4. Prefetch和Preload

  • webpack v4.6.0+ 增加了对预获取和预加载的支持。
  • 在声明 import 时,使用下面这些内置指令,来告知浏览器:
    • prefetch(预获取):将来某些导航下可能需要的资源
    • preload(预加载):当前导航下可能需要资源
btn2.onclick = function () {import(/* webpackChunkName: "about" *//* webpackPreload:true */'./router/home.js').then(() => {document.body.appendChild(component)})
}
  • 与 prefetch 指令相比,preload 指令有许多不同之处:
    • preload chunk 会在父 chunk 加载时,以并行方式开始加载。prefetch chunk 会在父 chunk 加载结束后开始加载
    • preload chunk 具有中等优先级,并立即下载。prefetch chunk 在浏览器闲置时下载。
    • preload chunk 会在父 chunk 中立即请求,用于当下时刻。prefetch chunk 会用于未来的某个时刻。

5. CDN加载配置

  • CDN称之为内容分发网络

  • 在开发中,我们使用CDN主要是两种方式:

    • 打包的所有静态资源,放到CDN服务器,用户所有资源都是通过CDN服务器加载的;
    • 一些第三方资源放到CDN服务器上
  • 打包的所有静态资源,放到CDN服务器

	output: {publicPath: 'http://btn12or.com/'},
  • 打包后
	<script defer src="http://btn12or.com/runtime.bundle.js"></script><script defer src="http://btn12or.com/291_vendors.js"></script><script defer src="http://btn12or.com/main.bundle.js"></script>
  • 排除打包,第三方资源放到CDN服务器上加载
  • 配置排除打包
	// 排除打包 ,注意这里的key与value要和导入的保持一致// key 是导入使用排除的包// value 是CDN提供的名字externals:{axios:'axios'},
  • 在html模块中,加入CDN服务器地址:
	<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.min.js"></script>

6. CSS的提取

安装 npm i style-loader css-loader -D

  • 配置
{test: /\.css$/,use: ['style-loader',  // 开发环境使用// MiniCssExtractPlugin.loader,   // 生产环境'css-loader']}
  1. 安装 npm install mini-css-extract-plugin -D 用于提取css
  2. 注意 该插件需要在webpack4+以上使用
  3. 注意 默认css是直接内联到html中的
  • 引用css , 并导入插件与配置
// 0. main.js 中引入 
import './css/style.css';
// 1. 导入
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 2. 配置loadermodule: {rules: [{test: /\.css$/,use: [// 'style-loader',  // 开发环境使用MiniCssExtractPlugin.loader,   // 生产环境'css-loader']}]},
// 3. 配置plugins
plugins: [// css / [name].css 文件夹与文件名new MiniCssExtractPlugin({filename: 'css/[name].css',//  单独导入的css进行分包chunkFilename: 'css/[name]_chunk.css'})]

7. terser压缩

  • Terser可以帮助我们压缩、丑化我们的代码,让我们的bundle变得更小
  • 早期使用 uglify-js来压缩、丑化我们的JavaScript代码,但是目前已经不再维护,并且不支持ES6+的语法;
  • Terser是从 uglify-es fork 过来的,并且保留它原来的大部分API以及适配 uglify-es和uglify-js@3等;
  • Terser和babel都是一个独立的工具,所以它可以单独安装:
  1. 全局安装 npm install terser -g
  2. 局部安装 npm install terser -D
  • 命令行使用Terser

命令 1. terser [input files] [options]
举例 2. npx terser qa.js -o qa.min.js -c -m

在这里插入图片描述

  • Compress和Mangle的options
  • Compress option:
    • arrows:class或者object中的函数,转换成箭头函数;
    • arguments:将函数中使用 arguments[index]转成对应的形参名称;
    • dead_code:移除不可达的代码(tree shaking);
    • 具体配置参考属性
  • Mangle option
    • toplevel:默认值是false,顶层作用域中的变量名称,进行丑化(转换);
    • keep_classnames:默认值是false,是否保持依赖的类名称;
    • keep_fnames:默认值是false,是否保持原来的函数名称;
    • 具体配置参考属性
npx terser qa.js -o qa.min.js -c arrows,arguments=true,dead_code -m 
toplevel=true,keep_classnames=true,keep_fnames=true

7.1 Terser在webpack中配置

  • 真实开发中,不需要手动的通过terser来处理代码,直接通过webpack来处理
    • 注意 在webpack中有一个minimizer属性,在production模式下,默认就是使用TerserPlugin来处理我们的代码的;
    • 同时自己也可以自己来创建TerserPlugin的实例,并且覆盖相关的配置;
  • 具体配置
    • development 模式下需要打开minimize,让其对我们的代码进行压缩(默认production模式下已经打开了)
    • 导入 TerserPlugin 插件
const TerserPlugin = require('terser-webpack-plugin')
  • 在minimizer创建一个TerserPlugin:
    • extractComments:默认值为true,表示会将注释抽取到一个单独的文件中;在开发中,我们不希望保留这个注释时,可以设置为false;
    • parallel:使用多进程并发运行提高构建的速度,默认值是true
      • 并发运行的默认数量: os.cpus().length - 1;
      • 我们也可以设置自己的个数,但是使用默认值即可;
    • terserOptions:设置我们的terser相关的配置
      • compress:设置压缩相关的选项;
      • mangle:设置丑化相关的选项,可以直接设置为true;
      • toplevel:顶层变量是否进行转换
      • keep_classnames:保留类的名称;
      • keep_fnames:保留函数的名称;
  • 具体配置参考webpack官网
// 1. webpack 中引用插件 
const TerserPlugin = require('terser-webpack-plugin')
// 配置terserPluginoptimization: {// 代码优化: TerserPlugin => 让代码更加简单与压缩 => Terserminimize: true,    // minimize 在development 模式下必须手动指定为true ,在production模式下,webpack自动设置为trueminimizer: [// JS代码简化new TerserPlugin({extractComments: false,    // 第三方注释是否进行抽取terserOptions:{mangle:true,toplevel:true}})// CSS代码简化]},

7.2 css压缩

  • CSS压缩通常是去除无用的空格等,因为很难去修改选择器、属性的名称、值等
  • 安装 css-minimizer-webpack-plugin 插件

npm i css-minimizer-webpack-plugin

//  1. webpack 中引用插件 
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
// 2. 使用new CssMinimizerPlugin({parallel:true}),
  • 具体配置参考webpack官网

8. Tree Shaking 消除未使用的代码

  • 用于消除未调用的代码(纯函数无副作用,可以放心的消除,这也是为什么要求我们在进行函数式编程时,尽量使用纯函数的原因之一)
  • 在webpack4正式扩展了这个能力,并且通过 package.json的 sideEffects属性作为标记,告知webpack在编译时,哪里文件可以安全的删除掉;
  • webpack5中,也提供了对部分CommonJS的tree shaking的支持 参考链接
  • webpack实现Tree Shaking
    • usedExports:通过标记某些函数是否被使用,之后通过Terser来进行优化的;
    • sideEffects:跳过整个模块/文件,直接查看该文件是否有副作用;

8.1 usedExports 配置

  • 将mode设置为development模式

    • 为了可以看到 usedExports带来的效果,我们需要设置为 development 模式
    • 因为在 production 模式下,webpack默认的一些优化会带来很大的影响。
  • 设置usedExports为true和false对比打包后的代码:

    • 源代码引用
      在这里插入图片描述

    • usedExports为fasle
      在这里插入图片描述

    • usedExports为true

    • 在usedExports设置为true时,会有一段注释:unused harmony export mul

    • 告知Terser在优化时,可以删除掉这段代码
      在这里插入图片描述

  • minimize也设置true:mul函数有被移除掉
    在这里插入图片描述

    • usedExports设置为false时,mul函数没有被移除掉;
  • 所以,usedExports实现Tree Shaking是结合Terser来完成的。

8.2 sideEffects配置

  • sideEffects用于告知webpack compiler哪些模块时有副作用的:
    • 副作用的意思是这里面的代码有执行一些特殊的任务,不能仅仅通过export来判断这段代码的意义;
  • package.json中设置sideEffects的值:
    • sideEffects设置为false,就是告知webpack可以安全的删除未用到的exports;
  • 源副作用代码

在这里插入图片描述

  • 设置为true
    在这里插入图片描述
  • sideEffects设置为false 删除所有副作用代码
  • 注意这里不管引入的是否是全局要用的代码还是css文件只要变量未被接受都会被删除
  • 比如引入的css文件我们希望保留,可以设置为数组
    • 源css文件
      在这里插入图片描述
  • 打包后的文件在这里插入图片描述

8.3 CSS实现Tree Shaking

  • CSS的Tree Shaking需要借助于一些其他的插件
  • 安装 npm install purgecss-webpack-plugin -D
  • 配置PurgeCss
    • paths:表示要检测哪些目录下的内容需要被分析,这里使用glob查找文件夹;
    • 默认情况下,Purgecss会将我们的html标签的样式移除掉,如果我们希望保留,可以添加一个safelist的属性;
// 1. 导入
const path = require('path')
const glob = require('glob')
const { PurgeCSSPlugin } = require('purgecss-webpack-plugin')
// 2.配置插件new PurgeCSSPlugin({//  glob node提供 查找src文件下的所有文件夹// nodir: true 是查找所有的文件paths: glob.sync(`${path.resolve(__dirname, '../src')}/**/*`, { nodir: true }),// 添加白名单,看哪些不需要删除,默认标签选择器是不删除的safelist: function () {return {standard: ["body"]}}})
  • 打包后文件对比
    在这里插入图片描述

9. Scope Hoisting作用域提升

  • 默认情况下webpack打包会有很多的函数作用域,包括一些(比如最外层的)IIFE
    • 无论是从最开始的代码运行,还是加载一个模块,都需要执行一系列的函数;

在这里插入图片描述

  • Scope Hoisting可以将函数合并到一个模块中来运行
  • 在production模式下,默认这个模块就会启用; 在development模式下,需要手动打开该模块
  • webpack官网参考
// 1. 导入
const webpack = require('webpack');
// 2. 配置plugins
new webpack.optimize.ModuleConcatenationPlugin()

10 webpack对文件进行压缩

  1. 安装CompressionPlugin:

npm install compression-webpack-plugin -D

const CompressionPlugin = require("compression-webpack-plugin")// 对打包后的文件(js/css)进行压缩new CompressionPlugin({test: /\.(js|css)$/,algorithm: 'gzip',   // 压缩算法minRatio:0.7,  // 压缩比例threshold:50   // 设置文件从多大开始压缩})
  • 具体配置参考webpack
  • html压缩借助 HtmlWebpackPlugin插件
	new HtmlWebpackPlugin({template: './index.html',// 自定义html压缩minify: isProdution ? {removeComments: true} : false}),
  • inject:设置打包的资源插入的位置
  • cache:设置为true,只有当文件改变时,才会生成新的文件(默认值也是true)
  • minify:默认会使用一个插件html-minifier-terser
    在这里插入图片描述
    参考文章
  • Mr_RedStar
  • coderwhy
  • webpack官网

相关文章:

webpack性能优化

文章目录 1. 性能优化-分包2. 动态导入3. 自定义分包4. Prefetch和Preload5. CDN加载配置6. CSS的提取7. terser压缩7.1 Terser在webpack中配置7.2 css压缩 8. Tree Shaking 消除未使用的代码8.1 usedExports 配置8.2 sideEffects配置8.3 CSS实现Tree Shaking 9. Scope Hoistin…...

保存和读取带有透明通道的视频

保存带有透明通道的视频&#xff1a; import osimport imageio from rembg import remove as removBg,new_session from PIL import Image import numpy as np import cv2 from tqdm import tqdmclass cls_rembg():def __init__(self,model_pth):self.session new_session(mo…...

bilibili的评论ip属地显示未知

现象 出于某些原因&#xff0c;我们在日常使用中的大部分平台都开启了IP地址显示&#xff0c;一般会显示当事人所在的地址&#xff0c;这其中就有一些奇怪的地址&#xff0c;&#xff08;在此不谈魔法&#xff09;就比如我最近在刷B站的时候&#xff0c;就在评论区发现了一些显…...

[BabysqliV3.0]phar反序列化

文章目录 [BabysqliV3.0]phar反序列化 [BabysqliV3.0]phar反序列化 开始以为是sql注入 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ST1jvadM-1691302941344)(https://raw.githubusercontent.com/leekosss/photoBed/master/202308032140269.png)…...

数据库架构演变过程

&#x1f680; ShardingSphere &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&…...

webpack 静态模块打包工具

webpack 为什么? 把静态模块内容&#xff0c;压缩&#xff0c;整合&#xff0c;转译等(前端工程化) 把less/sass转成css代码把ES6 降级成ES5支持多种模块文件类型&#xff0c;多种模块标准语法 vite 为什么不直接学习vite 而学习webpack 因为很多项目还是基于webpack来进…...

万界星空科技/免费开源MES系统/免费仓库管理

仓库管理&#xff08;仓储管理&#xff09;&#xff0c;指对仓库及仓库内部的物资进行收发、结存等有效控制和管理&#xff0c;确保仓储货物的完好无损&#xff0c;保证生产经营活动的正常进行&#xff0c;在此基础上对货物进行分类记录&#xff0c;通过报表分析展示仓库状态、…...

【暑期每日一练】 Epilogue

目录 选择题&#xff08;1&#xff09;解析&#xff1a; &#xff08;2&#xff09;解析&#xff1a; &#xff08;3&#xff09;解析&#xff1a; &#xff08;4&#xff09;解析&#xff1a; &#xff08;5&#xff09;解析&#xff1a; 编程题题一描述输入描述&#xff1a;输…...

Go微服务实践 - Rpc核心概念理解

概述 从0研究一下Golang已经Golang的微服务生态体系&#xff0c;Golang的微服务首先要从Rpc开始&#xff0c;在升级到Grpc&#xff0c;详细介绍这些技术点都在解决什么技术问题。 Rpc Rpc (Remote Procedure Call) 远程过程调用&#xff0c;简单的理解是一个节点请求另一个节…...

Effective Java笔记(27)消除非受检的警告

用泛型编程时会遇到讲多编译器警告 &#xff1a; 非受检转换警告&#xff08; unchecked cast warning &#xff09;、非受检方法调用警告、非受检参数化可变参数类型警告&#xff08; unchecked parameterized vararg type warning&#xff09;&#xff0c;以及非受检转换警告…...

Dapper

介绍 Dapper是一个轻量级的ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它可以方便地将数据库查询结果映射到.NET对象上&#xff0c;同时也支持执行原生SQL查询。下面我将详细介绍Dapper的使用方法。 安装Dapper 首先&#xff0c;你需要通过NuGet包管理器将Dap…...

Python基础知识(一)

数据类型 基本类型 数字&#xff0c;字符串&#xff0c;布尔 数字类型 int整型 整数 float浮点型 带小数的数 complex复数 abj 字符串类型 str字符串 视作文本 组成&#xff1a;由数字&#xff0c;字母&#xff0c;空格&#xff0c;其他字符等组合而成 表达&#xff…...

QTthreadPool 程序

//*******************主窗口****************************// ------------------------.H--------------------------------- ----------------------------------------------------------- #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #inclu…...

python注册机制Registry

Register用法 1. 为什么使用Register2. 先验知识-----装饰器2.1 代码视角的装饰器用法2.2 装饰器的使用场景2 3. Registry注册器参数parent介绍未完待续 1. 为什么使用Register 2. 先验知识-----装饰器 2.1 代码视角的装饰器用法 实例1 decorate def func():pass #! 等价于…...

【Megatron-DeepSpeed】张量并行工具代码mpu详解(三):张量并行层的实现及测试

相关博客 【Megatron-DeepSpeed】张量并行工具代码mpu详解(三)&#xff1a;张量并行层的实现及测试 【Megatron-DeepSpeed】张量并行工具代码mpu详解(一)&#xff1a;并行环境初始化 【Megatron-DeepSpeed】张量并行工具代码mpu详解(二)&#xff1a;Collective通信操作的封装ma…...

【SpringBoot学习笔记】02. yaml配置注入

yaml配置注入 yaml基础语法 说明&#xff1a;语法要求严格&#xff01; 1、空格不能省略 2、以缩进来控制层级关系&#xff0c;只要是左边对齐的一列数据都是同一个层级的。 3、属性和值的大小写都是十分敏感的。 yaml注入配置文件 1、在springboot项目中的resources目录…...

【初阶C语言】指针的妙用

前言&#xff1a;在C语言中&#xff0c;有一个非常重要的知识点&#xff0c;叫做指针&#xff0c;指针也是数据类型中的一种。在本节内容中&#xff0c;我们就一起来学习指针。 学习一个新知识的时候&#xff0c;我们需要从这几个方面&#xff1a;指针是什么&#xff0c;指针是…...

链表——LinkedList类的概述和实现

LinkedList类 1.1LinkedList类概述 LinkedList类底层是基于双向链表结构实现的&#xff0c;不同于ArrayList类和Vector类是基于数组实现的&#xff1b;LinkedList类是非线程安全的&#xff1b;LinkedList类元素允许为null&#xff0c;允许重复元素&#xff1b;LinkedList类插…...

快六一啦,学习CSS3实现一个冰淇淋动画特效

快六一啦&#xff0c;小时候顶多吃个小冰棍&#xff0c;或者是那种小冰袋&#xff0c;现在的小朋友真是好&#xff0c;动不动就能吃到冰淇淋&#xff0c;今天用CSS3实现一个冰淇淋的动画特效吧 目录 实现思路 桶身的实现 冰淇淋身体的实现 五彩颗粒的实现 HTML源码 CSS3源…...

VSCode CMake vcpkg 整合

VSCode 整合 CMake 调试 CMake 工程 // launch.json {"version": "0.2.0","configurations": [{"name": "(gdb) Launch","type": "cppdbg","request": "launch",// Resolved by …...

c++ | win vscode

vscode 适合新手做一些简单的单个的编译和调试 新手适合去配置c 环境&#xff0c;尤其是当涉及复杂一点的编程&#xff0c;如多文件、多线程&#xff0c;在调试的时候会头大&#xff0c;要求会高一点 但怎么说呢&#xff1f; c 编译和调试是最接近实际开发环境的&#xff0c;与…...

算法-快速排序

给你一个整数数组 nums&#xff0c;请你将该数组升序排列。 输入&#xff1a;nums [5,2,3,1] 输出&#xff1a;[1,2,3,5] 输入&#xff1a;nums [5,1,1,2,0,0] 输出&#xff1a;[0,0,1,1,2,5] 详细思路直接看我录制的视频吧 算法-快速排序_哔哩哔哩_bilibili class Soluti…...

SSM项目-博客系统

在线体验项目&#xff1a;登陆页面 项目连接&#xff1a;huhublog_ssm: 个人博客系统 技术栈&#xff1a;SpringBoot、SpringMVC、Mybatis、Redis、JQuery、Ajax、Json (gitee.com) 1.项目技术点分析 SpringBoot、SpringWeb(SpringMVC)、MyBatis、MySQL(8.x)、Redis(存储验…...

Android Gradle Plugin 编译

1. 源码下载&#xff1a; $ mkdir studio-main $ cd studio-main $ repo init -u https://android.googlesource.com/platform/manifest -b studio-main $ repo sync -c -j4 -q 这个官方网址让下载 studio-master-dev 分支&#xff0c;这个分支很老旧了&#xff0c;我这里直接…...

如何快速掌握水土保持方案编制

1、熟悉水土保持常用的主要法律法规、部委规章、规范性文件及技术规范与标准&#xff1b; 2、了解水土保持方案、监测及验收工作开展的流程&#xff1b; 3、熟悉水土保持方案、监测及验收工作需要收集的资料、现场踏勘注意事项&#xff1b; 4、熟悉常见水土保持工程施工工艺…...

前端笔试---acm模式

前言 之前一直刷力扣&#xff0c;昨天做了小红书笔试&#xff0c;发现是acm模式&#xff0c;不太熟悉&#xff0c;特此总结。其实如果是acm模式就需要自己写一下输入输出。前端一般有两个选择&#xff0c;一个是基于 V8 环境&#xff0c;另一个是基于 node。 V8 // 对于有多…...

国联易安网页防篡改保护系统“渠道招募”启动啦!

作为业内专注于保密与非密领域的分级保护、等级保护、业务连续性安全和大数据安全的领军企业&#xff0c;国联易安网页防篡改保护系统基于“高效同步”、“安全传输”两项技术&#xff0c;具备了独特的“五重防护”新特性&#xff0c;支持网页的全自动发布、网页监控、报警和自…...

JavaScript--WebStorage

目录 WebStorage概述 WebStorage分类 注意&#xff1a; localStorage方法 介绍&#xff1a; 常见方法&#xff1a; 案例演示&#xff1a; sessionStorage方法 介绍&#xff1a; 常见方法&#xff1a; 案例演示&#xff1a; WebStorage概述 WebStorage是HTML5中…...

elementui 的 dialog 常用逻辑总结

菜鸟最近写后台管理系统&#xff0c;发现不管是弹窗、还是编辑、查看、添加等功能&#xff0c;真的代码都差不多&#xff0c;但是每次都要重新写里面的关闭逻辑等&#xff0c;菜鸟就感觉不如搞一个模版&#xff0c;后面只关注于逻辑&#xff0c;其他都直接来这里复制了&#xf…...

ip网络广播系统网络音频解码终端公共广播SV-7101

SV-7101V网络音频终端产品简介 网络广播终端SV-7101V&#xff0c;接收网络音频流&#xff0c;实时解码播放。本设备只有网络广播功能&#xff0c;是一款简单的网络广播终端。提供一路线路输出接功放或有源音箱。 产品特点 ■ 提供固件网络远程升级■ 标准RJ45网络接口&…...