You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tauri应用中mousemove事件处理器卡顿问题求助

Tauri应用Canvas绘图卡顿问题解决

问题描述

我正在构建一个简易的Tauri应用,支持用户在上传的图片上绘图。通过mousemove事件记录鼠标指针的x、y坐标,并在canvas上绘制路径。该功能在浏览器中运行完全正常,但在Tauri中体验十分卡顿:路径开始绘制后会出现一段无绘制的延迟,数秒后路径才会显示。

核心的mousemove处理器代码如下:

window.addEventListener("mousemove", draw);
let drawing = false;

function startDrawing() {
    drawing = true;
}

function draw(e) {
    if (!drawing) return;
    console.log('DRAW After return');

    let { x, y } = getMousePos(canvas, e);
    context.lineTo(x, y);
    context.stroke();
}

解决方案

1. 用requestAnimationFrame批量绘制

Tauri的webview在处理高频mousemove事件时,同步绘制容易阻塞事件队列。将绘制逻辑放到requestAnimationFrame中,让webview在帧渲染周期内批量处理路径点,提升流畅度:

window.addEventListener("mousemove", draw);
let drawing = false;
let pendingPath = [];

function startDrawing() {
    drawing = true;
}

function draw(e) {
    if (!drawing) return;
    let { x, y } = getMousePos(canvas, e);
    pendingPath.push({ x, y });
}

function render() {
    if (pendingPath.length === 0) {
        requestAnimationFrame(render);
        return;
    }
    context.beginPath();
    const firstPoint = pendingPath.shift();
    context.moveTo(firstPoint.x, firstPoint.y);
    while (pendingPath.length > 0) {
        const point = pendingPath.shift();
        context.lineTo(point.x, point.y);
    }
    context.stroke();
    requestAnimationFrame(render);
}

requestAnimationFrame(render);

2. 对mousemove事件节流

高频触发的mousemove会产生大量绘制请求,通过节流函数限制事件处理频率,避免资源过载:

function throttle(func, limit) {
    let inThrottle;
    return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    }
}

// 用节流后的函数监听,间隔约16ms(对应60帧)
window.addEventListener("mousemove", throttle(draw, 16));

3. 启用硬件加速

在tauri.conf.json中确保webview启用硬件加速,利用GPU提升渲染性能:

{
  "tauri": {
    "windows": [
      {
        "webviewAttributes": {
          "hardwareAcceleration": true
        }
      }
    ]
  }
}

4. 移除冗余操作

删除draw函数中的console.log,高频日志输出会占用CPU资源,加重卡顿:

function draw(e) {
    if (!drawing) return;
    let { x, y } = getMousePos(canvas, e);
    context.lineTo(x, y);
    context.stroke();
}

内容的提问来源于stack exchange,提问作者dinika saxena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 05:36:21