在火狐中反应性能问题?



我在开发的反应应用程序时遇到了一些性能问题。这些问题特别(或最明显地(发生在Firefox(FF开发者77.0b7和FF 76.0.1(上。

在 Firefox 中使用此应用程序时,CPU 使用率变得非常高,我的风扇开始以非常高的速度旋转。根据FF中的性能工具,我在Firefox中获得了大约15-19fps。我在Chrome和Safari中获得了大约60fps。

当我开始在输入字段中键入时,会出现这些问题,并且随着输入变长而变得更糟(这是有道理的(

该应用程序可在此处获得: https://text-to-aura-generator.netlify.app/

此处提供的源代码:https://github.com/paalwilliams/Text-to-Aura/tree/master/src

我几乎可以肯定这是我做错了,或者我编写的代码效率低下,但这不一定得到浏览器之间明显性能差异的支持。铬有那么好吗,处理反应/常量重新渲染?

我知道这是一个广泛的问题,但老实说,我不明白这里发生了什么,或者不一定知道如何在开发人员工具之外对其进行故障排除。任何意见或想法将不胜感激。

问题是您的应用程序渲染速度太快。在您的特定情况下,有几种方法可以改善这一点。

每次更新状态时,React 都需要重新渲染你的应用程序,因此在循环中更新状态通常是一个坏主意。

此外,您正在使用 3 次useState,但只有colors应该在那里,因为App实际上需要重新渲染以反映那里的更改。另外两个状态(texthex(仅用于将数据从handleChange传递到useEffect内部的回调。

您可以重构代码以:

  • 避免在循环中更新状态。

  • 使用简单变量而不是状态。

  • 使用useCallback定义一个具有该逻辑的函数,该逻辑不会在每次渲染时重新创建,因为这也会强制TextInput重新渲染。

  • 使用如下所示的内容限制此回调:

    import { useCallback, useEffect, useRef } from 'react';
    export function useThrottledCallback<A extends any[]>(
    callback: (...args: A) => void,
    delay: number,
    deps?: readonly any[],
    ): (...args: A) => void {
    const timeoutRef = useRef<number>();
    const callbackRef = useRef(callback);
    const lastCalledRef = useRef(0);
    // Remember the latest callback:
    //
    // Without this, if you change the callback, when setTimeout kicks in, it
    // will still call your old callback.
    //
    // If you add `callback` to useCallback's deps, it will also update, but it
    // might be called twice if the timeout had already been set.
    useEffect(() => {
    callbackRef.current = callback;
    }, [callback]);
    // Clear timeout if the components is unmounted or the delay changes:
    useEffect(() => window.clearTimeout(timeoutRef.current), [delay]);
    return useCallback((...args: A) => {
    // Clear previous timer:
    window.clearTimeout(timeoutRef.current);
    function invoke() {
    callbackRef.current(...args);
    lastCalledRef.current = Date.now();
    }
    // Calculate elapsed time:
    const elapsed = Date.now() - lastCalledRef.current;
    if (elapsed >= delay) {
    // If already waited enough, call callback:
    invoke();
    } else {
    // Otherwise, we need to wait a bit more:
    timeoutRef.current = window.setTimeout(invoke, delay - elapsed);
    }
    }, deps);
    }
    

如果使用useEffect的原因是您在更新colors时没有看到正确的值,请尝试使用接受回调而不是新值的setState版本,而不是:

setColors([...colors, newColor]);

您将拥有:

setColors(prevColors => ([...prevColors , newColor]));

react 最常见的性能问题来自设置状态的次数过多,因为您不断重新渲染页面及其中的元素。

最新更新