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

手动可调整大小的弹出窗口性能不佳问题求助

手动调整侧边栏大小的性能优化方案

核心优化点及代码修改

1. 移除拖动时的CSS过渡动画

.sidenav的transition属性会在拖动过程中触发平滑过渡,导致视觉上的延迟感。我们可以在拖动时临时禁用过渡,结束后再恢复:

CSS修改:

.sidenav {
  /* 保留原有属性,新增以下配置 */
  will-change: width; /* 提示浏览器提前优化width变化的渲染逻辑 */
}

.sidenav.resizing {
  transition: none !important; /* 拖动时强制禁用过渡 */
}

body.resizing {
  user-select: none; /* 拖动时禁止页面文本被选中,避免干扰操作 */
}

JavaScript关联修改:
在拖动开始/结束时,给对应元素添加/移除resizing类:

// 拖动开始
resizeButtonEl.addEventListener('mousedown', function(event) {
  // ... 原有代码
  sidenavEl.classList.add('resizing');
  bodyEl.classList.add('resizing');
});

// 拖动结束
function stopResizing() {
  // ... 原有代码
  sidenavEl.classList.remove('resizing');
  bodyEl.classList.remove('resizing');
}

2. 缓存DOM元素,减少重复查询

避免每次操作都重复调用getElementById,提前缓存常用DOM元素,降低DOM查询开销:

// 全局缓存常用元素
const sidenavEl = document.getElementById("mySidenav");
const resizeButtonEl = document.getElementById("resizeButton");
const overlayEl = document.getElementById("overlay");
const bodyEl = document.body;

// 后续代码直接使用缓存变量,例如:
function openNav() {
  sidenavEl.style.width = "500px";
  overlayEl.style.display = "block";
  bodyEl.style.backgroundColor = "rgba(0,0,0,0.1)";
}

3. 用requestAnimationFrame优化重绘时机

直接在mousemove回调中修改样式会频繁触发浏览器重排,使用requestAnimationFrame将样式修改放到浏览器的重绘周期内执行,减少不必要的渲染开销:

function resize(event) {
  if (isResizing) {
    const newWidth = startWidth - (event.clientX - startX);
    if (newWidth > 100) {
      requestAnimationFrame(() => {
        sidenavEl.style.width = `${newWidth}px`;
      });
    }
  }
}

4. 完善事件监听与边界处理

添加mouseleave事件监听,防止鼠标移出浏览器窗口后无法停止拖动;同时在mousedown时阻止默认行为,避免选中文本等干扰操作:

function stopResizing() {
  if (isResizing) {
    isResizing = false;
    sidenavEl.classList.remove('resizing');
    bodyEl.classList.remove('resizing');
    resizeButtonEl.style.cursor = "grab";
    // 清理所有相关事件监听
    document.removeEventListener('mousemove', resize);
    document.removeEventListener('mouseup', stopResizing);
    document.removeEventListener('mouseleave', stopResizing);
  }
}

// 绑定停止拖动的事件
document.addEventListener('mouseup', stopResizing);
document.addEventListener('mouseleave', stopResizing);

// mousedown时阻止默认行为
resizeButtonEl.addEventListener('mousedown', function(event) {
  event.preventDefault(); // 阻止文本选择等默认行为
  // ... 原有初始化逻辑
});

完整优化后的JavaScript示例

const sidenavEl = document.getElementById("mySidenav");
const resizeButtonEl = document.getElementById("resizeButton");
const overlayEl = document.getElementById("overlay");
const bodyEl = document.body;

let isResizing = false;
let startX = 0;
let startWidth = 0;

function openNav() {
  sidenavEl.style.width = "500px";
  overlayEl.style.display = "block";
  bodyEl.style.backgroundColor = "rgba(0,0,0,0.1)";
}

function closeNav() {
  sidenavEl.style.width = "0";
  overlayEl.style.display = "none";
  bodyEl.style.backgroundColor = "white";
}

function resize(event) {
  if (isResizing) {
    const newWidth = startWidth - (event.clientX - startX);
    if (newWidth > 100) {
      requestAnimationFrame(() => {
        sidenavEl.style.width = `${newWidth}px`;
      });
    }
  }
}

function stopResizing() {
  if (isResizing) {
    isResizing = false;
    sidenavEl.classList.remove('resizing');
    bodyEl.classList.remove('resizing');
    resizeButtonEl.style.cursor = "grab";
    document.removeEventListener('mousemove', resize);
    document.removeEventListener('mouseup', stopResizing);
    document.removeEventListener('mouseleave', stopResizing);
  }
}

resizeButtonEl.addEventListener('mousedown', function(event) {
  event.preventDefault();
  isResizing = true;
  startX = event.clientX;
  startWidth = parseFloat(getComputedStyle(sidenavEl).width);
  
  sidenavEl.classList.add('resizing');
  bodyEl.classList.add('resizing');
  resizeButtonEl.style.cursor = "grabbing";
  
  document.addEventListener('mousemove', resize);
  document.addEventListener('mouseup', stopResizing);
  document.addEventListener('mouseleave', stopResizing);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 11:45:53