卸下我打开的每个浏览器的加载屏幕

2026年8月20日1 次浏览来源:Dev.to阅读原文

这是DEV的"夏天的臭虫"(Summer Bug Smash: Smash Stories)的呈文,由哨兵提供动力.

有一种特定的错误 让你怀疑你是否知道 如何编码。

不是那种东西 抛出一个明显的错误, 你追踪回来 在两分钟。

整个浏览器窗口开始闪出黑色的种类,唯一选择是在克罗姆完全锁定之前杀死标签.

那是我组合中装入屏幕错误。

我刚刚将个人投资组合迁移到Next.js 16, 该网站在根版式上安装了自定义的加载屏幕.

它需要在那里,因为它是用户在任何内容加载之前所看到的第一件事.

装载器不是简单的旋转器.

它绘制出一个SVG路径,用中风动画来追踪我最初的字母G,将它移到左边,同时显示我的全名,然后在调用回调和卸载之前分两个阶段执行彩色擦出动画.

有针对直接 DOM 操纵 SVG 元件的回历, 擦拭相的状态变量, 定时器, 以及整个擦拭相层的过渡逻辑 。

标准的东西。

还是我想的一样 发生了什么事 当我打开dev服务器时,浏览器窗口开始闪烁.

不是个微妙的闪烁。

整个取景口全速地在黑色和内容之间交替,上下相接,没有收分卡就无法阻止.

几秒钟之内,克罗姆就会在控制台上投出错误和警告并开始明显地减速.

如果我让它运行,浏览器最终会完全饱和.

同样的事情发生在生产。

页面是黑色的。

该循环执行得如此快,内容从未有时间显出.

任何访问网站的人都会看到黑幕,而别无他法。

每次我打开本地服务器,我都要杀死它 才能在项目中做其他事情 为什么要花时间去寻找 症状如此极端,以至于指向了错误的方向。

当浏览器有这样的行为时,本能就是寻找一些主要的东西:内存出漏,建设配置被打碎,依赖冲突.

我花时间检查了所有这些 却什么都没发现。

我读完后,这个构件本身看起来很合理 有状态,有裁判, 有定时逻辑。

代码里没有明显的循环 最终导致我找到实际原因的是两件事的结合.

我在DEV上发现了描述类似症状的文章, 之后我打开了DevTools的回放,看看运行时实际发生的情况.

控制台显示: 这一错误,加上在DevTools组件树上连续地观看组件重挂,使得原因变得清晰.

问题在于控制加载器行为的状态更新在渲染过程中运行,超出任何效果.

在一个具有如此多的定时和过渡逻辑的组件中,这很容易发生意外.

每次渲染都引发了状态变化,这又引发了另一个渲染,从而引发了另一个状态变化.

浏览器正重新将整个根版式每秒上百回送出,这就是为什么取景口被闪出,最终将所有东西都锁上.

该组件的复杂性使得在读取时更难捕捉到,因为定时逻辑造成了状态更新是有条件和有时间限制的印象.

他们没有。

正在对每一处情况进行评估。

解决方法是两件事一起应用的 首先,将SVG动画逻辑和擦拭出局逻辑分开,分为两个截然不同的钩子,每个钩子都有明显的清理.

SVG动画上架后运行一次.

擦拭计时器以单独的效果运行,可以清理出所有三个停放在倒挂上.

第二,我将装载器移入它自己孤立的部件中,而不是将其固定在根部布局中.

分离使得寿命周期提前

分享