Профилирование производительности React в Chrome

Я занимаюсь профилированием производительности с помощью инструментов разработчика Chrome в приложении SPA React (15.6), которое использует ag-grid-react, и у меня возникли небольшие проблемы с согласованием вывода профилировщика с реальностью. Например, на снимке экрана ниже видно, что метод «componentWillReceiveProps» компонента подключенного ящика (Connect(Drawer), оранжевая полоса) занимает ~2 секунды, но под этим ничего нет. После просмотра кода я скептически отнесся к тому, что сам метод может занять так много времени, поэтому я добавил несколько операторов console.time вокруг всего кода внутри функции, и вот:

Компонент ящикаWillReceiveProps: 0,02001953125 мс

Вот как выглядит мой componentWillReceiveProps для справки:

componentWillReceiveProps(nextProps) {
        console.time('Drawer componentWillReceiveProps');
        if (nextProps.changes.length !== this.props.changes.length &&
            nextProps.changes.length === 0 &&
            this.state.isDiscarding) {
            this.setState({isDiscarding: false});
        }
        console.timeEnd('Drawer componentWillReceiveProps');
    }

Итак, что мне здесь не хватает? Я (своего рода) понимаю, что API синхронизации пользователя показывает только то, что помечено (я только узнаю об этом сегодня, поэтому мое понимание этого API ограничено, если не сказать больше...), так что это просто случай, когда React на самом деле не синхронизирует то, что происходит внутри componentWillReceiveProps? Если это полезно, я использую повторный выбор и Redux, но я предполагаю, что мои селекторы уже запущены до вызова componentWillReceiveProps, но, может быть, я ошибаюсь?

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

Обновление: добавлена ​​реализация componentWillReceiveProps

реагировать на профиль Chrome

Обновление 2. Добавление ссылки в профиль Chrome

Если кому-то интересно взглянуть на фактический профиль, вот ссылка, вы можете просмотреть его, открыв инструменты разработчика Chrome, перейдя на вкладку производительности, а затем нажав «загрузить профиль»:

https://www.dropbox.com/s/72e9kwyxr0myec3/delete_react_perf_user_timing?dl= 0

Обновление 3: объяснение componentWillReceiveProps

Итак, кажется, что componentWillReceiveProps (каким-то образом) в конечном итоге вызывает mapStateToProps, что объясняет, почему это выглядит так долго в профиле. Я предполагаю, что вызов componentWillReceiveProps заменяется методом redux connect или чем-то подобным, но я не проверял это См. принятый ответ. Во всяком случае, вы можете увидеть доказательства этого на следующем снимке экрана:

componentWillReceiveProps стек вызовов


person davertron    schedule 03.07.2018    source источник
comment
Какие реквизиты получает ваш ящик? Посмотрите на HEAP — во время ComponentWillReceiveProps вы видите большие изменения в использовании памяти, увеличение на 250 МБ, а затем уменьшение на 350 МБ. Однако я не уверен, что между этим и вашими проблемами с производительностью есть какая-то связь.   -  person nxSolari    schedule 04.07.2018
comment
В куче в верхней части скриншота не похоже, что во время этого вызова функции все резко меняется в куче, я неправильно понимаю?   -  person davertron    schedule 04.07.2018
comment
Ну, я не могу навести курсор на график, чтобы увидеть точные значения, но похоже, что они почти удвоились. Я не говорю, что изменение использования памяти на 300 МБ ДОЛЖНО вызывать проблемы с производительностью, но для меня это показывает, что что-то происходит, что приводит к увеличению использования памяти. Кроме того, рассматривали ли вы возможность добавления проверок производительности console.log в жизненные циклы как до, так и после componentWillReceiveProps?   -  person nxSolari    schedule 04.07.2018
comment
Ах, извините, я смотрел перед componentWillReceiveProps, но я понимаю, что вы говорите, после того, как componentWillReceiveProps сделан, куча немного подпрыгивает. Это очень странно, потому что код внутри componentWillReceiveProps очень прямолинейный, и я не вижу, как он вообще будет выделять какую-либо память (все, что он делает, это проверяет, изменилась ли длина одного из реквизитов, и устанавливает простое свойство состояния ...). В любом случае, я продолжу копать, я думаю.   -  person davertron    schedule 04.07.2018
comment
Да, не видя кода внутри componentWillReceiveProps, я не думаю, что могу дать какой-либо другой совет. Я предполагаю, что вы знакомы с предупреждениями, касающимися этого хука жизненного цикла, но если вы не знакомы, вам следует прочитать документацию здесь (reactjs.org/docs/) и, возможно, реорганизуйте его из своего кода, чтобы увидеть, решит ли это вашу проблему.   -  person nxSolari    schedule 04.07.2018
comment
Я давно не читал эти документы, спасибо за ссылку. Я могу попробовать переместить код в compondentDidUpdate и посмотреть, имеет ли это значение или нет, похоже, что в настоящее время это правильное место для размещения чего-то подобного (пока я не перейду на React 16). Я обновил свой пост выше своей реализацией componentWillReceiveProps для справки.   -  person davertron    schedule 05.07.2018


Ответы (1)


Если вы внимательно посмотрите на диаграмму пламени, то увидите, что вызов Connect(Drawer).componentWillReceiveProps занимает много времени, а не сам компонент Drawer, что объясняет, почему мой временной код внутри компонента Drawer показывал время совершенно иначе, чем пламя. график. Компонент Connect(Drawer) является компонентом более высокого порядка, вся цель которого состоит в вызове mapStateToProps и mapDispatchToProps для сопоставления создателей состояния и действий с реквизитами вашего компонента. В этом случае мой вызов mapStateToProps был очень медленным, что объясняет результаты на графике.

В качестве примечания: было бы здорово, если бы react-redux добавила User Timing API, чтобы вызовы mapStateToProps и т. д. отображались на графике пламени.

TL;DR Обратите особое внимание на фактические названия компонентов на графике пламени.

person davertron    schedule 12.07.2018