[前端优化]项目优化--Lighthouse

[前端优化]项目优化--Lighthouse

  • 前端优化的分类
  • Lighthouse 优化工具
  • 优化维度--性能(Performance)
    • 性能指标概览
      • 白屏时间--FP
      • 首字节时间--TTFB
      • 首次输入延迟--FID
      • 累积布局偏移--CLS
    • 性能指标分析
    • Lighthouse的性能优化方案
    • 性能优化实战解析
      • Serve images in next-gen formats
      • Enable text compression
      • gzip 压缩
        • 项目打包时gzip压缩
          • vue.config.js配置 gzip 压缩:
          • vite.config.js 配置 gzip 压缩:
          • 加载时允许使用压缩
        • nginx代理 gzip压缩
      • 图片压缩
        • vue.config.js配置图片压缩
        • vite.config.js配置图片压缩:
      • 禁止生成 map 映射文件
      • 拆分三方包
        • vue.config.js的拆分方式
        • vite.config.js的拆分方式
      • 删除 console 打印语句
        • vite.config.js配置删除 console
        • @vue/cli配置删除 console
      • CDN 资源加载
        • vite配置 CDN 资源加载
      • Treeshaking
    • 总结分析
  • 优化维度--可访问性(Accessibility)
    • ARIA
    • NAMES AND LABELS
  • 优化维度--SEO(Search Engine Optimization)

前端优化的分类

前端优化分为代码优化及页面优化

页面优化主要针对页面加载环节,包括:HTTP 请求数、脚本的无阻塞加载、内联脚本的位置优化等内容。
代码优化包括:Javascript 中的 DOM 操作优化、CSS 选择符优化、图片优化以及 HTML 结构优化等内容。

代码级别优化则更关注数据请求,很重要的一条就是减少 HTTP 请求的数量。一个完整的 HTTP 请求需要经过路由查找,TCP 握手,发送请求,服务器响应和浏览器接收等一些列过程。对于小文件,实际下载文件的时间对于整个请求的时间占比很低,因此需要将小文件合并为大文件来传输。

Lighthouse 优化工具

Lighthouse 是 Google Chrome 推出的开源工具,现在的 Google Chrome 浏览器也集成了 LightHouse 优化工具,它从多个维度量化的去衡量前端项目的用户体验。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从上图可以看出通过性能、可访问性、是否是最佳实践、SEO的设置与渐进式框架的得分来判断是否还有优化空间
在这里插入图片描述

优化后

在这里插入图片描述

优化维度–性能(Performance)

性能指标概览

Google定义了衡量网站性能的基本指标,性能维度的数值是各个性能指标综合后的得分,一般将得分与标准值进行比较反应网站的性能,体现性能的指标项包括:

性能指标名称性能指标说明推荐标准值
首次内容绘制(First Contentful Paint)即浏览器首次将任意内容(如文字、图像、canvas 等)绘制到屏幕上的时间点标准≤1s
最大内容绘制(Largest Contentful Paint)度量标准报告视口内可见的最大图像或文本块的呈现时间标准≤2s
交互时间(Time to Interactive)指的是所有的页面内容都成功加载,且能够快速地对用户的操作做出反应的时间点
总阻塞时间(Total Blocking Time)指首次内容绘制 (FCP)与 交互时间 (TTI)之间的总时间
累积布局偏移(Cumulative Layout Shift)衡量的是页面整个生命周期中每次元素发生的非预期布局偏移得分的总和。每次可视元素在两次渲染帧中的起始位置不同时,就说是发生了 LS(Layout Shift)标准≤0.1s
速度指标(Speed Index)衡量了首屏可见内容绘制在屏幕上的速度。在首次加载页面的过程中尽量展现更多的内容,往往能给用户带来更好的体验,所以速度指标的值约小越好

以下是一些实际中经常出现的一些概念性问题的说明。

白屏时间–FP

白屏时间FP(First Paint)指的是从用户输入url的时刻开始计算,一直到页面有内容展示出来的时间节点,推荐的标准≤2s

首字节时间–TTFB

默认指导航请求的TTFB(Time to First Byte),导航请求是指在浏览器切换页面时创建,从导航开始到该请求返回HTML

首次输入延迟–FID

