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

Deno Fresh应用Island加载缓慢及交互异常问题求助

Deno Fresh应用问题修复方案

问题1:无缓存环境下首次点击About按钮无响应

原因分析

  • Navigation组件的useEffect未设置依赖数组,导致组件每次渲染都会重复绑定/解绑scroll事件,引发状态不稳定,干扰导航链接的事件绑定。
  • 若Links组件使用原生<a>标签而非Fresh的客户端路由<Link>组件,首次加载时可能因组件未完成hydration,导致点击事件无法触发。

修复步骤

  1. 给Navigation的useEffect添加空依赖数组,确保scroll事件只绑定一次:
useEffect(() => {
  const handleScroll = () => {
    const position = globalThis.window.scrollY;
    const threshold = 300;

    if (position > threshold && position < prevPosition.current) {
      isHidden.value = false;
    } else if (position > threshold) {
      isHidden.value = true;
    } else {
      isHidden.value = false;
    }

    prevPosition.current = position;
  };

  self.window.addEventListener("scroll", handleScroll);

  return () => {
    self.window.removeEventListener("scroll", handleScroll);
  };
}, []); // 添加空依赖数组
  1. 确认Links组件使用Fresh官方的<Link>组件:
import { Link } from "$fresh/runtime.ts";

// 替换原有<a>标签为<Link>
<Link href="/about">About</Link>

问题2:安卓手机滚动到About区域时动画卡顿

原因分析

  • Skills组件中使用大量嵌套setTimeout频繁更新signal,触发组件多次重渲染,占用移动端有限的主线程资源。
  • 基于color属性的过渡动画会触发浏览器重绘,无法利用GPU加速,导致卡顿。
  • IntersectionObserver回调在元素进入视口时一次性执行大量定时器任务,造成任务队列阻塞。

修复步骤

  1. 优化定时器逻辑,用requestAnimationFrame替代setTimeout,减少主线程阻塞:
useEffect(() => {
  const observer = new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting && !animationPlayed.value) {
      let step = 0;
      const totalSkills = skills.length;
      
      const animate = () => {
        if (step < totalSkills) {
          active.value = skills[step].name;
          step++;
          requestAnimationFrame(() => setTimeout(animate, 140));
        } else {
          setTimeout(() => {
            active.value = null;
            setTimeout(() => {
              flashIcons.value = true;
              setTimeout(() => {
                flashIcons.value = false;
                active.value = skills[0].name;
                animationPlayed.value = true;
              }, 300);
            }, 300);
          }, 110);
        }
      };
      
      animate();
      observer.disconnect();
    }
  }, { rootMargin: "0px 0px -50px 0px" }); // 提前50px触发动画,避免卡顿

  const skillsElement = document.getElementById("skills");
  if (skillsElement) observer.observe(skillsElement);

  return () => observer.disconnect();
}, []);
  1. 修改动画属性,利用GPU加速:
    把图标颜色过渡替换为transform: scale配合颜色变化,添加will-change提示浏览器优化:
<Icon
  class={`
    cursor-pointer transition-all duration-300 ease-in-out will-change:transform,color
    hover:scale-110 hover:text-blue-600 dark:hover:text-neutral-300
    ${active.value === name ? "scale-110 text-blue-600 dark:text-neutral-300" : ""}
  `}
  onClick={() => (active.value = name)}
/>
  1. 用CSS关键帧动画替代JS控制的闪烁效果:
    在全局样式中添加:
@keyframes iconFlash {
  0% { color: theme('colors.neutral.600'); }
  50% { color: theme('colors.blue.600'); }
  100% { color: theme('colors.neutral.600'); }
}

.dark @keyframes iconFlash {
  0% { color: theme('colors.neutral.600'); }
  50% { color: theme('colors.neutral.300'); }
  100% { color: theme('colors.neutral.600'); }
}

.flash-icons {
  animation: iconFlash 0.6s ease-in-out;
}

然后修改Skills组件的section:

<section
  id="skills"
  class={`
    grid place-items-center gap-y-8 text-neutral-600
    ${flashIcons.value ? "flash-icons" : ""}
  `}
>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 04:57:33