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

如何解决鼠标触发的图片动画在Firefox浏览器中运行卡顿的问题

问题描述

实现了鼠标操作触发的图片动画效果,功能基本开发完成,但在Firefox浏览器中动画运行非常卡顿。相关代码如下:

JavaScript 代码

jQuery(document).ready(function($) {
  $('.box_effect').hover(function(e) {
      $(document).on("click mousemove", ".box_effect", function(e) {
        var x = e.clientX;
        var y = e.clientY;
        if ($(this).hasClass("right")) {
          console.log($(this));
          var middleX1 = (x - $("#page").width() * 0.69) / 6;
          console.log('right');
        } else if ($(this).hasClass("left")) {
          console.log('left');
          var middleX1 = (x - $("#page").width() * 0.31) / 6;
        }
        var middleY1 = (y - $(window).height() * 0.4) / 8;
        var middleX2 = -middleX1 / 2;
        var middleY2 = (-middleY1) / 2;
        var image11 = $(this).find("img");
        image11.css({
          "-webkit-transform": "translate3d(" + middleX1 + "px," + middleY1 + "px,0px)",
          "-moz-transform": "translate3d(" + middleX1 + "px," + middleY1 + "px,0px)",
          "-ms-transform": "translate3d(" + middleX1 + "px," + middleY1 + "px,0px)",
          "-o-transform": "translate3d(" + middleX1 + "px," + middleY1 + "px,0px)",
          "transform": "translate3d(" + middleX1 + "px," + middleY1 + "px,0px)"
        });
        var image12 = $(this).find(".border");
        image12.css({
          "-webkit-transform": "translate3d(" + middleX2 + "px," + middleY2 + "px,0px)",
          "-moz-transform": "translate3d(" + middleX2 + "px," + middleY2 + "px,0px)",
          "-ms-transform": "translate3d(" + middleX2 + "px," + middleY2 + "px,0px)",
          "-o-transform": "translate3d(" + middleX2 + "px," + middleY2 + "px,0px)",
          "transform": "translate3d(" + middleX2 + "px," + middleY2 + "px,0px)"
        });
      });
    },
    function() {
      var image11 = $(this).find("img");
      var image12 = $(this).find(".border");
      image11.css({
        "-webkit-transform": "translate3d(" + 0 + "px," + 0 + "px,0px)",
        "-moz-transform": "translate3d(" + 0 + "px," + 0 + "px,0px)",
        "-ms-transform": "translate3d(" + 0 + "px," + 0 + "px,0px)",
        "-o-transform": "translate3d(" + 0 + "px," + 0 + "px,0px)",
        "transform": "translate3d(" + 0 + "px," + 0 + "px,0px)"
      });
      image12.css({
        "-webkit-transform": "translate3d(" + 0 + "px," + 0 + "px,0px)",
        "-moz-transform": "translate3d(" + 0 + "px," + 0 + "px,0px)",
        "-ms-transform": "translate3d(" + 0 + "px," + 0 + "px,0px)",
        "-o-transform": "translate3d(" + 0 + "px," + 0 + "px,0px)",
        "transform": "translate3d(" + 0 + "px," + 0 + "px,0px)"
      });
    }
  );
});

CSS 代码

body {
  margin: 0;
  display: block;
}
div {
  display: block;
}
.container {
  width: 75.3%;
  margin: auto;
}
.row {
  display: flex;
  justify-content: flex-end;
}
.row>div {
  width: 50%;
  padding: 6.484vw 3.984vw 4vw;
}
.box_effect {
  padding: 0 3.984vw;
  max-width: 450px;
  margin: auto;
  margin-bottom: 4vw;
}
.img_effect {
  position: relative;
  overflow: visible;
  margin-top: 2.187vw;
  z-index: -1;
}
.box_effect span.border {
  content: "";
  display: block;
  position: absolute;
  left: 1.093vw;
  top: -2.0832vw;
  width: 86.84%;
  height: 97.87%;
  border: 3px solid #91b508;
  box-sizing: border-box;
  z-index: 3;
  max-width: 380px;
}
.box_effect img {
  max-width: 380px;
  width: 100%;
}
.box_effect .img_effect img,
.box_effect .img_effect span {
  -webkit-transition: transform 5s cubic-bezier(0, 0.92, 0, 0.72)s;
  -moz-transition: transform 5s cubic-bezier(0, 0.92, 0, 0.72)s;
  -ms-transition: transform 5s cubic-bezier(0, 0.92, 0, 0.72)s;
  -o-transition: transform 5s cubic-bezier(0, 0.92, 0, 0.72)s;
  transition: transform 5s cubic-bezier(0, 0.92, 0, 0.72);
  -webkit-transform: translate3d(0px, 0px, 0px);
  -moz-transform: translate3d(0px, 0px, 0px);
  -o-transform: translate3d(0px, 0px, 0px);
  transform: translate3d(0px, 0px, 0px);
}