FID(First Input Delay)首次输入延迟,标准是用户触发后,浏览器的响应时间, 标准≤100ms

累积布局偏移–CLS

这里对 CLS(Cumulative Layout Shift) 做一个说明,一开始我理解的CLS关注的是因为偏移问题,导致了重新渲染,降低了性能,之后了解到官网的解释是指:
在这里插入图片描述

用户下单时发现自己的订单有误,所以想返回重新选择,但是此时页面并没有完成加载,导致了广告栏被展示了,还没来得及隐藏,使得提交按钮与取消按钮的整体下移,此时用户手快,点击了提交按钮,其实用户是想点击取消按钮,用户的操作偏移到了提交上,因此该指标也是一个重要指标

性能指标分析

开发环境性能指标分析:
在这里插入图片描述

线上生产环境性能指标分析:
在这里插入图片描述

上图明显可以看出线上环境的指标数据比开发环境好,这是因为一般浏览器的开发插件可能导致性能降低!!!而且开发环境米有经历压缩打包等一系列的优化处理,而线上资源包都是处理后的产品,线下环境是不打包开发资源的

Lighthouse的性能优化方案

Lighthouse工具提供了一些优化的方案:
在这里插入图片描述

Opportunities节点下的建议:

  • Enable text compression:开启文本压缩
  • Serve images in next-gen formats:使用下一代图片格式
  • Eliminate render-blocking resources:消除非页面加载时关键的js、css资源
  • Efficiently encode images:压缩图片大小
  • Avoid large layout shifts:避免大的布局变化

Diagnostics 节点下的内容需要开发者通过调试来分析诊断;建议包括:

  • Serve static assets with an efficient cache policy: 静态资源使用高效的缓存策略,这里是因为一般静态资源发生变化的概率较小,而从内存缓存中加载静态资源基本是不消耗时间,磁盘缓存消耗时间一般也很小,也就是说从本地加载资源都比从服务器加载资源速度快,所以使用合适的缓存策略很重要
  • Avoid enormous network payloads:避免大的资源加重网络负载

在这里插入图片描述

在这里插入图片描述

Passed Audit节点下的内容可以查看所有检查的项,你也可以根据这部分逐项优化改进:

  • Minimize main-thread work:最小化主线程 这里会执行解析 Html、样式计算、布局、绘制、合成等动作

Chrome浏览器,默认会限制6个文件数量的并发请求。因此如果你有12个文件,针对 http 1.0 协议,就会分成2个批次去请求资源;如果是http2.0,就会同时请求这12个文件

性能优化实战解析

Serve images in next-gen formats

本人的项目Lighthouse工具有该提示,展开后有详细说明,说是最好使用下一代图片格式webp或者avif

因为现在网站涉及图片越来越多,所以对于同样清晰度的图片,体积自然是越小越好,而目前(2023年)这一点做的比较极致的两种格式是 webp/avif,接下还有一个比较关键的问题是浏览器的支持性。

支持webp的浏览器包括chrome/edge/firefox;

avif格式的图片,同样清晰度文件大小比webp还要小20%,但是支持的浏览器较少,所以本人采取了webp格式图片。

本人背景图是采用了一张大图,通过在线转换工具转换为webp质量无损的情况,体积缩小了20倍!!!

之前页面会出现渲染的痕迹,一部分一部分的在加载,修改后加载非常快,也不再有该现象

但是有一点需要注意的是,我发现本身体积就小的png图片,转化为webp反而体积增大了,所以感觉较大的图片比较适合转换为webp图片

这里记录一个非常好用的在线转换工具squoosh

Enable text compression

开启文本压缩,本人因为是轻量级的小项目,因此一开始是米有考略压缩的问题,通过该工具,发现部分三方资源的库打包后还是挺大的,具体解决方案可以参考以下压缩方案

gzip 压缩

gzip 压缩可以特别明显的提高我们的代码加载效果,提升效率 5-6 倍左右,它会把诸如 js、css 等文件进行压缩,并且让我们在加载时去请求那些 gz 文件而提升请求效率。

项目打包时gzip压缩
vue.config.js配置 gzip 压缩:
const CompressionPlugin = require("compression-webpack-plugin");

