前端性能优化实践方向与方法

news/2024/9/20 15:31:17/文章来源:https://www.cnblogs.com/SRIGT/p/18325542

0x01 代码优化与压缩

(1)HTML

移除不必要的空白字符、注释和冗余标签,以减少文件大小

  1. 使用命令 npm install html-minifier -g 安装 HTML Minifier

  2. 使用命令 html-minifier -V 确认安装成功

  3. 在 Node.js 环境中配置 index.js

    // 引入 HTML Minifier
    const minify = require("html-minifier").minify;// 处理 HTML 文本
    let result = minify('<p title="blah" id="moo">foo</p>', {removeAttributeQuotes: true,
    });// 输出处理结果
    console.log(result);
    
  4. 使用命令 node .\index.js 运行,输出结果为:<p title=blah id=moo>foo</p>

  5. 详细参考:https://www.npmjs.com/package/html-minifier
    在线使用:https://kangax.github.io/html-minifier/

(2)CSS

精简样式表,避免使用冗余或过时的属性,合理组织选择器以减少计算复杂度

  1. 使用命令 npm install cssnano postcss postcss-cli --save-dev 安装 PostCSS 与 CSSNaNo

  2. 在 Node.js 环境中配置 postcss.config.js

    module.exports = {plugins: [require("cssnano")({preset: "default",}),],
    };
    
  3. 使用命令 npx postcss input.css > output.css 运行,生成优化后的结果 output.css

  4. 详细参考:https://www.cssnano.cn/docs/introduction/

  5. 其他工具:

    1. PostCSS:https://www.postcss.com.cn/
    2. PurgeCSS:https://www.purgecss.cn/

(3)JavaScript

使用工具(如 Webpack 等)或在线服务对代码进行压缩,移除空格、注释和不必要的字符

  1. 使用命令 npm install terser-webpack-plugin --save-dev 安装 terser-webpack-plugin

  2. 在 Node.js 环境中配置 webpack.config.js

    const TerserPlugin = require("terser-webpack-plugin");module.exports = {optimization: {minimize: true,minimizer: [new TerserPlugin()],},
    };
    
  3. 使用命令 npx webpack 运行 Webpack 打包工具,并优化 JavaScript 代码

(4)合并文件

将多个 CSS、JavaScript 文件合并为一个,减少 HTTP 请求的数量

  • 在 Webpack 中,可以通过配置 entryoutput 选项来自动合并多个模块到一个文件中
  • 在 Gulp 中,可以使用 gulp-concat 插件来合并文件

0x02 静态资源优化

(1)压缩图片

  • TinyPNG:API Reference
  • ImageOptim:Optimize on the fly
  • imagemin:https://www.npmjs.com/package/imagemin

(2)图片懒加载

