可以附加很多事件侦听器吗?

时间:2019-02-02 18:44:51

标签: javascript reactjs performance dom addeventlistener

假设我有一些组件,代表某种智能图像(IUKWIM:D)。

export default class SmartImage extends React.Component {
    state = {
        visible: false
    }

    wrapper: HTMLDivElement

    componentDidMount() {
        window.addEventListener("scroll", this.handleScroll)
        this.handleScroll()
    }

    componentWillUnmount() {
        window.removeEventListener("scroll", this.handleScroll)
    }

    handleScroll = (event?: UIEvent) => {
        var box = this.wrapper.getBoundingClientRect()
        if (box.bottom < 0 || box.top > window.innerHeight) {
            if (this.state.visible)
                this.setState({ visible: false })
        } else {
            if (!this.state.visible)
                this.setState({ visible: true })
        }
    }

    render() {
        return (
            <div className="c-image-wrapper" ref={r => this.wrapper = r}>
                {this.state.visible &&
                    <img src="someSource" className="u-fade-in" />
                }
            </div>
        )
    }
}

让我们成为absctract关于包装的高度细节的图像时不会呈现什么(假设我已经处理了,这仅仅是的DOM性能优化的示例)。

因此,显然,主要目标是制作某种性能列表。你可能知道,当有大量的图像。(特别是如果他们没有进行优化 - 大图像,PNG有很多透明的像素等),然后页面开始滞后

因此,其想法是让每个渲染的SmartImage都知道它是否在视口内。为此,我附加该侦听器为window.onscroll,并动态地检测,如果该边界框的SmartImage是在视口,如果有必要,切换的图像的可见性。我知道我可以使用条件渲染或以内联样式使用{ display: "none" },但这不是主要问题。

主要问题是:如果我将拥有许多这些SmartImage组件,最好附上唯一的事件侦听器并监视SmartImage列表的更改,或者是否可以为每个SmartImage组件附加很多单个侦听器?表现更好的是什么?

AFAIK,addEventListener不会为每个类似事件添加额外的侦听器,而是创建处理程序列表并逐一执行。是真的吗?

我想问题是形而上的,但是,如果有人有这种情况的经验,请给我一些建议或解释,对我来说是很好的。

感谢任何帮助或信息! 预先谢谢你!

1 个答案:

答案 0 :(得分:4)

有关大多数事件,如键盘或鼠标事件每个项目添加一个监听器通常不是一个大问题。

scrollresize之类的事件会因每次像素变化而触发,这使它们每秒根据变化率触发多次

因此,如果您有数百个项目都以每秒快速触发多次多次触发事件处理程序,那么它可能会陷入停顿,从而影响用户体验。

,以提高性能的一种方式是使用被称为技术的“节流” “去抖动” (容易研究),只有处理程序中运行的代码,当它不是招”在过去n毫秒内被调用

使用仅添加一个侦听器来监视所有类似对象的高阶组件可能是一种更好的方法,即使仅使用一个侦听器也可能需要进行一些限制