{
  configureWebpack: {
    plugins: [
      new CompressionPlugin({
        algorithm: "gzip", // 使用gzip压缩
        test: /\.js$|\.html$|\.css$/, // 匹配文件名
        filename: "[path].gz[query]", // 压缩后的文件名(保持原文件名,后缀加.gz)
        minRatio: 1, // 压缩率小于1才会压缩
        threshold: 10240, // 对超过10k的数据压缩
        deleteOriginalAssets: false // 是否删除未压缩的源文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false(比如删除打包后的gz后还可以加载到原始资源文件)
      })
    ];
  }
}

以下是压缩前后对比图:

在这里插入图片描述

vite.config.js 配置 gzip 压缩:
import viteCompression from 'vite-plugin-compression'

plugins: [
    viteCompression(
      {
        algorithm: 'gzip',//压缩算法,可选['gzip',' brotliccompress ','deflate ','deflateRaw']
        threshold: 10240,// 体积大于阈值,压缩,单位为b
        verbose: false,//是否在控制台中打印压缩结果
        ext: '.gz',
        deleteOriginFile: true,// 源文件压缩后是否删除
        disable: false,//是否禁用
      }
    )
]

注意,虽然设置了阈值,导致小于阈值的文件不会被压缩,但是终端却会打印出每个文件的压缩后大小--即最终生成的打包文件夹里没有该文件的压缩文件,但是会打印该文件压缩后的大小

加载时允许使用压缩

以上方式是在打包阶段生成了一个名为chunk-common.js.gz的压缩文件200kb,但是发现项目部署后,并不会加载.gz文件,仍旧加载是未压缩的600kb的chunk-common.js文件???!!!

通过资料的查找说是服务器也要允许加载压缩文件,因为现在基本都是前后端分离,所以这里的服务器,指的是前端代码部署的服务器,也就是nginx服务器,要支持并仅仅设置gzip_static on;。然后查看加载的资源,此时如果响应头中有Content-Encoding:gzip,说明启用gzip加载压缩文件成功

这里需要注意添加配置的位置!!!配置在nginx中 server 中是成功的,但是如果配置在server的location中有时是不成功的??!!!

以下是gzip_static配置在不同位置时的效果说明:

  1. 直接配置在 server

    server {
     gzip_static on;
    }
    

    在这里插入图片描述

    成功,此时response的响应类型、响应编码都是正常符合要求

  2. 配置在location根目录中,响应同上,也成功

    location / {
     gzip_static on;
    }
    
  3. 配置在非根location中,目前测试均不成功,也记录一下

    # assets文件夹中所有静态资源
    location ~ ^/assets {
     gzip_static on;
    }
    
    # assets文件夹中所有静态资源
    location /assets {
     gzip_static on;
    }
    
    # assets文件夹中所有静态资源js /css文件
    location ~ \.(css|js)$ {
     gzip_static on;
    }
    location ~ .*\.(css|js)${
     gzip_static on;
    }
    

    在这里插入图片描述

    发现所有的响应类型都是text/html,根本不是静态资源的本身类型???!!!
    最后在尝试的过程中发现以下设置会正常的动态响应静态文件的类型,发现是因为系统加载了源文件,根本没有开启gzip,感觉还是对于nginx配置不够熟悉导致的,以后再继续深入吧,目前可以通过方式1,2实现

    location = .*\.(css|js)${
      gzip_static on;
    }
    

这里有一点明确说明一下,不论是否是开启压缩,浏览器端加载的文件链接始终是.../assets/js/chunk-common.js,所以仅从Request URL是无法判断是否启用压缩了的。但是启用压缩后,可以观察到加载的文件大小变了,由原来的.js大文件变成了.gz文件的大小,加载的真实文件是chunk-common.js.gz,如果找不到该文件可能会去找chunk-common.js,所以在打包阶段一般不删除源文件,并且浏览器根据响应头的解压缩编码Content-Encoding:gzip对文件进行解码,所以可以根据两点判断是否启用了压缩:

  • 文件的大小
  • 响应头中是否存在Content-Encoding:gzip,存在即使用了压缩

注意:因为浏览器解压也需要时间,所以代码体积不是很大的话不建议使用 gzip 压缩

nginx代理 gzip压缩

