JavaScript性能优化实战(9):图像与媒体资源优化
引言
在当今视觉驱动的网络环境中,图像和媒体资源往往占据了网页总下载量的60%-80%,因此对图像和媒体资源进行有效优化已成为前端性能提升的关键领域。尽管网络带宽持续提升,但用户对加载速度的期望也在不断提高,特别是在移动设备和网络条件不稳定的场景下。
本文作为JavaScript性能优化实战系列的第九篇,将深入探讨图像与媒体资源优化的各个方面,从现代图像格式选择、响应式图像加载、Canvas和WebGL渲染技巧,到视频流优化以及OffscreenCanvas的应用。我们将结合实际案例,为您提供实用且可立即应用的优化策略,助力提升您的Web应用性能。
现代图像格式选择与性能对比
图像是网页中最常见的资源类型之一,选择合适的图像格式对性能有着决定性影响。
主流图像格式性能对比
格式 | 优势 | 劣势 | 最佳使用场景 | 浏览器支持 |
---|---|---|---|---|
JPEG | 压缩率高 兼容性好 | 有损压缩 不支持透明 | 照片、复杂色彩图像 | 全面支持 |
PNG | 无损压缩 支持透明 | 文件较大 | 需要透明度的图像 图标、简单图形 | 全面支持 |
GIF | 支持动画 兼容性好 | 色彩有限(256色) 压缩效率低 | 简单动画 图标 | 全面支持 |
WebP | 同时支持有损和无损 支持透明度和动画 比JPEG小25-34% | IE不支持 | 几乎所有场景 替代JPEG/PNG | Chrome, Firefox, Edge, Safari 14+ |
AVIF | 比WebP小50% 更好的压缩率 | 编码速度慢 浏览器支持有限 | 静态图像 照片 | Chrome, Firefox, Opera |
SVG | 矢量格式 任意缩放不失真 文件小 | 不适合复杂图像 渲染成本高 | 图标、Logo 简单插图 | 全面支持 |
现代图像格式深入分析
WebP格式
WebP是由Google开发的图像格式,提供了优异的压缩性能。
// 使用JavaScript检测WebP支持
function checkWebPSupport() {return new Promise((resolve) => {const webpImage = new Image();webpImage.onload = () => { resolve(true); };webpImage.onerror = () => { resolve(false); };webpImage.src = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAgA0JaQAA3AA/vv9UAA=';});
}// 根据浏览器支持提供相应格式
async function provideOptimalImageFormat() {const isWebPSupported = await checkWebPSupport();const imageUrl = isWebPSupported ? 'image.webp' : 'image.jpg';document.getElementById('hero-image').src = imageUrl;
}provideOptimalImageFormat();
AVIF格式
AVIF是基于AV1视频编解码器的图像格式,提供更好的压缩率和质量。
// 检测AVIF支持
function checkAVIFSupport() {return new Promise((resolve) => {const avifImage = new Image();avifImage.onload = () => { resolve(true); };avifImage.onerror = () => { resolve(false); };avifImage.src = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=';});
}
根据场景智能选择格式
基于不同图像类型的特性,我们可以智能选择最佳格式:
// 根据图像内容和浏览器支持选择最佳格式
async function selectOptimalFormat(imageType, needsTransparency) {const supportsAVIF = await checkAVIFSupport();const supportsWebP = await checkWebPSupport();if (imageType === 'photo') {if (supportsAVIF) return 'avif';if (supportsWebP) return 'webp';return 'jpg';}if (imageType === 'graphic') {if (needsTransparency) {if (supportsAVIF) return 'avif';if (supportsWebP) return 'webp';return 'png';}return 'svg';}if (imageType === 'animation') {if (supportsWebP) return 'webp';return 'gif';}return 'jpg'; // 默认
}
图像转换与优化工具
选择合适的格式后,我们还需要对图像进行进一步的优化:
- sharp.js: 用于Node.js环境中高性能图像处理
- imagemin: 广泛使用的图像压缩工具,支持多种格式
- squoosh.app: Google提供的在线图像优化工具
以下是使用imagemin在构建流程中优化图像的示例:
// webpack.config.js中使用imagemin-webpack-plugin
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const ImageminMozjpeg = require('imagemin-mozjpeg');
const ImageminPngquant = require('imagemin-pngquant');
const ImageminWebp = require('imagemin-webp');module.exports = {// ... 其他配置plugins: [new ImageminPlugin({test: /\.(jpe?g|png|gif|svg)$/i,pngquant: {quality: '65-80'},plugins: [ImageminMozjpeg({quality: 75,progressive: true}),ImageminWebp({ quality: 75 })]})]
};
图像格式性能测试与对比
下面展示了不同格式对同一图像的压缩效果对比:
图像 | 原始大小 | JPEG (Q=80) | WebP (Q=80) | AVIF (Q=60) | 加载时间对比(3G网络) |
---|---|---|---|---|---|
风景照 | 5.2MB | 820KB | 410KB | 205KB | JPEG: 4.1s, WebP: 2.1s, AVIF: 1.1s |
产品照 | 3.8MB | 640KB | 320KB | 160KB | JPEG: 3.2s, WebP: 1.6s, AVIF: 0.8s |
图标集 | 1.5MB | 不适用 | 180KB | 90KB | PNG: 1.8s, WebP: 0.9s, AVIF: 0.5s |
关键发现:对于典型的图像内容,WebP比JPEG减少约50%的文件大小,而AVIF比WebP再减少约50%。这直接转化为加载时间的显著改善。
响应式图像加载与懒加载实现
在不同设备和网络条件下,我们需要为用户提供最适合其环境的图像资源,这就是响应式图像加载的核心思想。
响应式图像技术
使用srcset和sizes属性
HTML5提供了强大的响应式图像属性:
<img src="small.jpg" srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1600w" sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1600px"alt="响应式图像示例">
这告诉浏览器:
- 在窄屏设备(600px以下)上使用small.jpg (400px宽)
- 在中等宽度设备(600px-1200px)上使用medium.jpg (800px宽)
- 在宽屏设备(1200px以上)上使用large.jpg (1600px宽)
使用picture元素实现格式和分辨率响应
<picture><source media="(min-width: 1200px)" srcset="large.avif" type="image/avif"><source media="(min-width: 1200px)" srcset="large.webp" type="image/webp"><source media="(min-width: 1200px)" srcset="large.jpg"><source media="(min-width: 600px)" srcset="medium.avif" type="image/avif"><source media="(min-width: 600px)" srcset="medium.webp" type="image/webp"><source media="(min-width: 600px)" srcset="medium.jpg"><source srcset="small.avif" type="image/avif"><source srcset="small.webp" type="image/webp"><img src="small.jpg" alt="响应式图像示例">
</picture>
这个例子不仅根据屏幕宽度提供不同尺寸的图像,还根据浏览器支持提供不同的格式。
图像懒加载实现
图像懒加载是一种延迟加载视口外图像的技术,可以显著提升页面初始加载性能。
使用原生懒加载
现代浏览器支持原生的懒加载属性:
<img src="image.jpg" loading="lazy" alt="懒加载图像">
使用Intersection Observer API实现高级懒加载
// 自定义懒加载实现
function setupLazyLoading() {const images = document.querySelectorAll('.lazy-image');if ('IntersectionObserver' in window) {const imageObserver = new IntersectionObserver((entries) => {entries.forEach(entry => {if (entry.isIntersecting) {const image = entry.target;const src = image.dataset.src;const srcset = image.dataset.srcset;if (src) image.src = src;if (srcset) image.srcset = srcset;image.classList.remove('lazy-image');imageObserver.unobserve(image);}});});images.forEach(image => imageObserver.observe(image));} else {// 回退方案,使用滚动事件监听let lazyloadThrottleTimeout;function lazyload() {if (lazyloadThrottleTimeout) {clearTimeout(lazyloadThrottleTimeout);}lazyloadThrottleTimeout = setTimeout(() => {const scrollTop = window.pageYOffset;images.forEach(image => {if (image.offsetTop < window.innerHeight + scrollTop) {if (image.dataset.src) image.src = image.dataset.src;if (image.dataset.srcset) image.srcset = image.dataset.srcset;image.classList.remove('lazy-image');}});if (images.length === 0) {document.removeEventListener('scroll', lazyload);window.removeEventListener('resize', lazyload);window.removeEventListener('orientationChange', lazyload);}}, 20);}document.addEventListener('scroll', lazyload);window.addEventListener('resize', lazyload);window.addEventListener('orientationChange', lazyload);}
}document.addEventListener('DOMContentLoaded', setupLazyLoading);
渐进式加载与图像模糊预览
渐进式加载可以先显示低质量的图像,然后逐步加载高质量版本:
// 实现LQIP (Low Quality Image Placeholder)技术
function setupProgressiveImages() {const progressiveImages = document.querySelectorAll('.progressive-image-container');progressiveImages.forEach(container => {const thumbnail = container.querySelector('.thumbnail');const fullImage = new Image();fullImage.src = container.dataset.src;fullImage.className = 'full-image';fullImage.onload = () => {container.appendChild(fullImage);container.classList.add('image-loaded');};});
}
配合CSS实现平滑过渡:
.progressive-image-container {position: relative;overflow: hidden;
}.thumbnail {width: 100%;filter: blur(10px);transform: scale(1.05);transition: all 0.3s ease-in-out;
}.full-image {position: absolute;top: 0;left: 0;width: 100%;height: 100%;opacity: 0;transition: opacity 0.3s ease-in-out;
}.image-loaded .thumbnail {filter: blur(0);
}.image-loaded .full-image {opacity: 1;
}
响应式图像CDN与自适应服务
对于大型应用,可以使用专业的图像CDN服务自动优化图像:
<!-- 使用图像CDN (以Cloudinary为例) -->
<img src="https://res.cloudinary.com/demo/image/upload/w_auto,c_scale,f_auto,q_auto/sample.jpg" alt="CDN优化的响应式图像">
这种服务可以:
- 自动选择最佳格式 (
f_auto
) - 根据设备提供合适尺寸 (
w_auto
) - 优化压缩质量 (
q_auto
) - 应用智能裁剪 (
c_scale
)
响应式图像加载性能测试
以下是在不同场景下响应式图像技术的性能改进对比:
优化技术 | 页面图像总大小减少 | 首屏加载时间改善 | 内存占用减少 |
---|---|---|---|
使用srcset/sizes | 60-70% | 45-55% | 30-40% |
图像懒加载 | 40-60% | 30-40% | 50-60% |
渐进式加载 | 不显著 | 25-35% (感知) | 不显著 |
格式自适应 | 30-50% | 20-30% | 不显著 |
组合应用所有技术 | 70-85% | 60-75% | 55-70% |
真实案例:某电商网站应用上述技术后,首页加载时间从原来的4.2秒降至1.5秒,页面跳出率下降了18%,页面转化率提升了12%。
Canvas性能优化与渲染技巧
Canvas作为HTML5引入的强大绘图API,能够处理复杂的2D图形渲染,但在处理大量图形元素或高频率更新时,性能问题也随之而来。以下我们将探讨Canvas性能优化的关键技术和实战经验。
Canvas基础性能优化
1. 调整Canvas尺寸
Canvas的实际渲染尺寸(通过width和height属性设置)与显示尺寸(通过CSS设置)是分开的。当这两者不一致时,浏览器需要进行缩放,这会消耗额外的性能:
// 不推荐:通过CSS调整Canvas大小
canvas.style.width = '500px';
canvas.style.height = '300px';// 推荐:通过属性设置实际渲染尺寸
canvas.width = 500;
canvas.height = 300;// 在高分辨率屏幕上,可以考虑使用更高的渲染尺寸配合CSS缩放以提高清晰度
if (window.devicePixelRatio > 1) {const scale = window.devicePixelRatio;// 增加实际渲染尺寸canvas.width = 500 * scale;canvas.height = 300 * scale;// 使用CSS保持显示尺寸不变canvas.style.width = '500px';canvas.style.height = '300px';// 缩放绘图上下文以匹配const ctx = canvas.getContext('2d');ctx.scale(scale, scale);
}
2. 避免Canvas状态改变
每次改变绘图上下文的状态(如颜色、线宽、阴影等)都会产生一定的性能开销。可以通过最小化状态改变和批量处理相同状态的绘制操作来优化:
// 不推荐:频繁改变状态
function drawShapes(ctx) {for (let i = 0; i < shapes.length; i++) {ctx.fillStyle = shapes[i].color;ctx.fillRect(shapes[i].x, shapes[i].y, shapes[i].width, shapes[i].height);}
}// 推荐:按状态分组绘制
function drawShapesOptimized(ctx) {// 按颜色分组const shapesByColor = {};for (let i = 0; i < shapes.length; i++) {const color = shapes[i].color;if (!shapesByColor[color]) {shapesByColor[color] = [];}shapesByColor[color].push(shapes[i]);}// 每种颜色只设置一次fillStylefor (const color in shapesByColor) {ctx.fillStyle = color;for (const shape of shapesByColor[color]) {ctx.fillRect(shape.x, shape.y, shape.width, shape.height);}}
}
3. 使用多层Canvas分离更新频率不同的元素
当场景中包含静态和动态元素时,可以使用多个重叠的Canvas层,将不同更新频率的元素放在不同的层上:
<div class="canvas-container"><canvas id="background-layer" class="canvas-layer"></canvas><canvas id="middle-layer" class="canvas-layer"></canvas><canvas id="foreground-layer" class="canvas-layer"></canvas>
</div>
.canvas-container {position: relative;width: 800px;height: 600px;
}.canvas-layer {position: absolute;top: 0;left: 0;width: 100%;height: 100%;
}
// 初始化各层
const bgLayer = document.getElementById('background-layer');
const midLayer = document.getElementById('middle-layer');
const fgLayer = document.getElementById('foreground-layer');// 各层上下文
const bgCtx = bgLayer.getContext('2d');
const midCtx = midLayer.getContext('2d');
const fgCtx = fgLayer.getContext('2d');// 背景层(很少更新)
function drawBackground() {// 绘制复杂但静态的背景// ...
}// 中间层(偶尔更新)
function drawMiddleLayer() {// 绘制偶尔变化的元素// ...
}// 前景层(频繁更新)
function drawForeground() {// 清除前一帧fgCtx.clearRect(0, 0, fgLayer.width, fgLayer.height);// 绘制快速变化的元素// ...
}// 初始绘制
drawBackground();
drawMiddleLayer();// 动画循环只更新前景层
function animate() {drawForeground();requestAnimationFrame(animate);
}
animate();// 当需要时才更新中间层
function updateMiddleLayerWhenNeeded() {midCtx.clearRect(0, 0, midLayer.width, midLayer.height);drawMiddleLayer();
}
高级Canvas渲染优化
1. 离屏渲染与缓存
对于复杂但不经常变化的图形,可以先绘制到离屏Canvas,然后将结果作为图像绘制到主Canvas上:
// 创建离屏Canvas
const offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = 200;
offscreenCanvas.height = 200;
const offCtx = offscreenCanvas.getContext('2d');// 在离屏Canvas上绘制复杂图形(只需执行一次)
function drawComplexShape(ctx) {// 绘制复杂形状...ctx.beginPath();for (let i = 0; i < 1000; i++) {const angle = (i / 1000) * Math.PI * 2;const x = 100 + Math.cos(angle) * (50 + Math.sin(i/50) * 20);const y = 100 + Math.sin(angle) * (50 + Math.cos(i/50) * 20);if (i === 0) {ctx.moveTo(x, y);} else {ctx.lineTo(x, y);}}ctx.fillStyle = 'rgba(0, 128, 255, 0.5)';ctx.fill();ctx.strokeStyle = 'blue';ctx.lineWidth = 2;ctx.stroke();
}// 绘制到离屏Canvas
drawComplexShape(offCtx);// 主绘制循环中复用离屏Canvas内容
function mainRenderLoop() {const mainCtx = document.getElementById('main-canvas').getContext('2d');mainCtx.clearRect(0, 0, mainCanvas.width, mainCanvas.height);// 绘制多个复杂形状的实例(使用缓存的图像)for (let i = 0; i < 20; i++) {mainCtx.drawImage(offscreenCanvas, Math.random() * 600, Math.random() * 400);}requestAnimationFrame(mainRenderLoop);
}
2. 避免阴影和半透明
Canvas中的阴影和半透明操作是性能密集型的,可以通过预渲染或减少使用来优化:
// 不推荐:直接使用阴影
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.fillRect(50, 50
相关文章:
JavaScript性能优化实战(9):图像与媒体资源优化
引言 在当今视觉驱动的网络环境中,图像和媒体资源往往占据了网页总下载量的60%-80%,因此对图像和媒体资源进行有效优化已成为前端性能提升的关键领域。尽管网络带宽持续提升,但用户对加载速度的期望也在不断提高,特别是在移动设备和网络条件不稳定的场景下。 本文作为Jav…...
施磊老师rpc(四)
文章目录 rpc网络服务简介RpcProvider 的设计目标Eventloop不使用智能指针-弃用RpcProvider类似于集群的服务器provider网络实现**src/include/rpcprovider.h****src/include/mprpcapplication.h****src/rpcprovider.cc** 错误1错误2-重点**本项目的 mprpc 是动态库, muduo..是…...
Java学习手册:MyBatis 框架作用详解
一、MyBatis 简介 MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发。它通过将 Java 对象与数据库表之间的映射关系进行配置,使得开发者可以使用简单的 SQL 语句和 Java 代码来完成复杂的数据操作。MyBatis 支持自定义 SQL 语句,提供了灵…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】3.1 数据质量评估指标(完整性/一致性/准确性)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 数据质量评估核心指标:完整性、一致性、准确性实战解析3.1 数据质量评估指标体系3.1.1 完整性:数据是否存在缺失1.1.1 核心定义与业务影响1.1.2 检测…...
分布式系统中的 ActiveMQ:异步解耦与流量削峰(一)
一、引言 在当今数字化时代,分布式系统已成为构建大规模应用的关键架构。随着业务的快速发展和用户量的急剧增长,分布式系统面临着诸多挑战,其中异步通信、系统解耦和流量削峰是亟待解决的重要问题。 以电商系统为例,在秒杀活动中…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】2.5 事务与锁机制(ACID特性/事务控制语句)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 PostgreSQL 事务与锁机制深度解析:ACID 特性与事务控制全流程2.5 事务与锁机制2.5.1 ACID 特性与实现原理2.5.1.1 ACID 核心概念2.5.1.2 MVCC(多版本并发控制)与WAL(预写式日志)协同效应2.5.2 事务…...
STM32教程:ADC原理及程序(基于STM32F103C8T6最小系统板标准库开发)*详细教程*
前言: 本文章介绍了STM32微控制器的ADC外设,介绍了ADC的底层原理以及基本结构,介绍了ADC有关的标准库函数,以及如何编写代码实现ADC对电位器电压的读取。 可以根据基本结构图来编写代码 大体流程: 1、开启RCC时钟&am…...
RabbitMQ 深度解析:从核心组件到复杂应用场景
一.RabbitMQ简单介绍 消息队列作为分布式系统中不可或缺的组件,承担着解耦系统组件、保障数据可靠传输、提高系统吞吐量等重要职责。在众多消息队列产品中,RabbitMQ 凭借其可靠性和丰富的特性,在企业级应用中获得了广泛应用。本研究报告将全…...
linux 使用nginx部署ssl证书,将http升级为https
前言 本文基于:操作系统 CentOS Stream 8 使用工具:Xshell8、Xftp8 服务器基础环境: nginx - 请查看 linux 使用nginx部署vue、react项目 所需服务器基础环境,请根据提示进行下载、安装。 1.下载证书 以腾讯云为例ÿ…...
iview 分页改变每页条数时请求两次问题
问题 在iview page分页的时候,修改每页条数时,会发出两次请求。 iview 版本是4.0.0 原因 iview 的分页在调用on-page-size-change之前会调用on-Change。默认会先调用on-Change回到第一页,再调用on-page-size-change改变分页显示数量 此时就会…...
【Hive入门】Hive与Spark SQL深度集成:Metastore与Catalog兼容性全景解析
目录 引言 1 元数据管理体系架构对比 1.1 Hive Metastore架构解析 1.2 Spark Catalog系统设计 2 元数据兼容性深度剖析 2.1 元数据模型映射关系 2.2 元数据同步机制 3 生产环境配置指南 3.1 基础兼容性配置 3.1.1 Spark连接Hive Metastore 3.1.2 多引擎共享配置 3.…...
C#与西门子PLC通信:S7NetPlus和HslCommunication使用指南
西门子S7协议是用来和PLC进行通讯的一个协议,默认端口是102,数据会保存在一个个DB块中,比较经典的用法是一个DB块专门用来读取,一个用来写入。 DB(数据块) {块号}.DBX/DBD/DBW{字节地址}.{位偏移} 1、数据…...
湖北理元理律师事务所:法律科技融合下的债务管理实践
随着债务纠纷数量攀升,如何通过合法途径化解债务风险成为社会焦点。湖北理元理律师事务所作为国家司法局注册的债事服务机构,尝试以“法律技术”重构传统服务模式,为债务人提供系统性解决方案。 专业化服务架构 该律所设立客服、运营、法务…...
Spring Cloud Gateway MVC 基于 Spring Boot 3.4 以 WAR 包形式部署于外部 Tomcat 实战
一、引言 随着微服务架构的广泛应用,Spring Cloud Gateway 作为网关层的核心组件,为服务间的通信与流量管理提供了强大支持。spring-cloud-starter-gateway-mvc 则进一步助力开发者以熟悉的 MVC 模式进行网关开发。同时,将项目以 WAR 包形式…...
LLM论文笔记 27: Looped Transformers for Length Generalization
Arxiv日期:2024.9.25 关键词 长度泛化 transformer结构优化 核心结论 1. RASP-L限制transformer无法处理包含循环的任务的长度泛化 2. Loop Transformer显著提升了长度泛化能力 Input Injection 显著提升了模型的长度泛化性能,尤其在二进制加法等复杂…...
PCIe TLP | 报头 / 包格式 / 地址转换 / 寄存器 / 配置空间类型
注:本文为 “PCIe TLP” 相关文章合辑。 英文引文,机翻未校。 中文引文,未整理去重。 图片清晰度受引文原图所限。 略作重排,如有内容异常,请看原文。 PCIe - TLP Header, Packet Formats, Address Translation, Conf…...
《AI大模型应知应会100篇》第46篇:大模型推理优化技术:量化、剪枝与蒸馏
第46篇:大模型推理优化技术:量化、剪枝与蒸馏 📌 目标读者:人工智能初中级入门者 🧠 核心内容:量化、剪枝、蒸馏三大核心技术详解 实战代码演示 案例部署全流程 💻 实战平台:PyTor…...
C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 20)
🎁个人主页:工藤新一 🔍系列专栏:C面向对象(类和对象篇) 🌟心中的天空之城,终会照亮我前方的路 🎉欢迎大家点赞👍评论📝收藏⭐文章 文章目录 三…...
【Python生成器与迭代器】核心原理与实战应用
目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比二、实战演示环境配置要求核心代码实现案例1:自定义迭代器类案例2:生成器函数案例3:生成器表达式运行结果验证三、性能对比测试方法论量…...
2025年最新嵌入式开发STM32单片机详细教程(更新中)
ARM 处理器架构 ARM 处理器从 1984 ARM-1 发展到 2004 ARM-11 之后,放弃数字命名,用 cortex 来命令处理器产品。 Cortex-A系列 主打高性能 手机,平板,智能电视等 Cortex-R系列 主打实时 汽车,工业控…...
neatchat轻量级丝滑的ai模型web客户端
NeatChat 人工智能模型对话web客户端 前言 此项目是nextchat分支,相比原者更加简洁流畅。 部署 docker部署 name: next-chat services:chatgpt-next-web:ports:- 8080:3000environment:- OPENAI_API_KEYsk-xx543Ef3d- BASE_URLhttps://api.ai.com- GOOGLE_API_K…...
学习黑客分析案例
▶️ Day 2 任务 – 「怪物图鉴」实战 选一条最新安全事件(国内外均可,建议 1 年内) 例:CVE-2024-21887 Ivanti VPN RCE 用下列表格框架,3 句话归纳它的“派系”“CIA 受击点”“一句话原理”: 攻击流派…...
sonar-scanner在扫描JAVA项目时为什么需要感知.class文件
1 概述 SonarQube是一个静态代码分析工具,主要用于检查源代码的质量,包括代码重复、潜在漏洞、代码风格问题等。而SonarScanner是SonarQube的客户端工具,负责将代码进行形态分析,并将结果发送到SonarQube服务器。所以,…...
AtCoder Beginner Contest 404(ABCDE)
A - Not Found 翻译: 给您一个字符串S,长度在1 到25 之间,由小写英文字母组成。 输出S 中没有出现的一个小写英文字母。 如果有多个这样的字母,可以输出其中任何一个。 思路: 数组记录存在于 s 中的字母。(…...
【言语理解】中心理解题目之结构分析
front:中心理解题目之抓住关键信息 3.1 五种常见对策表达方式 3.1.1 祈使或建议给对策 应该(应) 需要(要) eg:……。对此,媒体要做好自我规约。……。 eg:……。然而,两地仅简单承接…...
DeepSeek-Prover-V2-671B:AI在数学定理证明领域的重大突破
文章目录 什么是DeepSeek-Prover-V2-671B?核心技术亮点1. **超大规模参数与高效推理**2. **超长上下文窗口**3. **强化学习与合成数据** 主要应用场景1. **教育领域**2. **科学研究**3. **工程设计**4. **金融分析** 开源与商业化性能表现总结 2025年4月30日&#x…...
React18组件通信与插槽
1、为DOM组件设置Props 在react中jsx中的标签属性被称为Props DOM组件的类属性,为了防止与js中的class属性冲突改成了className DOM组件的style属性 import image from "./logo.svg"; function App() {const imgStyleObj {width: 200,height: 200,};re…...
第15章 对API的身份验证和授权
第15章 对API的身份验证和授权 在构建RESTful API时,确保只有经过身份验证和授权的用户才能访问特定资源是至关重要的。身份验证是确认用户身份的过程,而授权则是决定用户是否有权访问特定资源的过程。在本章中,我们将详细探讨如何在ASP.NET Core Web API中实现身份验证和授…...
【项目归档】数据抓取+GenAI+数据分析
年后这两个月频繁组织架构变动,所以博客很久没更新。现在暂时算是尘埃落定,趁这段时间整理一下。 入职九个月,自己参与的项目有4个,负责前后端开发,测试,devops(全栈/doge)ÿ…...
如何优化MySQL主从复制的性能?
优化MySQL主从复制的性能需要从硬件、配置、架构设计和运维策略等多方面入手。以下是详细的优化方案: 一、减少主库写入压力 1. 主库优化 二进制日志(binlog)优化: 使用 binlog_formatROW 以获得更高效的复制和更少的数…...
asp.net客户管理系统批量客户信息上传系统客户跟单系统crm
# crm-150708 客户管理系统批量客户信息上传系统客户跟单系统 # 开发背景 本软件是给郑州某企业管理咨询公司开发的客户管理系统软件 # 功能 1、导入客户数据到系统 2、批量将不同的客户分配给不同的业务员跟进 3、可以对客户数据根据紧急程度标记不同的颜色,…...
PCIe | TLP | 报头 / 包格式 / 地址转换 / 配置空间 / 寄存器 / 配置类型
注:本文为 “PCIe - TLP” 相关文章合辑。 英文引文,机翻未校。 中文引文,未整理去重。 图片清晰度受引文原图所限。 略作重排,如有内容异常,请看原文。 PCIe - TLP Header, Packet Formats, Address Translation, Co…...
ip和域名
好的,我来依次回答你的问题: 域名和 IP 地址是什么关系? IP 地址 (Internet Protocol Address):可以想象成互联网上每台设备(比如服务器、电脑、手机)的门牌号码。它是一串数字(例如 IPv4 地址 …...
《解锁GCC版本升级:开启编程新世界大门》
《解锁GCC版本升级:开启编程新世界大门》 一、引言:GCC 版本升级的魔法钥匙 在编程的广阔天地里,GCC(GNU Compiler Collection)宛如一座灯塔,为无数开发者照亮前行的道路。它是一款开源且功能强大的编译器集合,支持 C、C++、Objective - C、Fortran、Ada 等多种编程语言…...
前端跨域问题怎么在后端解决
目录 简单的解决方法: 添加配置类: 为什么会跨域 1. 什么是源 2. URL结构 3. 同源不同源举🌰 同源例子 不同源例子 4. 浏览器为什么需要同源策略 5. 常规前端请求跨域 简单的解决方法: 添加配置类: packag…...
生成式 AI 的工作原理
在科技浪潮汹涌澎湃的当下,生成式 AI 宛如一颗璀璨的新星,照亮了我们探索未知的征程。它不再仅仅是科幻电影中的幻想,而是已经悄然融入我们生活的方方面面,从智能客服的贴心应答,到艺术创作的天马行空,生成式 AI 正以一种前所未有的姿态重塑着世界。然而,你是否曾好奇,…...
DeepSeek辅助学术写作之修订与校稿以及发表与推广相关提示词分享祝你顺利毕业~
目录 1.修订与校对 2.发表与推广 大家好这里是AIWritePaper官方账号,官网👉AIWritePaper~ 宝子们可以使用小编精选的“ChatGPT研究论文提示词”集合来创建研究论文。利用ChatGPT的智能回应生成详尽有效的内容,这样可以加快研究论文的策划、…...
叠层阻抗线框
1.阻抗介绍 特性阻抗:又称“特征阻抗”,它不是直流电阻,属于长线传输中的概念。在高频范围内,信号传输过程中,信号沿到达的地方,信号线和参考平面(电源或地平面)间由于电场的建立&am…...
大数据:驱动技术创新与产业转型的引擎
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 在全球数字化转型的浪潮中,大数据已经成为推动各行各业革新的核心力量。随着信息技术的迅猛发展,数据的收集、存储、处理和分析能力不断提升,大数据不仅改变了企业的运营模式,更引领了技术创新和产业结构…...
C++继承基础总结
引言 在编写多个类时,类之间可能会存在多个相同的成员变量,导致代码冗余度过高,C继承的出现,使得我们可以在已有类的基础上构建新类,从而实现代码复用与结构扩展。 一、继承的基本概念 继承是指子类(派生…...
2025年斯诺克世锦赛——“75三杰”在1/4决赛作为对手的概率
“在最近的斯诺克世锦赛中,中国两名球员成功挺进前8强。此外,前8强也出现令人感慨的一幕:75三杰全部进入到了八强,这也是历史第5次,50岁正是打拼的年纪!传奇之旅继续!”——摘自50岁正是打拼的年…...
Python绘制地球的重力地图
文章目录 Boule重力地图从ensaio下载重力数据Boule boule中定义了多种参考椭球,可用于表示地球、火星等星体的重力分布。可通过pip安装 pip install bouleboule中已经定义的椭球如下 椭球GRS80WGS84MARSMERCURYMOONVENUSVESTA星体地球地球火星水星月球金星灶神星这些椭球可直…...
多端定制系统开发:打造高效全平台覆盖的APP解决方案
在移动互联网时代,用户需求日益多样化,企业若想触达更广泛的受众,仅靠单一平台的应用已远远不够。无论是iOS、Android、Web端,还是智能手表、车载设备等新兴终端,多端适配已成为企业数字化转型的刚需。多端定制系统开发…...
WGDI-分析WGD及祖先核型演化的集成工具-文献精读126
WGDI: A user-friendly toolkit for evolutionary analyses of whole-genome duplications and ancestral karyotypes WGDI:一款面向全基因组重复事件与祖先核型演化分析的易用工具集 摘要 在地球上大多数主要生物类群中,人们已检测到全基因组复制&…...
旋转矩阵公式理解
这里给出其中一种理解方法: 设原始直角坐标系下的坐标为(x,y),我们可以将它分解为两个向量(x,0)和(0,y)。接下来将两个向量分别顺时针旋转θ度,二者就会分别变成:(xcosθ,xsinθ)和(-ysinθ,ycosθ)。 也就是说,二者…...
网络Tips20-002
1..某主机接口的IP地址为192.16.7.131/26.则该IP地址所在网络的广播地址是:192 16.7.191 广播地址是指在特定网络上发送广播消息的地址。它用于向网络上的所有设备发送信息。 方法1:广播地址掩码取反和网络地址的或运算 方法2:广播地址将网…...
firewall docker 冲突问题解决(亲测有效)
# 关闭iptables,使用firewall systemctl disable iptables # 禁用服务 systemctl stop iptables # 关闭服务 systemctl status iptables # 查看服务状态 systemctl enable firewalld # 设置防火墙开机自启动 systemctl start firewalld # 开启服务 systemctl s…...
SwiftUI-MLX本地大模型开发(二)
介绍 在 SwiftUI-MLX本地大模型开发一文中,我们已经详细讲了如何利用 MLX 进行本地大模型的开发。但是通过案例可以发现 2 个问题: MLX 内置的大模型数量有限。每次大模型都需要从 HuggingFace 下载。 如何解决这 2 个问题,方案是:…...
基于「骑手外卖系统」串联7大设计原则
你说得对!这些设计原则听起来都很抽象、很“玄”,如果不是实际开发过系统,很难理解“到底为什么要这样设计”。 那我现在就用一个你能想象得很清楚的真实例子,帮你把这7个设计原则一一落地到具体情境里,你会一眼明白。…...
泰迪杯特等奖案例学习资料:基于时空图卷积网络的城市排水系统水位精准重建与异常检测
(第十四届泰迪杯数据挖掘挑战赛A题特等奖案例解析) 一、案例背景与核心挑战 1.1 应用场景与行业痛点 城市排水系统(Urban Drainage Network, UDN)是城市基础设施的重要组成部分,其运行效率直接影响防洪排涝能力和水环境质量。然而,实际运维中面临以下难题: 监测数据稀…...