HTML 代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
  <div id="page" class="site">
    <div class="container">
      <div class="row one">
        <div class="text"></div>
        <div class="right box_effect">
          <div class="img_effect">
            <span class="border" style="transform: translate3d(0px, 0px, 0px);"></span>
            <img src="占位图片地址" alt="">
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- #page -->
</body>
修复方案

导致Firefox卡顿的核心原因及对应修复方案如下:

  • 修复重复事件绑定问题:原代码每次hover进入元素时都会给document新增一次click和mousemove事件监听,多次hover后会积累成百上千个重复监听器,高频触发的mousemove事件直接占满主线程。修改逻辑为hover进入时绑定事件,离开时移除对应事件,避免事件重复绑定。
  • 修复CSS语法错误:带前缀的transition属性末尾多写了多余的s单位,错误的CSS语法导致Firefox渲染引擎解析过渡规则异常,拉低动画性能。删除所有带前缀transition属性末尾多余的s即可。
  • 删除高频console.log输出:Firefox对控制台高频输出的性能处理弱于Chrome,mousemove每次触发都打印日志会占用大量计算资源,生产环境移除所有调试用的console.log语句。
  • 新增GPU加速配置:给动画元素加上will-change: transform属性,提前告知浏览器该元素会执行变换动画,浏览器会提前分配GPU资源处理渲染,大幅提升动画流畅度。

修复后核心代码

修复后JS代码

jQuery(document).ready(function($) {
  // 定义事件处理函数,方便后续解绑
  function handleMove(e) {
    const $target = $(e.currentTarget);
    const x = e.clientX;
    const y = e.clientY;
    let middleX1;
    if ($target.hasClass("right")) {
      middleX1 = (x - $("#page").width() * 0.69) / 6;
    } else if ($target.hasClass("left")) {
      middleX1 = (x - $("#page").width() * 0.31) / 6;
    }
    const middleY1 = (y - $(window).height() * 0.4) / 8;
    const middleX2 = -middleX1 / 2;
    const middleY2 = -middleY1 / 2;
    const $img = $target.find("img");
    const $border = $target.find(".border");
    // 现代浏览器无需加transform前缀,减少冗余代码
    $img.css("transform", `translate3d(${middleX1}px, ${middleY1}px, 0px)`);
    $border.css("transform", `translate3d(${middleX2}px, ${middleY2}px, 0px)`);
  }
  $('.box_effect').hover(function() {
    // hover进入时绑定事件
    $(document).on("mousemove", ".box_effect", handleMove);
  }, function() {
    // hover离开时解绑事件,同时重置位置
    $(document).off("mousemove", ".box_effect", handleMove);
    const $img = $(this).find("img");
    const $border = $(this).find(".border");
    $img.css("transform", "translate3d(0px, 0px, 0px)");
    $border.css("transform", "translate3d(0px, 0px, 0px)");
  });
});

修复后CSS代码(仅修改动画相关部分)

.box_effect .img_effect img,
.box_effect .img_effect span {
  /* 移除多余的s,新增will-change属性触发GPU加速 */
  -webkit-transition: transform 5s cubic-bezier(0, 0.92, 0, 0.72);
  -moz-transition: transform 5s cubic-bezier(0, 0.92, 0, 0.72);
  -ms-transition: transform 5s cubic-bezier(0, 0.92, 0, 0.72);
  -o-transition: transform 5s cubic-bezier(0, 0.92, 0, 0.72);
  transition: transform 5s cubic-bezier(0, 0.92, 0, 0.72);
  will-change: transform;
  transform: translate3d(0px, 0px, 0px);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 22:36:03