项目开启gzip的方式有多种,这里并不是打包时预先生成了gzip,而是在请求资源时服务器(nginx)临时生成了.gz文件,服务器实时生成的gz资源再传输给浏览器

该方式主要是通过设置服务器(nginx)的配置文件,而不需要在其它位置再设置或添加代码了

nginx.conf配置文件:

http{
    # 开启压缩机制输出
    gzip on;
    # 指定会被压缩的文件类型(也可自己配置其他类型)
    gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
    # 设置压缩级别,越高资源消耗越大,但压缩效果越好
    gzip_comp_level 5;
    # Nginx 首先检查是否存在请求静态文件的 gz 结尾的文件,如果有则直接返回该 .gz 文件内容
    # gzip_static on;
    # 在头部中添加Vary: Accept-Encoding(建议开启)
    gzip_vary on;
    # 处理压缩请求的缓冲区数量和大小
    gzip_buffers 16 8k;
    # 对于不支持压缩功能的客户端请求不开启压缩机制
    gzip_disable "MSIE [1-6]\."; # 低版本的IE浏览器不支持压缩
    # 设置压缩响应所支持的HTTP最低版本
    gzip_http_version 1.1;
    # 设置触发压缩的最小阈值
    gzip_min_length 2k;
    # 关闭对后端服务器的响应结果进行压缩
    gzip_proxied off;
}

设置了以上内容,以上设置放置在非local /的块内时,静态资源加载没有使用gzip,但是在server/http块内都是生效的

根据以上两种方式:
一种预生成gzip文件,所有都使用gz文件,如果gz不存在就使用js文件
一种是加载时生成,所有请求时实时生成并使用gz文件

nginx.conf中关于gzip_static是注释掉的,或者没有的,此时仅仅是实时生成。
那么想要实现服务器存在则使用服务器.gz文件,如果服务器不存在.gz文件则实时生成.gz文件文件?
很简单,就是nginx.conf的配置文件两种配置方式都涵盖在内(即实时生成的配置中 gzip_static选项也开启或者去掉注释即可)!!!

那么对于同时使用了以上两种压缩方式的时候如何判断请求的资源是实时生成的.gz文件,还是打包时生成的.gz文件?

发现两种资源的响应头存在显著的区别,实时在线生成的Etag标签前有W/符号,但是响应头中两者的解码方式都是Content-Encoding:gzip

Etag:"654a0526-30eab"//打包时生成.gz文件
Etag:W/"654a0526-1a92"//请求时在线生成.gz文件

图片压缩

这里的图片压缩与上面的方式完全不同,上面Serve images in next-gen formats是指修改为下一代的图片格式,以最小体积展示同样清晰度的图片,而这里是指打包的时候对图片进行压缩

vue.config.js配置图片压缩
npm install image-webpack-loader

module.exports = {
    chainWebpack: config => {
        // 开启图片压缩
        config.module
             .rule('images')
             .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
             .use('image-webpack-loader')
             .loader('image-webpack-loader')
             .options({ bypassOnDebug: true });
    },
};
vite.config.js配置图片压缩:
npm i vite-plugin-imagemin -D

// vite.config.js

import { defineConfig } from 'vite';
import viteImagemin from 'vite-plugin-imagemin';

export default defineConfig({
  plugins: [
    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
          }
        ]
      }
    })
  ]
});

禁止生成 map 映射文件

vue 打包会保留源文件的 map 映射,方便打包部署后依然可以通过控制台的 source 查看搜索源文件的代码,方便定位问题,但是生成 map 文件会导致打包文件过大,看是否需要打包部署后的定位问题,不需要的话可以考虑禁止生成 map 映射文件。

module.exports = {
  productionSourceMap: true
};

拆分三方包

将一些三方包拆出来,如 vue, echarts 等都很大,拆出来后直接在页面加载更利于缓存。

vue.config.js的拆分方式
{
  configureWebpack: (config) => {
    let plugins = [
      new CompressionWebpackPlugin({
        algorithm: "gzip", //压缩方式
        test: productionGzipExtensions, //匹配压缩文件
        threshold: 2048 //对大于10k压缩
      })
    ];
    if (process.env.NODE_ENV === "production") {
      config.mode = "production";
      config.plugins = [...config.plugins, ...plugins];
    } else {
      config.mode = "development";
    }
    Object.assign(config, {
      externals: {
        vue: "Vue",
        element: "ElementUI",
        echarts: "echarts"
      }
    });
  };
}

