解决批量绘制canvas卡顿的问题

小程序canvas画画板签字版,touchmove时卡顿的问题(根本原因是因为vue语法中page.data导致视图层和逻辑层的频繁通讯导致) 因为要做一个画画板的功能,所以使用了canvas组件,一开始好多人说小程序canvas性能特别差,也没太注意,做出来之后确实有点卡,而且每一笔touchmove时间越长越卡,最终导致页面卡到无法使用。 阅读详情
AI摘要

文章介绍了在Vue3项目中,利用Element-Plus构建的ImageGroup.vue组件,通过图片懒加载、本地缓存以及webworker子线程来提高图片加载速度和减少卡顿。虽然webworker效果一般,但懒加载和本地缓存对性能提升显著。,

前情提要:项目采用 vue3 + element-plus 的结构

需求:在背景图上画出红色矩形,圈出重点,格式类似下面

解决卡顿方法:

1.图片懒加载(很重要)

2.图片本地缓存(比较重要)

3.创建web worker子线程(效果不佳)

思路存在,开始写代码

1.创建每一组图片的 ImageGroup.vue

<template>
  <div>
    <div style="display: flex;">
      <div style="flex: 1;">
        <el-image
          style="width: 100%; height: 107px"
          :src="url1"
          :zoom-rate="1.2"
          :max-scale="7"
          :min-scale="0.2"
          :preview-src-list="srcList"
          :initial-index="0"
          fit="cover"
          lazy
          @load="onload"/>
        <div>标准图</div>
      </div>
      <div style="flex: 1;">
        <el-image
          style="width: 100%; height: 107px"
          :src="url2"
          :zoom-rate="1.2"
          :max-scale="7"
          :min-scale="0.2"
          :preview-src-list="srcList"
          :initial-index="1"
          fit="cover"
          lazy>
          <template #error>
            <div>加载中</div>
          </template>
        </el-image>
        <div>canvas图</div>
      </div>
    </div>
  </div>
</template>

js代码

<script setup>
import { ref, onMounted, computed } from 'vue'
import { useImageStore } from '@/stores/image' // 图片缓存

const imageStore = useImageStore()

const info = ref({}) // 每一组图片的信息,包含id,图片url,和矩形四个角在图片上的绘制位置等(这里是子组件,应该从父组件获取)

const url1 = ref('') // 标准图的url

const url2 = ref('') // canvas图的url

const srcList = computed(() => { // 图片预览列表
  return [url1.value, url2.value]
})

const bgUrl = ref('') // 图二的背景图

const pointList = ref([]) // 红框的点位信息

let worker // web worker子线程

const createWorker = () => { // 创建web worker子线程
  if (!worker) {
    worker = new Worker('/apple/worker/worker.js') // 这里的路径要注意,和我下面的图对照一下
  }
  return worker
}

// 1.首先加载标准图
onMounted(() => {
  let images = info.value.image
  url1.value = images[0].url
})

// 2.(el-image的加载事件调用,这里取个巧,用element的懒加载功能带动canvas的懒加载)标准图加载,用于懒加载实景图
function onload() {
  let images = info.value.image
  if(info.value.pointList) { // 有标记红框的图片,才需要画图(为了节省性能)
    pointList.value = info.value.pointList // 设置点位信息
    bgUrl.value = images[1].url // 设置背景图

    // 获取图片缓存,有缓存的直接显示,无缓存的则生成base64(为了节省性能)
    const img = imageStore.findImage(info.value.id)
    if(img) {
      url2.value = img.url
    } else {
      generateBase64()
    }
  } else { // 没有标记红框的图片,直接显示,不进行画图
    url2.value = images[1].url
  }
}
// 3.生成图片base64
const generateBase64 = async () => {
  const worker = createWorker() // 创建web worker子线程
  
  worker.onmessage = (event) => { // 接收子线程返回的base64数据
    if (event.data.type === "toDataURL") {
      url2.value = event.data.img
      // 缓存图片,主键为id
      imageStore.addImageList({id: info.value.id, url: event.data.img})
      worker.terminate() // 结束子线程
    }
  }
  worker.onerror = (error) => {
    console.log(error)
  }

  // 将canvas数据发送给Web Worker
  worker.postMessage({ type: 'toDataURL', pointList: JSON.stringify(pointList.value), bgUrl: bgUrl.value })
}
</script>

