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

setInterval设为50ms却以约1500ms执行,求技术解决方案

问题分析与解决方案

你的定时器间隔异常、动画不流畅的问题,主要是由几个代码逻辑和性能问题导致的,咱们一步步拆解并修复:

核心问题根源

  • 定时器堆积阻塞主线程:在gamerule函数中,每次width < 1时都会新建一个setInterval(ser, 1000),但从未清理旧的定时器。随着运行次数增加,大量重复定时器会抢占主线程资源,直接导致setInterval(gamerule, 50)无法按时执行。
  • 重复定义函数导致逻辑混乱:你在点击事件和gamefunc里各定义了一次res函数,后面的定义会覆盖前面的,这会让旋转复位逻辑执行混乱,间接拖慢整体代码节奏。
  • 状态变量未更新:rotated变量初始设为false后从未修改,所有旋转操作都固定为22度,既达不到晃动效果,还会造成不必要的重绘开销。
  • 频繁DOM操作触发重排:短时间内反复修改元素的尺寸和旋转属性,会让浏览器频繁重排重绘,进一步阻塞主线程,拉长定时器的实际执行间隔。

修复后的优化代码

我针对上述问题做了针对性调整,同时优化了代码结构和性能:

// 统一初始化变量,用let/const提升可读性
let rotated = false;
let height = 24.6;
let width = 15;
let points = 0;
const cutvalw = 1;
const cutvalh = 1.64;
let val = 10;
let serTimer = null; // 存储定时器实例,方便后续清理

// 缓存DOM元素,避免重复查询DOM
const boxEl = document.querySelector("#box");
const contEl = document.getElementById("cont");

// 统一的旋转复位函数,避免重复定义
function resetRotation() {
  // 现代浏览器只需标准transform属性,无需写多前缀
  boxEl.style.transform = "rotate(0deg)";
}

// 点击事件处理逻辑
boxEl.addEventListener("click", function () {
  width -= cutvalw;
  height -= cutvalh;
  
  // 切换旋转状态,实现真正的晃动切换
  rotated = !rotated;
  const deg = rotated ? 22 : 0;
  boxEl.style.transform = `rotate(${deg}deg)`;
  
  setTimeout(resetRotation, 140);
});

// 游戏规则核心逻辑
function gamerule() {
  boxEl.style.width = `${width}%`;
  boxEl.style.height = `${height}%`;

  if (width < 1) {
    // 重置尺寸
    width = 15;
    height = 24.6;
    contEl.style.pointerEvents = "none";
    
    // 先清理旧定时器,避免堆积
    if (serTimer) clearInterval(serTimer);
    serTimer = setInterval(() => {
      contEl.style.pointerEvents = "all";
      // 执行后立即清理定时器,防止重复触发
      clearInterval(serTimer);
      serTimer = null;
    }, 1000);
    
    points++;
  }
}

// 自动晃动逻辑
function gamefunc() {
  if (val >= 10) {
    width -= 0.5;
    height -= 0.5;
    
    rotated = !rotated;
    const deg = rotated ? 22 : 0;
    boxEl.style.transform = `rotate(${deg}deg)`;
    
    setTimeout(resetRotation, 140);
    
    val = 9;
    setTimeout(() => {
      val = 10;
    }, 1000);
  }
}

// 启动定时器
setInterval(gamerule, 50);
setInterval(gamefunc, 500);

关键优化点说明

  • 缓存DOM元素:避免每次函数执行都重复查询DOM,减少性能开销。
  • 合并重复函数:将两个res函数合并为resetRotation,彻底解决函数覆盖问题。
  • 定时器生命周期管理:创建新定时器前先清理旧的,执行完成后及时销毁,避免定时器堆积。
  • 修复状态变量:在点击和自动晃动时切换rotated值,实现真正的晃动效果。
  • 简化CSS属性:去掉冗余的浏览器前缀,现代浏览器已支持标准transform属性。
  • 避免嵌套函数:把嵌套的函数改为箭头函数,减少作用域混乱问题。

这些调整应该能解决你定时器间隔异常的问题,让动画恢复流畅。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:11:54