拆出三方包后,打包文件会明显变小,但在 html 页面上需要显示引入三方包,如下:

<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

但是该方式也是存在隐患的,假如,有一天,该静态资源不可使用了…

vite.config.js的拆分方式
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: id => {
          // 将 node_modules 中的代码单独打包成一个 JS 文件
          if (id.includes('node_modules')) {
              return id.toString().split('node_modules/')[1].split('/')[0].toString();
          }
        }
      }
    }
  }
})

删除 console 打印语句

vite 引入工具包:

npm i terser -D
vite.config.js配置删除 console
export default defineConfig(({ mode }) => {
  return {
    build:{
      terserOptions: {
        compress: {
          drop_console: true,
          drop_debugger: true
        }
      }
    }
  }
})
@vue/cli配置删除 console

在@vue/cli脚手架中一般通过配置 babel.config.js:

const prodPlugin = []
if (process.env.NODE_ENV === 'production') {
  prodPlugin.push([// 如果是生产环境,则自动清理掉打印的日志,但保留onsole.error 与 console.warn
    'transform-remove-console',
    {
      exclude: ['error', 'warn'] 
    }
  ])
}
module.exports = {
  presets: ["@vue/cli-plugin-babel/preset"],
  plugins: [
    ...prodPlugin
  ]
};

CDN 资源加载

内容分发网络(Content Delivery Network,简称 CDN)是让用户从最近的服务器请求资源。提升网络请求的响应速度,同时减少应用打包体积,利用浏览器缓存,可以长期缓存不会变动的文件

vite配置 CDN 资源加载
  1. 通过 vite-plugin-cdn-import 工具包
    引入工具包:
npm i vite-plugin-cdn-import -D

vite.config.js配置CDN 资源加载:

// vite.config.js
import { defineConfig } from 'vite'
import viteCDNPlugin from 'vite-plugin-cdn-import'

export default defineConfig({
  plugins: [
    viteCDNPlugin({
      // 需要 CDN 加速的模块
      modules: [
        {
          name: 'lodash',
          var: '_',
          path: `https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js`
        }
      ]
    })
  ]
})
  1. 通过 vite-plugin-html/rollup-plugin-external-globals 工具包
    引入工具包
npm i vite-plugin-html -D
npm i rollup-plugin-external-globals -D

vite.config.js配置:

export default defineConfig(()=>{
  return {
      build: {
        rollupOptions: {
          external: ['vue'],
          plugins: [
            externalGlobals({
              // "项目中引入的变量名称":"CDN包导出的名称,一般在CDN包中都是可见的"
              vue: 'Vue'
            })
          ]
        }
      },
      plugins: [
        createHtmlPlugin({
          minify: true,//是否压缩 html
          inject: {
            data: {
              vuescript: '<script src="https://cdn.jsdelivr.net/npm/vue@3.2.37"></script>'
            }
          }
        })
    ]
  }
})

在index.html文件中的引入(定义的名称是什么,引入就用什么名称,例如上述定义为vuescript):

<head>
    <%- vuescript %>
</head>

Treeshaking

对没有用到的插件、api 不打包到最终打包后的静态文件中去,最新的 Vue、React 都是支持 Tree-Shaking 。

目前vue3支持自动treeshaking(删除冗余没有用到的相关代码)

总结分析

常见的一些提高性能的优化方案包括:

  1. 采用路由懒加载
  2. 将一些静态 js css 放到其他地方(如 OSS),减小服务器压力
  3. 按需加载三方资源,如 ant-design-vue,建议按需引入 ant-design-vue 中的组件
  4. nginx 容器开启 gzip 减小网络传输的流量大小
  5. webpack(打包的脚手架,也可以是vite) 开启 gzip 压缩
  6. 若首屏为登录页,可以做成多入口,登录页单独分离为一个入口
  7. 图片懒加载方案

优化维度–可访问性(Accessibility)

ARIA

Accessible Rich Internet Applications (ARIA) 无障碍技术规定了能够让 Web 内容和 Web 应用(特别是那些由 Ajax 和 JavaScript 开发的)对于残障人士更易使用的各种机制.