2.创建本地缓存,目的是尽量减少canvas绘画次数

import { ref } from 'vue'
import { defineStore } from 'pinia'

export const useImageStore = defineStore('image', () => {
  const imageList = ref([])

  function addImageList(image) {
    if(!imageList.value.filter((item) => item.id === image.id)[0]) 
    imageList.value.push(image)
  }

  function resetImageList() {
    imageList.value = []
  }

  function findImage(id) {
    return imageList.value.filter((item) => item.id === id)[0]
  }

  return {
    imageList,
    addImageList,
    resetImageList,
    findImage
  }
})

3.web woker代码(在这里用canvas比较麻烦)

 

onmessage = async function(event) {
  // 接收到消息时开始处理数据
  const { type, pointList, bgUrl } = event.data;
  const points = JSON.parse(pointList)
  // 获取背景图信息
  const response = await fetch(bgUrl) // 获取图片
  const blob = await response.blob() // 获取blob对象
  const image = await createImageBitmap(blob) // 创建一个ImageBitmap对象

  if (type !== 'toDataURL') return 
  const canvas = new OffscreenCanvas(100, 1) // 子线程中获取不到实体canvas,只能用OffscreenCanvas了
  const ctx = canvas.getContext('2d')
  canvas.width = image.width
  canvas.height = image.height
  ctx.drawImage(image, 0, 0)
  points.forEach(item => {
    const [x,y,w,h] = item[0]
    ctx.strokeStyle = "rgb(255, 0, 0)"
    ctx.lineWidth = 2
    ctx.strokeRect(Number(x), Number(y), Number(w), Number(h))
  })

  const bloba = await canvas.convertToBlob() // OffscreenCanvas没有转换base64的方法,只能先转换成blob

  // 然后创建一个文件读取器
  let reader = new FileReader()
  reader.onload = () => {
    let data = reader.result
    postMessage({ type, img: data })
  }

  // 读取blob对象为DataURL
  reader.readAsDataURL(bloba)
}

总结:懒加载是很有必要的,本地缓存效果也不错,web woker子线程只是提供了一种优化思路,但是效果聊胜于无,感兴趣的可以试一下。

高德地图海量点优化实战:用MassMarks解决1000+标点卡顿问题(附完整代码) 本文针对高德地图渲染海量点标记时出现的卡顿问题,提供了基于MassMarks的完整性能优化实战方案。通过对比传统Marker与MassMarks的渲染机制差异,详细阐述了如何利用Canvas批量渲染、数据组织、样式配置及事件交互,有效解决1000+标点导致的性能瓶颈,实现地图操作的丝滑体验。 阅读详情

相关推荐

Vue3 + Konva Canvas绘图实战:从零构建交互式数据可视化图表

本文详细介绍了如何使用Vue3和Konva从零构建交互式数据可视化图表。通过实战案例,展示了如何利用Vue3的响应式系统与Konva的高性能Canvas绘图能力,实现动态数据绑定、复杂交互功能(如拖拽排序)以及性能优化技巧。特别适合需要自定义图表开发的开发者学习。

weixin_29006701的博客 232

Canvas实现高性能网页雪景动画:从物理模拟到交互优化

前端动画是提升网页视觉体验和用户交互沉浸感的关键技术,其核心原理在于通过JavaScript控制DOM元素或Canvas绘图实现动态效果。在技术实现层面,Canvas 2D API因其高性能和灵活控制能力,成为实现复杂粒子系统的首选方案,尤其适合模拟自然现象如雨雪、火焰等。从技术价值看,优秀的动画不仅能增强页面表现力,还能通过交互反馈提升用户参与度,常见于节日活动页面、数据可视化、游戏等场景。本文聚焦于利用Canvas实现逼真的雪景动画,深入探讨雪花物理属性建模、动画循环优化以及鼠标交互等关键技术点,其中涉

weixin_34221073的博客 337

微信小程序Canvas卡顿优化解决方法

