Можно ли присоединить много слушателей событий? - PullRequest
0 голосов
/ 02 февраля 2019

Предположим, у меня есть какой-то компонент, который представляет собой некое умное изображение (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>
        )
    }
}

Давайте не будем вдаваться в подробности о высоте оболочки, когда изображениене рендеринг или что-то (предположим, что я уже обработал это, это всего лишь пример оптимизации производительности DOM).

Итак, главная цель, очевидно, состоит в том, чтобы создать какой-то список исполнителей изображений.Вы, наверное, знаете, что когда изображений много (особенно если они не оптимизированы - большие изображения, PNG с большим количеством прозрачных пикселей и т. Д.), Страница начинает лагать.

Так чтоИдея состоит в том, чтобы дать каждому визуализированному SmartImage знать, находится ли он внутри области просмотра или нет.Для этого я присоединяю слушателя для window.onscroll и динамически определяю, находится ли ограничивающая рамка SmartImage в области просмотра, и, если необходимо, переключаю видимость изображения.Я могу использовать условный рендер или { display: "none" } во встроенном стиле, я знаю, но это не главный вопрос.

Основной вопрос: если у меня будет много этих SmartImage компонентовБудет ли лучше подключить только один прослушиватель событий и следить за изменениями в списке SmartImage s, или можно подключить много отдельных прослушивателей для каждого компонента SmartImage?Что является более производительным?

AFAIK, addEventListener не добавляет дополнительного прослушивателя для каждого подобного события, но вместо этого создает список обработчиков и выполняет его один за другим.Это правда?

Вопрос более метафизический, я полагаю, но если кто-то имел опыт работы с подобными ситуациями, пожалуйста, мне будет приятно, если вы дадите мне несколько советов или объяснений.

Ценю любую помощь или информацию!Заранее спасибо!

1 Ответ

0 голосов
/ 02 февраля 2019

Для большинства событий, таких как события клавиатуры или мыши, добавление одного слушателя на элемент обычно не является большой проблемой.

Такие события, как scroll и resize, однако запускаются при каждом изменении пикселя, что заставляет их срабатывать много разраз в секунду в зависимости от скорости изменения

Так что, если у вас было несколько сотен элементов, каждый из которых запускает обработчики событий много раз в секунду при быстром движении, это может замедлить работу, чтобы повлиять на работу пользователя.

Одним из способов повышения производительности является использование методов, известных как «throttling» или «debouncing» (легко исследуемый), которые запускают код в обработчике только тогда, когда он не был вызван внутрипоследние n миллисекунды

Использование компонента более высокого порядка, который добавляет только одного слушателя для мониторинга всех подобных объектов, вероятно, является лучшим подходом, и даже простое использование может потребовать некоторого регулирования

...