该技术的应用是无障碍阅读的工具,帮助改善无障碍阅读

NAMES AND LABELS

为FORM元素添加label标签,用于说明FORM元素的作用

优化维度–SEO(Search Engine Optimization)

可以点击查看SEO的一些简要介绍

  1. 网页添加 viewport,兼容移动端内容的展示
<meta name="viewport" content="width=device-width,initial-scale=1.0" />

网页适应移动端浏览器,并且阻止用户的 300ms 的用户输入延迟
2. 网页添加 title 标题
3. 设置 meta description 描述,方便搜索引擎搜索
4. 关于 rel = “canonical” 这个标签,早在 2009 年 2 月,谷歌、雅虎和 live search 三家搜索引擎宣布支持 Link 的一个新属性 Canonical.主要是帮助搜索引擎解决网站内容存在多个版本,来制定规范的链接,解决内容重复的收录。

rel="canonical"标签,是为了解决网站由于网站 url 链接不一样但网页内容是一样而造成百度重复收录的问题,对于这样的情况,如果不采用百度该标签,将导致百度对两个相同的网页收录和排名的问题上不知情,久而久之,当网站存在大量这样的网页的时候,可能导致网站大量重复内容而被降权、不收录甚至被禁用

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云吴结生:云计算是企业实现数智化的阶梯

云布道师 近年来&#xff0c;越来越多人意识到&#xff0c;我们正处在一个数据爆炸式增长的时代。IDC 预测 2027 年全球产生的数据量将达到 291 ZB&#xff0c;与 2022 年相比&#xff0c;增长了近 2 倍。其中 75% 的数据来自企业&#xff0c;每一个现代化的企业都是一家数据公…

LVM-系统

# Linux常见的文件系统&#xff1a;ext4&#xff0c;xfs&#xff0c;vfat(linux和window都能够识别) mkfs.ext4 /dev/sdb1 # 格式化为ext4文件系统 mkfs.xfs /dev/sdb2 # 格式化为xfs文件系统 mkfs.vfat /dev/sdb1 # 格式化为vfat文件系统 mksw…

第3节 二分、复杂度、动态数组、哈希表

二分法 入门题目 有序数组中找到num package class03;import java.util.Arrays; // 有序数组中找到num public class Code_BSExist {// arr保证有序public static boolean find(int[] arr, int num) { // 二分法&#xff0c;有缺陷if (arr null || arr.length 0) { // 边界…

Open3D (C++) 距离计算

目录 一、算法原理1、欧氏距离二、代码实现三、结果展示一、算法原理 1、欧氏距离 在数学中,欧几里得距离或欧几里得度量是欧几里得空间中两点间“普通”(即直线)距离。欧几里得距离有时候有称欧氏距离,在数据分析及挖掘中经常会被使用到,例如聚类或计算相似度。 如果我…

blender径向渐变材质-着色编辑器

要点&#xff1a; 1、用纹理坐标中的物体输出连接映射中的矢量输入 2、物体选择一个空坐标&#xff0c;将空坐标延z轴上移一段距离 3、空坐标的大小要缩放到和要添加材质的物体大小保持一致

【Spring Security】认证密码加密Token令牌CSRF的使用详解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Spring Security》。&#x1f3af;&#x1f3af; …

Ubuntu 常用命令之 sed 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 sed是一个在Linux和其他Unix-like系统中常用的流编辑器&#xff0c;用于对输入流&#xff08;文件或管道&#xff09;进行基本的文本转换。它可以非常方便地进行文本替换、插入、删除等操作。 sed命令的基本格式为 sed [options…

图像处理—小波变换

小波变换 一维小波变换 因为存在 L 2 ( R ) V j 0 ⊕ W j 0 ⊕ W j 0 1 ⊕ ⋯ L^{2}(\boldsymbol{R})V_{j_{0}}\oplus W_{j_{0}}\oplus W_{j_{0}1}\oplus\cdots L2(R)Vj0​​⊕Wj0​​⊕Wj0​1​⊕⋯&#xff0c;所以存在 f ( x ) f(x) f(x)可以在子空间 V j 0 V_{j_0} Vj0…

通讯录应用程序开发指南