一、引入: 原安卓图书馆选座项目优快云博客链接: Android图书馆选座系统课程设计 最近在搞微信小程序,想把以前写的安卓图书馆选座项目的编辑地图移到小程序上去,但是发现小程序的canvas性能优化极差,导致编辑地图卡顿,如下: 我 可以明显的感觉,绘画黄色的线框很卡。 二、分析问题 我网上搜索相关解决方法,发现没有比较简单的可行方法,于是自己琢磨好久。 发现如果打开小程序开始界面是如上编辑地图的界面,绘制黄色框并不会很卡顿,而如果像我这个小程序本身要求要从显示当前地图界面,再跳转到编辑地图界面,绘制

qq_34060370的博客 7672

canvas 的动画卡顿问题(运行一段时间卡顿)

关于canvas动画越来越卡的问题

zimistan0997的博客 6789

华为快应用在setInterval中绘制canvas动画卡顿,怎么破

现象描述: 快应用中通过setinterval周期函数来循环触发canvas绘制代码,在华为手机上绘制的动画会很卡顿,不流畅。 问题代码如下: click0() { this.speed = 0.3 let ctx = this.$element('canvas').getContext('2d') setInterval(() => { this.num0 += 2 this.noise = Math.min(0.5, 1) * t

华为开发者联盟 2196

微信小程序Canvas卡顿?试试这个隐藏的销毁技巧,让你的绘制流畅如飞

本文深入剖析了微信小程序中Canvas组件在页面跳转后引发性能卡顿的根本原因,并提供了一个高效的主动销毁技巧。通过将Canvas宽高动态设置为0,并结合wx:if条件渲染,开发者可以精准触发底层资源回收,有效解决多个Canvas实例并存导致的渲染竞争与内存占用问题,从而显著提升绘制流畅度。

nept的博客 648

canvas画布网络慢时图片加载不出来解决方法

canvas 小程序 JavaScript

weixin_44758974的博客 2089

d3 canvas 绘制力导向图

d3 canvas 绘制力导向图 下面是分别使用svg和canvas绘制的效果图 svg绘制的效果图 canvas绘制的效果图 数据量小的时候,使用svg绘制是没什么问题的,但是一旦点和线的数据量一大,就会造成页面卡顿的情况,因此只能使用canvas又重新绘制了一遍,下面是参考了他人写的,进行改进,链接放在最下面了 html <div class="micro-topo-chart"> <canvas id="topo-canvas" class="topo-canvas" w

qq_32862143的博客 1825

【性能篇】29 # 怎么给Canvas绘制加速?

【跟月影学可视化】学习笔记。例子:实现一些位置随机的多边形,并且不断刷新这些图形的形状和位置 我们f12查看帧率,效果如下:Google Chrome浏览器怎么开启查看帧率功能?对于一个 500 边形来说,它的顶点数量非常多,所以 Canvas 需要执行的绘图指令也会非常多,那绘制很多个 500 边形自然会造成性能问题。下面减少绘制 500 边形的绘图指令的数量:用 -1 代替正 500 边形,如果type小于0表名多边形是正500边形,用 arc 指令来画圆 优化完之后的效果:具体做法就是将图形缓存下来,

学习前端这门手艺,栈底到栈顶依次是:浏览器架构、Web 网络、事件循环机制、JavaScript 核心、V8 的内存管理、浏览器的渲染流程、Web 安全、CSS、React、Vue、Node、构建工具链等 2142

字玩FontPlayer开发笔记3 性能优化 大量canvas渲染卡顿问题

在笔者的开源项目中,经常需要对大量canvas进行渲染,比如渲染字体预览列表,一个字库可能要包含上千上万个字符,这时候界面会卡住一段时间,体验非常不好。目前项目中主要采用了三个方法进行优化...

玩具工匠的博客 1763

WPF Canvas 高效渲染 DXF 图纸:组码解析、坐标变换与性能优化实战

在工控上位机与 CAD 辅助工具开发中,矢量图形渲染与坐标变换是核心技术。DXF 作为通用的二维矢量交换格式,其组码解析、世界坐标到屏幕坐标的映射以及 WPF Canvas 的高性能绘制,直接决定了图纸预览的流畅度与交互体验。通过手写解析器提取实体列表,结合 DrawingVisual 批量渲染与 MatrixTransform 实现缩放平移,可有效解决大图纸加载卡顿、线宽失真等问题。这些技术不仅适用于设备监控与图纸批注,也为轻量级 CAD 预览工具提供了工程实践参考。

weixin_32247165的博客 281

canvas绘图性能优化

canvas性能优化的几个点 测试的几个点: 1、遍历图像数据; 2、对比drawImage()与putImageData()的绘图效率; 3、使用drawImage()来绘制canvas,而非普通图像 4、在使用drawImage()绘图时缩放图像; 测试神器:http://jsperf.com/ 对比drawImage(HTMLIma...

weixin_34202952的博客 1478

C++实战:基于ONNX Runtime与OpenCV部署XFeat图像匹配模型

本文详细介绍了在C++环境中,利用ONNX Runtime与OpenCV高效部署XFeat图像匹配模型的完整流程。内容涵盖环境搭建、模型转换、核心代码封装及可视化实现,旨在帮助开发者将这一先进的深度学习模型集成到对性能要求苛刻的工业或嵌入式应用中,实现鲁棒且快速的特征匹配。

gpu4optimizer的博客 522

C++ Builder结合GDI+实现高效图片透明水印批量处理

图像处理是计算机图形学的基础应用,其核心原理之一便是Alpha混合技术,通过计算前景与背景像素的透明度值实现图像叠加。这项技术在工程实践中价值显著,能够为图片版权保护、品牌标识添加等场景提供自动化解决方案。借助GDI+这一Windows图形设备接口,开发者可以高效处理PNG等格式的Alpha通道,避免手动像素遍历,大幅提升处理性能。本文聚焦于使用C++ Builder这一RAD工具,结合GDI+库,详细讲解如何开发一个支持批量处理、自定义位置与透明度的本地化图片水印添加工具,涵盖从核心混合算法、多线程批量处

weixin_34128237的博客 525

从零到一:基于Esp32与LVGL的ST7789屏幕驱动全流程实战

本文详细介绍了基于Esp32与LVGL的ST7789屏幕驱动全流程实战,包括环境准备、驱动文件改造、硬件接口配置、LVGL集成与优化等关键步骤。通过VSCode+ESP-IDF开发环境,读者可以快速掌握SPI模式下的屏幕驱动开发,解决常见问题如颜色错乱、画面撕裂等,并实现LVGL的高效集成与性能优化。

weixin_33725722的博客 711

CodeBuddy 接入 MCP,一键生成网站!

2024 年 11 月,Anthropic 公司搞了个挺有意思的新玩意 - Model Context Protocol(模型上下文协议)简称为 MCP 协议。简单来说,它就是给 AI 和各类工具数据之间搭了个标准化的”桥梁”,让开发者不用再为对接问题头疼了。mcp.so如下图所示,这是 mcp.so 网站中的 MCP Server。使用百度/高德地图分析旅线计算时间接 Puppeteer 自动操作网页使用 Github/Gitlab 让大模型接管代码仓库。

悟空聊架构的专栏 1946

轻规划鸿蒙开发实战11:自研 Haptic Canvas 粒子系统,纯 ArkUI 高性能烟花渲染与性能避

情绪反馈是习惯养成的催化剂。本文将详细介绍如何不依赖任何外部 Web 引擎,基于鸿蒙 ArkUI 原生 Canvas 绘制组件,自研一套高性能的粒子渲染系统,并在打卡成功时渲染出物理级丝滑的漫天渐变烟花特效。

轻口味的专栏 1万+

从TL431光耦到集成隔离器:3种反激电源反馈方案全对比,你的项目到底该选哪个?

本文深入对比了反激电源设计中TL431光耦、集成隔离器和原边反馈三种主流反馈方案的优缺点,帮助开发者在电源设计中选择最适合的方案。从精度、成本、隔离等级等多维度分析,为反激式(Flyback)拓扑的应用提供实用选型指南。

weixin_30536513的博客 399

终极指南:如何用react-canvas彻底解决移动端Canvas渲染卡顿问题

在移动应用开发中,Canvas渲染性能一直是开发者面临的重大挑战。react-canvas作为一款专为React组件设计的高性能Canvas渲染库,通过创新的渲染策略和优化技术,有效解决了传统Canvas在移动端常见的卡顿问题。本文将详细介绍如何利用react-canvas结合PWA技术,构建流畅的移动应用体验。 ## 🚀 为什么选择react-canvas?核心优势解析 react-can

gitblog_00233的博客 1058

避坑指南:企业微信IP白名单设置失败的5种常见原因及解决方案

本文深入解析企业微信API调用中IP白名单设置失败的5种常见原因,包括动态公网IP变更、代理服务器导致的IP失真等,并提供针对性的解决方案。特别针对可信IP配置问题,详细介绍了诊断方法和Java代码示例,帮助企业开发者快速解决访问限制问题,确保API调用安全稳定。

weixin_29280657的博客 619

哨兵1号回波数据(L0级)FDBAQ压缩算法详解

本文介绍哨兵1号用的FDBAQ算法,它实现非整数可变bit压缩,大部分数据仅需 3bit输出,少数高反射率数据需4bit输出,使得平均输出比特率刚超过3bit,比熵约束分块自适应量化 (ECBAQ)压缩算法所需的3.7bit更低。也就是说FDBAQ压缩完,除了要记录分块尺寸和各块的均值码(对应哨兵1号数据包里的THIDX)外,还需要记录霍夫曼码字的长度(对应哨兵1号数据包里的BRC)。唯一不同的就是量化后的编码规则使用了霍夫曼编码,相当于在传统的BAQ压缩流程的后面又加了一个步骤。

2303

面试官:canvas绘制越画越卡怎么解决?

本文介绍了三种优化Canvas性能的核心方法:分层绘制将静态与动态内容分离,减少重复渲染;离屏Canvas提前缓存复杂元素,避免实时计算;按需绘制只在内容变化时触发重绘。通过组合使用这些技术,能显著降低CPU/GPU负载,在数据可视化、游戏等场景中实现流畅的60fps渲染。优化关键在于减少不必要的计算和渲染,根据实际需求灵活运用分层、缓存和智能重绘机制。

前端圈边缘选手,擅长把 UI 稿 “翻译” 成代码,也擅长在 console.log 里写 “求救信号”。日常状态:要么在调像素级对齐,要么在查 “为什么这个样式只在我电脑上生效”。博客不搞高深理论,只唠实在干货~ 1940

海洋CMS admin_notify.php 远程代码执行漏洞复现(CVE-2024-30565)

海洋CMS admin_notify.php 接口处存在远程代码执行漏洞,经过身份验证的远程攻击者可利用该漏洞执行任意代码,写入后门文件,进而控制整个web服务器。

0xSec 2714

鸿蒙API14开发【复杂绘制场景下使用Native Drawing自绘制能力替代Canvas提升性能】减少卡顿丢帧

[Canvas] 画布组件是用来显示自绘内容的组件,它具有保留历史绘制内容、增量绘制的特点。Canvas 有 [CanvasRenderingContext2D]/[OffscreenCanvasRenderingContext2D] 和 [DrawingRenderingContext] 两套API,应用使用两套API绘制的内容都可以在绑定的 Canvas 组件上显示。其中 CanvasRenderingContext2D 按照W3C标准封装了 [Native Drawing] 接口,可以方便快速复用w

bbq的博客 1142

【3D Slicer】的小白入门使用指南一

3D Slicer 是一个免费的开源软件平台,用于医学、生物医学和其他 3D 图像的可视化、处理、分割、配准和分析。Slicer 的功能包括:读/写。

图挖掘领域,新晋砖家 ☞ 未来可期,欢迎和静静一起学习交流吖 5555

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【swift】SwiftUI动画卡顿全解:GeometryReader滥用检测与Canvas绘制替代方案

SwiftUI动画卡顿全解:GeometryReader滥用检测与Canvas绘制替代方案。识别并消除不必要的GeometryReader;采用Canvas绘制替代方案;复杂场景使用Metal加速;可实现高达45%的帧率提升,同时降低CPU/GPU负载和内存占用。针对不同场景选择合适的技术方案,是保证SwiftUI动画流畅的关键。

夜雨的博客 1330

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: el-table中固定fixed列的错位问题
下一篇: 关于el-tooltip自适应显示
倾盆小雨
博客等级 码龄5年 24粉丝 9原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值