a. 原生 JavaScript

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><style>img {width: 1000px;height: 700px;background-color: wheat;object-fit: cover;object-position: center;}</style>
</head><body><img src="" data-src="./images/1.jpg" alt="" /><img src="" data-src="./images/2.jpg" alt="" /><img src="" data-src="./images/3.jpg" alt="" /><img src="" data-src="./images/4.jpg" alt="" /><img src="" data-src="./images/5.jpg" alt="" /><script>/*** 初始化图片懒加载功能。* 该函数通过监听窗口的滚动事件,来实现图片的延迟加载。当图片进入视口时,将其src属性设置为真正的图片源URL,从而实现懒加载的效果。*/const imageLazyLoad = () => {// 获取页面中所有带有data-src属性的图片元素const imgs = document.querySelectorAll("img");// 定义计算函数,用于检查图片是否进入视口const calc = () => {imgs.forEach((img) => {// 检查图片是否进入视口:如果图片的顶部位置小于等于窗口的底部位置,则图片已进入视口,可以加载if (img.offsetTop <= window.innerHeight + window.scrollY)// 设置图片的src属性为data-src属性的值,真正开始加载图片img.src = img.dataset.src;else// 如果图片未进入视口,则返回,不进行加载return;});};// 监听窗口的滚动事件,以便在滚动时触发图片的加载window.addEventListener("scroll", () => calc());// 初次加载页面时,立即计算并加载可视区域内的图片calc();};// 调用函数,初始化图片懒加载imageLazyLoad();</script>
</body></html>

b. Intersection Observer API

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><style>img {width: 1000px;height: 700px;background-color: wheat;object-fit: cover;object-position: center;}</style>
</head><body><img src="" data-src="./images/1.jpg" alt="" /><img src="" data-src="./images/2.jpg" alt="" /><img src="" data-src="./images/3.jpg" alt="" /><img src="" data-src="./images/4.jpg" alt="" /><img src="" data-src="./images/5.jpg" alt="" /><script>/*** 初始化图片懒加载* 该函数通过IntersectionObserver API来实现图片的懒加载。只有当图片进入视口时,才会真正加载图片资源*/const imageLazyLoad = () => {// 获取所有需要懒加载的图片元素const imgs = document.querySelectorAll("img");// 创建IntersectionObserver实例,用于观察图片是否进入视口const observer = new IntersectionObserver((entries) => {// 遍历所有观察到的条目entries.forEach((entry) => {// 如果图片进入视口if (entry.isIntersecting) {let img = entry.target;// 设置图片的src属性为data-src属性的值,即真正的图片源地址img.src = img.dataset.src;// 停止观察该图片,因为它已经加载observer.unobserve(img);}});});// 对所有需要懒加载的图片元素启用IntersectionObserver观察imgs.forEach((img) => {observer.observe(img);});};imageLazyLoad();</script>
</body></html>

c. 第三方库

  • 如 vue-lazyload(Vue 框架中使用)

(3)CDN

  • 部署内容分发网络(CDN),将静态资源托管在地理位置接近用户的边缘节点上,减少延迟
  • 步骤:
    1. 选择 CDN 服务提供商,如 Amazon、Cloudflare 等
    2. 上传静态资源
    3. 配置 DNS
    4. 测试并优化
  • 优点:减少访问延迟、提高可用性、减轻源服务器负载

(4)缓存机制

  • 步骤:
    1. 设置 Cache-Control 头部:响应头字段,表示在缓存有效期内直接从本地缓存中加载这些资源,而不是向服务器发送请求
    2. 使用 ETag:响应头字段,表示资源的特定版本
      • 当浏览器再次请求资源时,会将 ETag 值发送给服务器,如果资源未更改(即 ETag 值相同),服务器将返回 304 Not Modified 响应,告诉浏览器使用本地缓存的版本。
    3. 配置 Expires 头部:兼容旧版浏览器
  • 优点:减少服务器负载、加快加载速度、改善用户体验

0x03 渲染性能优化

(1)减少 DOM 元素数量

避免不必要的 DOM 元素,以减少渲染和重绘的时间

  1. 使用 CSS 替代 DOM 元素

    举例:

    <ul><li><img src="icon1.png" alt="Icon 1"><span>Item 1</span></li><li><img src="icon2.png" alt="Icon 2"><span>Item 2</span></li>
    </ul>
    

    优化为

    <ul><li class="item">Item 1</li><li class="item">Item 2</li>
    </ul><style>
    .item::before {content: "";display: inline-block;width: 20px;height: 20px;background-image: url(icon-based-on-class.png);background-size: cover;margin-right: 5px;
    }
    </style>
    
  2. 引入 Flex 布局与 Grid 布局

    举例:

    <div class="container"><div class="row"><div class="col">Item 1</div><div class="col">Item 2</div></div>
    </div>
    

    优化为

    <div style="display: flex;"><div>Item 1</div><div>Item 2</div>
    </div>
    
  3. 多个动态内容采用 DocumentFragment 添加

    举例:

    for (let i = 0; i < 100; i++) {let li = document.createElement("li");li.textContent = `Item ${i}`;document.querySelector("ul").appendChild(li);
    }
    

    优化为

    let fragment = document.createDocumentFragment();
    for (let i = 0; i < 100; i++) {let li = document.createElement("li");li.textContent = `Item ${i}`;fragment.appendChild(li);
    }
    document.querySelector("ul").appendChild(fragment);
    

    DocumentFragment 是一个轻量级的文档对象,可以包含节点和子节点,但不会成为文档树的一部分

(2)事件委托

通过事件委托来减少与 DOM 的交互次数,提高性能

  • 事件委托:一种事件处理的技术,它利用事件冒泡的原理,只在父元素上设置一个事件监听器,而不是在每个子元素上分别设置。当子元素上发生事件时,该事件会冒泡到父元素,父元素上的事件监听器会检查事件源(即触发事件的子元素),并据此执行相应的操作

  • 举例

    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" />
    </head><body><ul><li>Item 1</li><li>Item 2</li></ul><button>Add item</button><script>const ul = document.querySelector("ul");ul.addEventListener("click", (e) => {if (e.target.tagName === "LI") {console.log("e.target.textContent", e.target.textContent);e.target.remove();}});const button = document.querySelector("button");button.addEventListener("click", () => {const newItem = document.createElement("li");newItem.textContent = `Item ${ul.children.length + 1}`;ul.appendChild(newItem);});</script>
    </body></html>
    

(3)优化 DOM 操作

使用批量更新、虚拟 DOM 等技术减少重绘和回流

  1. 批量更新:将多个 DOM 操作合并成一个批次,然后一次性执行(参考 DocumentFragment)
  2. 虚拟 DOM:一种编程概念,用 JavaScript 对象来表示 DOM 树
    • 当应用程序的状态发生变化时,虚拟 DOM 树会首先进行更新,然后使用高效的算法(如 diff 算法)来比较新旧虚拟 DOM 树之间的差异,并只将这些差异应用到真实的 DOM 上
    • 即检测发生变化的 DOM 元素,并仅对变化的 DOM 元素操作,减少不必要的 DOM 操作
    • 一般在 React、Vue 等前端框架中广泛应用

(4)CSS 放在顶部

  • 将CSS放在 <head> 标签内,以确保页面在加载时能够优先渲染样式

    <head><link rel="stylesheet" href="style.css" />
    </head>
    

(5)异步加载 JavaScript

  • 将非首屏必需的 JS 脚本放在文档末尾或使用 asyncdefer 属性,避免阻塞渲染

    <!DOCTYPE html>
    <html lang="en"><head><!-- 同步加载首屏必需脚本 --><script src="critical.js"></script>
    </head><body><!-- 页面内容 --><!-- 异步加载非首屏且无依赖的脚本 --><script async src="non-critical-async.js"></script><!-- 异步加载但按顺序执行的非首屏脚本 --><script defer src="non-critical-defer.js"></script><!-- 将非首屏脚本放在底部(适用于不支持 async/defer 的老旧浏览器) --><!-- <script src="non-critical-old-browser.js"></script> -->
    </body></html>
    
  • asyncdefer

    • 两者都用于异步加载脚本
    • async:完全异步,脚本的加载和执行不会阻塞文档的解析,但多个异步脚本之间执行顺序不一定,不建议用于具有依赖关系的脚本
    • defer:等到整个文档都被解析和显示之后,再按照脚本在文档中出现的顺序来执行

0x04 网络性能优化

(1)启用 HTTP/2 或 HTTP/3

  • 启用 HTTP/2 或 HTTP/3,利用多路复用、头部压缩等特性提升请求效率
  • 一般在 Web 服务器中,通过 Nginx、Apache 等配置并启用

(2)TLS/SSL

  • 确保网站使用 HTTPS 加密传输,提高安全性并可能获得 SEO 优势
  • HTTPS、TLS/SSL 在网络传输的应用参考:浏览器工作过程及相关名词 | 博客园-SRIGT

(3)预加载和预读取

a. 预加载

  • 预加载:一种资源提示,它告诉浏览器这个资源对于当前导航立即需要,并且应该被优先下载和解析

    • 如字体、CSS 和关键 JavaScript 脚本
  • 使用 <link rel="preload"> 预加载关键资源

    <head><!-- 预加载字体 --><link rel="preload" href="fonts/myfont.woff2" as="font" type="font/woff2" crossorigin="anonymous"><!-- 预加载CSS --><link rel="preload" href="styles/main.css" as="style"><!-- 其他头部标签... -->
    </head>
    

b. 预读取

  • 预读取:一种资源提示,它告诉浏览器这个资源可能会在将来的导航中被用到,但不像预加载那样具有紧迫性

    • 浏览器可以选择在空闲时间下载这些资源,以便在用户实际需要它们时能够更快地加载
  • 使用 <link rel="prefetch"> 预读取可能需要的未来资源

    <link rel="prefetch" href="details/product-images.jpg">
    <link rel="prefetch" href="details/product-details.js"> 
    

(4)本地缓存

  • 存储限制:存储大小限制在 4KB 左右,且存储数量有限制
  • 缺点:
    1. 每次都会将 Cookie 数据携带在 HTTP 请求中,可能带来性能问题占用带宽
    2. 安全性较低
  • 由于浏览器的跨域限制,客户端和服务端必须保证同源原则
  • 场景:跟踪用户会话信息,如用户登录状态、购物车信息等
  • Session:以键值对的方式将缓存数据保存在服务器中,并把键值(Session ID)作为 Cookie 返给浏览器
  • Token:应对移动互联网不提供 Cookie 的解决方案,将数据哈希加密并保存在移动端的存储系统中
    • JWT 是一种广泛应用的 Token 标准

b. LocalStorage

  • HTML5 提供的一种新的本地缓存方案,用于存储数据在用户的浏览器中
  • 存储限制:
    • 长久保存,无有效期,直到手动删除或浏览器清理缓存为止
    • 存储空间一般可以达到 5MB 及以上(不同的浏览器有所区别)
  • 场景:存储需要在多个页面或会话中持久保存的数据,如用户偏好设置、游戏进度等

c. SessionStorage

  • 大体与 LocalStorage 类似,在存储限制上,数据仅在当前会话期间有效,浏览器关闭或标签页关闭后数据即被清除
  • 场景:存储仅在当前会话中需要的数据,如临时状态信息、表单数据等

d. IndexedDB

  • 一个低级的 API,允许进行复杂的查询、事务处理和数据库管理操作,提供索引功能
  • 存储限制:存储空间相对较大,可以存储大量数据
  • 场景:存储大量结构化数据并需要进行复杂查询,如离线应用、游戏数据存储等

e. Cache API

  • 一种用于存储和检索网络请求的响应的接口

  • 可以与 Service Workers 结合使用,实现离线应用和性能优化

    Service Workers:在 Web 浏览器中运行的脚本,具备在后台独立于网页运行的能力

    • 提供很多高级功能,如离线内容缓存、推送通知、背景数据同步等
  • 场景:精确控制缓存策略和资源缓存,如构建 PWA(Progressive Web Apps)时

0x05 框架与库的选择与优化

(1)框架

  • 轻量级

    • Preact:3kb 大小的 React 轻量、快速替代方案,拥有相同的现代 API
    • Vue3:在 Vue2 基础上,应用 Tree-shaking,允许在构建过程中自动移除未使用的代码
  • 按需加载

    • 采用代码分割懒加载技术,将应用拆分成多个小块,并在需要时才加载它们

    • 以 Vue Router 为例,Vue Router 支持动态导入

      const routes = [{path: "/products",name: "Products",// 使用动态导入来懒加载组件component: () =>import(/* webpackChunkName: "products" */ "./views/Products.vue"),},// 其他路由...
      ];
      

(2)第三方库

  • 仅引入必要的库,避免过时或冗余的库,定期检查更新以利用性能优化

0x06 性能监控与优化工具

(1)性能分析工具

  • Lighthouse:Google 开发的一款开源自动化工具,集成在 Chrome DevTools 中
  • PageSpeed Insights:Google 提供的一款免费工具,官网链接
  • Chrome DevTools Performance 面板:集成在 Chrome DevTools 中

(2)用户性能监控

采用集成 RUM(Real User Monitoring)工具收集实际用户的加载性能数据

  • Google Analytics:使用插件 Google Tag Manager 来部署 RUM 脚本,该脚本将收集用户交互数据并发送到 Google Analytics 进行处理和分析
  • SpeedCurve:https://www.speedcurve.com/

0x07 其他优化策略

(1)首屏内容优化

  • 确保首屏加载时立即展示关键内容,避免用户看到空白或加载指示器过久
  • 举例:电商网站首屏优化操作
    • 精简首屏内容:保留最关键的内容,如网站Logo、欢迎语、轮播图、商品推荐
    • 优化图片和脚本:压缩和优化所有首屏加载的图片,合并和压缩 CSS 和 JavaScript 脚本进行,减少HTTP请求次数
    • 异步加载非关键内容:非首屏关键内容设置为异步加载,即用户滚动到相应位置时再加载这些内容
    • 使用CDN加速:将网站内容分发到全球多个 CDN 节点,根据用户地理位置选择最近的节点进行加载
    • 预加载和缓存:利用浏览器的预加载和缓存机制,提前加载和存储一些常用的资源文件

(2)语义化 HTML

  • 使用合理 HTML 标记以及其特有的属性去格式化文档内容,提高内容可理解性

  • 详细方法参考:HTML语义化 | CSDN-北航程序员小陈

  • 举例:

    <!DOCTYPE html>
    <html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>新闻文章标题</title>
    </head><body><header><h1>新闻文章标题</h1><p>由 <a href="/author-profile">作者姓名</a> 发表于 <time datetime="2023-04-01">2023年4月1日</time></p></header><main><article><h2>引言</h2><p>这里是引言部分的内容,简要介绍文章的主题和背景。</p><h2>正文标题</h2><p>这里是正文的第一段,详细阐述文章的主要观点或故事。</p><h3>小节标题</h3><p>这里是文章中的一个小节,进一步细化或支持主要观点。</p><!-- 可以继续添加更多的h2、h3、p等元素来构建文章内容 --><footer><p>文章结束。</p></footer></article></main><aside><h2>相关文章</h2><ul><li><a href="/article1">相关文章1</a></li><li><a href="/article2">相关文章2</a></li><!-- 更多相关文章链接 --></ul></aside><footer><p>版权所有 &copy; 2023 网站名称</p></footer>
    </body></html>
    

(3)元数据

  • 设置 <title><meta><link rel="canonical"> 等 SEO 相关标签

  • 举例:

    <!DOCTYPE html>
    <html lang="zh-CN"><head><!-- 页面编码,用于处理不同语言的字符串 --><meta charset="UTF-8" /><!-- 设置视口,确保网页在不同设备上正确显示 --><meta name="viewport" content="width=device-width, initial-scale=1.0" /><!-- 页面标题,显示在浏览器标签和搜索结果中 --><title>页面标题 - 网站名称</title><!-- 页面描述,显示在搜索结果中,用于概括页面内容 --><meta name="description" content="这里是页面的简短描述,应包含关键词并吸引用户点击。" /><!-- 页面关键词,虽然现代搜索引擎对keywords标签的重视程度降低,但仍可作为参考 --><meta name="keywords" content="关键词1, 关键词2, 关键词3" /><!-- 指定页面的规范URL,有助于防止内容重复被搜索引擎索引 --><link rel="canonical" href="https://www.example.com/your-page-url" /><!-- 其他可能的元数据 --><meta name="author" content="作者姓名或组织" /> <!-- 添加作者信息 --><meta name="robots" content="index, follow" /> <!-- 指示搜索引擎索引并跟踪页面上的链接 --><!-- 对于响应式网站,可以使用meta标签来适应不同设备 --><meta name="HandheldFriendly" content="true" /> <!-- 告诉移动设备,页面适合于手机浏览 --><meta name="MobileOptimized" content="320" /> <!-- 指定移动设备的屏幕宽度,以适应响应式设计 --><!-- 引入CSS样式 --><link rel="stylesheet" href="style.css" />
    </head><body><!-- 页面内容 --><!-- 引入JavaScript脚本 --><script src="script.js"></script>
    </body></html>
    

(4)结构化数据

  • 结构化数据:一种使用特定格式(如 JSON-LD、Microdata 或 RDFa)来标记网页内容的方式,以便搜索引擎和其他机器能够更容易地理解和处理这些信息

  • 举例:以下是采用 Schema.org 和JSON-LD 格式的结构化数据

    <!DOCTYPE html>
    <html lang="zh-CN"><head><meta charset="UTF-8" /><title>电影《星际穿越》</title><script type="application/ld+json">{  "@context": "https://schema.org/",  "@type": "Movie",  "name": "星际穿越",  "image": "https://example.com/movie-poster.jpg",  "director": {  "@type": "Person",  "name": "克里斯托弗·诺兰"  },  "genre": ["科幻", "剧情", "冒险"],  "actor": [  {  "@type": "Person",  "name": "马修·麦康纳希"  },  {  "@type": "Person",  "name": "安妮·海瑟薇"  }  ],  "datePublished": "2014-11-07",  "description": "一队探险家利用他们针对虫洞的新发现,超越人类对于太空旅行的极限,从而开始在广袤的宇宙中进行星际航行的故事。",  "aggregateRating": {  "@type": "AggregateRating",  "ratingValue": "8.7",  "reviewCount": "123456"  }  }  </script>
    </head><body><!-- 网页内容 --><h1>电影《星际穿越》</h1><p>导演:克里斯托弗·诺兰</p><p>主演:马修·麦康纳希, 安妮·海瑟薇</p><p>类型:科幻, 剧情, 冒险</p><p>上映日期: 2014年11月7日</p><p>剧情简介:...(详细描述)</p>
    </body></html>
    

(5)无障碍性(a11y)

  • 无障碍性:确保网站对所有用户,包括残障用户,都能够友好地访问和使用
  • WCAG 标准:Web 内容无障碍指南
  • 举例:
    1. 非文本内容的文本替代
      • 如:<img alt="这是一张图片" />
    2. 键盘可访问
    3. 清晰和一致的导航
    4. 足够的颜色对比度
    5. 字幕和音频描述

-End-

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【YashanDB知识库】开源调度框架Quartz写入Boolean值到YashanDB报错

问题现象 Quartz 是一个广泛应用于企业级应用中的开源作业调度框架,它主要用于在Java环境中管理和执行任务。 为了任务调度,Quartz的数据模型中使用了大量的布尔值记录任务、流程的各种状态,如:Quartz使用JDBC写入任务状态代码: ps = conn.prepareStatement(); setBoolean…

jmeter 测试getpost请求测试遇到的问题

GET请求Get请求的参数要写在Url后面,不能写在请求体POST请求post请求验证除了cookie之外,可能还会有token,需要加到http请求头里面提示说是会话校验失败,猜测是cookie失效或者是少了参数,查看请求post请求Content-Type和实际接口不符合,接口返回415错误服务器返回415,表…

01HTML+CSS

今日正式开始学习前端,学习内容有 1.标签的写法:标签分为单标签和双标签,其中他们都是由尖括号组成<>,例如:加粗标签<strong></strong>,倾斜标签<em></em>,下划线标签<ins></ins>,删除线标签<del></del>。 2.HT…

24数据安全产业人才积分争夺赛

Wireshark2.1 题目内容:存在漏洞的PHP页面名称是?(比如:a.php) 直接搜索php所以flag: theanswerishere.php Wireshark2.2 题目内容:当前表的列数共有几列?(比如:1)找到了 所以flag:3 Wireshark2.3 题目内容:注入目标的列名是?所以flag:th1sfI4g 错的,要加flag{}…

MySQL入门---(一)SQL的DDL语句

1.管理员身份进入命令行窗口:win+r cmd 然后不要直接点,按ctrl+shift+enter管理员模式进去,点确定 2.MySQL数据库启动:net start mysql80 停止:net stop mysql80 3.系统自带的命令行工具执行指令:mysql -u root -p 1.SQL通用语法:2.DDL语句3.表结构查询:4.创建表结构…

《最新出炉》系列入门篇-Python+Playwright自动化测试-54- 上传文件(input控件) - 上篇

1.简介 在实际工作中,我们进行web自动化的时候,文件上传是很常见的操作,例如上传用户头像,上传身份证信息等。所以宏哥打算按上传文件的分类对其进行一下讲解和分享。 2.上传文件的API(input控件) Playwright是一个现代化的自动化测试工具,它支持多种浏览器和操作系统,…

ceph数据重构原理

在分布式存储系统Ceph中,硬盘故障是一种常见问题。为了保证数据安全,当发生硬盘故障后,分布式存储系统会依据算法对故障硬盘上的数据进行数据重构及转储。和一般分布式系统一样的是,Ceph同样使用多副本机制来保证数据的高可靠性(注:EC在实现层面可以理解为副本机制的一种…

服务网关-GateWay-微服务核心组件【分布式微服务笔记05】

服务网关-GateWay-微服务核心组件【分布式微服务笔记05】 服务网关-GateWay 引出GateWay 当我们后端的服务部署在不同的ip和端口上,存在一些问题:前端项目需要维护不同的后端服务ip/访问接口,非常麻烦 如果调用的是后端的集群服务,存在负载均衡问题 没有断言以及过滤机制 因…

ComfyUI插件:IPAdapter_plus(新版)节点

ComfyUI插件:IPAdapter_plus(新版)节点前言:学习ComfyUI是一场持久战,而IPAdapter_plus是常用且便捷有效的风格迁移模型,可以通过提供参考图像去进行图像的生成,比如风格迁移,风格融合,人物脸部模拟等各种工作,请大家重点关注本篇内容,深刻理解节点用法!!祝大家学习…

可以捕捉高动态范围成像的的AR0521SR2C09SURA0-DP2、AR0522SRSM09SURA0-DP2、AR0821CSSC18SMEA0-DPBR图像传感器

推出可以捕捉高动态范围成像的的AR0521SR2C09SURA0-DP2、AR0522SRSM09SURA0-DP2、AR0821CSSC18SMEA0-DPBR图像传感器AR0521SR2C09SURA0-DP2、AR0522SRSM09SURA0-DP2、AR0821CSSC18SMEA0-DPBR图像传感器——明佳达 1、AR0521SR2C09SURA0-DP2是一款 1/2.5 英寸 CMOS 数字图像传感…

波段空单 豆油

首先要破掉7780分型 反弹加空 损新高。

EasyExcel复杂导出 一对多

将数据一条一条查出来 千万不要用一对多查询 最后用方法进行合并public class ExcelFileCellMergeStrategy implements CellWriteHandler{ /** * 合并列的范围索引 */ private int[] mergeColumnIndex; /** * 合并起始行索引 */ private int merge…