目录 一、前言 二、构建通讯录应用程序 2.1通讯录框架 (1)打印菜单 (2) 联系人信息的声明 (3)创建通讯录 (4)初始化通讯录 2.2功能实现 (1)增加联系人 (2)显示联系人 (3)删除联系人 (4)查找联系人 (5)修改联系人 (6)排序联系人 三、通讯录的优化 3.1 文件存储 …

机器学习——分类评价指标

【说明】文章内容来自《机器学习——基于sklearn》&#xff0c;用于学习记录。若有争议联系删除。 1、评价指标 对于模型的评价往往会使用损失函数和评价指标&#xff0c;两者的本质是一致的。一般情况下&#xff0c;损失函数应用于训练过程&#xff0c;而评价指标应用于测试过…

代码随想录-刷题第三十四天

1005. K 次取反后最大化的数组和 题目链接&#xff1a;1005. K 次取反后最大化的数组和 思路&#xff1a;取反k次&#xff0c;保证每次取反的数值是数组中的最小值&#xff0c;最后数组和就是最大的。 class Solution {public int largestSumAfterKNegations(int[] nums, in…

pdf 在线编辑

https://smallpdf.com/edit-pdf#rapp 参考 https://zh.wikihow.com/%E5%B0%86%E5%9B%BE%E5%83%8F%E6%8F%92%E5%85%A5PDF

直排轮滑教程4

蹬地 1&#xff0c;前面练习了蹬地的结构&#xff0c;知道蹬地方向&#xff0c;如何用力。下面来练习具体的蹬地的方法&#xff0c;轮滑蹬地有自己特点。 2&#xff0c;技术方法和特点&#xff1a;蹬地速度快&#xff0c;蹬地有弹性。似跳非跳蹬。 3&#xff0c;四轮着地。轮…

GitHub打不开或者访问慢解决方法

一、获取IP地址 首先进入下面的网站 IP/DNS Detect 获取到当前github.com对应的IP地址 可以多search几次, github.com对应的IP地址不止一个,都记录下来 二、修改hosts文件内容 找到文件夹路径&#xff1a;C:\Windows\System32\drivers\etc\ 打开hosts文件&#xff0c;将刚才…

simulink代码生成(一)——环境搭建

一、安装C2000的嵌入式环境&#xff1b; 点击matlab附加功能&#xff0c; 然后搜索C2000&#xff0c;安装嵌入式硬件支持包&#xff1b;点击安装即可&#xff1b;&#xff08;目前还不知道破解版的怎么操作&#xff0c;目前我用的是正版的这样&#xff0c;完全破解的可能操作…

达梦到达梦的外部链接dblink(DM-DM DBLINK)

一. 使用场景&#xff1a; 部链接对象&#xff08;LINK&#xff09;是 DM 中的一种特殊的数据库实体对象&#xff0c;它记录了远程数据库的连接和路径信息&#xff0c;用于建立与远程数据的联系。通过多台数据库主库间的相互通讯&#xff0c;用户可以透明地操作远程数据库的数…

EDA实验-----直流电机驱动设计(Quartus II )

目录 一、实验目的 二、实验仪器设备 三、实验的重点和难点 四、实验原理 五、实验步骤 六、实验报告 七、实验过程 1.分频器代码 2.方向选择器 3.直流电动机工作原理 4.电路连接图 5.文件烧录 一、实验目的 了解直流电机控制的工作原理和实现的方法。掌握PWM波控…

OpenGL glLineWidth失效问题

文章目录 一、问题描述二、解决方法 一、问题描述 之前在使用OpenGL时&#xff0c;突然发现glLineWidth失效了&#xff0c;也就是怎么设置线宽都没反应&#xff0c;也使用了一些方法检测了自己的电脑是否支持线宽&#xff08;其实大部分电脑都支持&#xff09;&#xff0c;最后…

IgH调试注意事项

1&#xff0c;不要在虚拟机测试&#xff0c;否则IgH无法收发数据包 现象&#xff1a;虚拟机中运行IgH master并绑定网卡后&#xff0c;主站由ORPHANED状态转换成IDLE状态&#xff0c;但无法收发数据报。 这是因为虚拟机用的是虚拟网卡&#xff0c;需通过iptables将数据包到转…

基于SSM的旅游网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…