Это первые 115 не поливают оригинал, я хочу получить более хороший оригинальный текст, ищите количество общественных забот о нас ~ Эта статья впервые появилась в правительстве, чтобы принять блог облачного интерфейса:Использование React-профилировщика
Использование React-профилировщика
предисловие
Обычно, когда вы разрабатываете проект, иногда вы чувствуете, что проект застрял.Обычно вы можете сразу внести исправления, но иногда бывает непросто найти точку, которая вызывает зависание, или трудно найти потенциальные проблемы с производительностью.React Developer Tools
который предоставилProfiler
Он может интуитивно помочь вам найти узкое место в производительности в проекте React и еще больше улучшить наше приложение.Рекомендуется всем установить и использовать.
-
Концептуально React работает в две фазы, и график жизненного цикла React выглядит так:
-
рендерингопределит, какие изменения необходимо внести, например, в DOM. Реагировать на звонки на этом этапе
render
, затем сравните результат с последним визуализированным результатом. -
этап фиксацииПроисходит при изменении приложения React. На этом этапе React также вызовет
componentDidMount
а такжеcomponentDidUpdate
методы жизненного цикла, такие как . (Для React DOM это происходит, когда React вставляет, обновляет и удаляет узлы DOM.)Profiler
Данные о производительности собираются на этапе отправки, поэтому проблемы с производительностью на этапе отсутствия отправки обнаружить невозможно.
-
использовать
Установить
ОтМагазин приложений Chrome,Расширение для браузера Фаерфокс,Пакет узлаЗагрузить и установить;
представлять
-
rendered
причина
-
render
s компонент
демо
Для того, чтобы всем было удобно читать информацию панели дисплея, продемонстрируем на простейшем примере:
import React from "react";
const style = {
display: "flex",
justifyContent: "space-around",
maxWidth: 800,
margin: "0 auto",
padding: 60,
};
const Display = (props) => {
console.log("Display");
return <pre>{JSON.stringify(props.data, null, 2)}</pre>;
};
const Count = (props) => {
console.log("count");
return <p>{props.data}</p>;
};
// Anonymous
export default class extends React.Component {
state = {
count: 0,
};
handleAdd = () => {
this.setState({
count: this.state.count + 1,
});
};
onChange = (key) => (e) => {
this.setState({
[key]: e.target.value,
});
};
render() {
const { text, password, count } = this.state;
return (
<div>
<div style={style}>
<div>
<input type="text" value={text || ""} onChange={this.onChange("text")} />
<br />
<br />
<input type="text" value={password || ""} onChange={this.onChange("password")} />
</div>
<Display data={{ text, password }} />
</div>
<div align="center">
<Count data={count} />
<button onClick={this.handleAdd}>add</button>
</div>
</div>
);
}
}
Действуйте следующим образом:
1. Нажмите кнопку перезагрузки и дождитесь завершения загрузки страницы;
2. Введите контент во входные данные, чтобы страница появиласьrender
;
3, нажмите кнопку «Добавить» еще раз, чтобы снова создать страницу.render
;
потомProfiler
AпредставитьКоличество раз каждый столбец представляет собой представленные данные.
-
Цвет и высота столбцов соответствуют времени, необходимое для рендеринга этого фиксатора (более высокие желтые, чем более короткие зеленые);
-
Мы можем игнорировать самый короткий серый столбец, серый цвет означает отсутствие повторного рендеринга;
AНашим шагам соответствуют 6 столбцов района:
-
Первый столбец соответствует монтированию страницы, потому что это первый рендеринг, поэтому он самый высокий, что означает самое долгое время;
-
Второй и третий столбцы соответствуют двум рендерингам, вызванным введенным текстом;
-
Последние три столбца соответствуют рендерингу, вызванному тремя щелчками кнопки добавления.
переключаться влево и вправоAДанные области, указывающие на то, что информация о представлении выбранного столбца будет отображаться вBОбласть, в то же времяC
-
Committed at
-
Render duration
Эта подача представляет собой потребление времени оказания, нам нужно сосредоточиться на этом;
Например06/11Этот коммит, весьAnonymous
используемый компонент1ms
Рендерировать, но только провел себя0.2ms
, На рисунке0.2ms of 1ms
, оставшиеся0.8ms
Используется при рендеринге его дочерних элементов. ПодсборкаDisplay
а такжеCount
У него также есть собственное соответствующее время рендеринга и так далее.
- Ширина и цвет компонента указывают время, необходимое для рендеринга, а время желтого цвета также больше;
Для более удобного просмотра затрат времени на компоненты мы можем переключитьсяRanked 排序图
, вы можете четко увидеть компонент, который занял больше всего времени.
Например10/11Это представление, операция просто нажмите кнопку добавления, чтобы обновитьCount
, но здесьDisplay
Но он самый затратный по времени.
- Нажмите, чтобы выбрать
Display
, который можно увидеть 6 раз справаrendered
Информация вышеWhy did this render?
Записывайте каждый разrendered
с причин;
Если вы знаете приведенный здесь код, вам будет очень легко подумать, что следующим шагом будет оптимизация.Display
Код, потому что здесьprops.data
Что кажется не изменилась. Конечно, в это время вы можете перейти наComponents
Вкладка, подтвердите свои идеи, вот более подробная информация компонента.
-
<>
Вы можете просмотреть исходный код; -
🐞
Информация о компонентах может быть напечатана на консоли;
предотвратить повторный рендеринг
ИзменятьDisplay
а такжеCount
Формулировка для обеспечения того, чтобы два компонентаreRender
Просто потому, что его собственные атрибуты изменились, давайте посмотрим на эффект.
const Display = React.memo(
(props) => {
console.log("Display");
return <pre>{JSON.stringify(props.data, null, 2)}</pre>;
},
(prev, next) => {
return JSON.stringify(prev) === JSON.stringify(next);
}
);
const Count = React.memo((props) => {
console.log("count");
return <p>{props.data}</p>;
});
Повторите вышеуказанную операцию еще раз и посмотрите на результат.
жаль, хотяDisplay
существуетReact.memo
При функции сравнения больше не повторяется.render
. ноDisplay
Время рендеринга приложения и время рендеринга приложения стали больше, чем до перезаписи, а это значит, чтоmemo
Время сравнения функции больше, чем время рендеринга самого компонента.В текущем простом приложенииReact.memo
Не стоит пытаться «оптимизировать» приложение.
Улучшать
Теперь мы знаем, как читатьProfiler
reRender
import { List, Avatar } from "antd";
const Length100List = ({ data }) => {
return (
<List
itemLayout="horizontal"
dataSource={data}
renderItem={(item) => (
<List.Item key={item.id}>
<List.Item.Meta
avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
title={item.name.last}
description={item.email}
/>
<div>{item.nat}</div>
</List.Item>
)}
/>
);
};
// list 代表一个长度为100的数组,取自 https://randomuser.me/api/?results=100&inc=name,gender,email,nat&noinfo
<div style={style2}>
<Length100List data={list} />
</div>;
render
Profiler
Записанная информация выглядит следующим образом:
Очевидно, что неоптимизированныйLength100List
занимает большую частьcommit
время, которое явно не нужно, мы используемReact.memo
остановитьсяList
ненужный рендеринг.
const PureListItem = React.memo(({ item }) => {
return (
<List.Item key={item.id}>
<List.Item.Meta
avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
title={item.name.last}
description={item.email}
/>
<div>{item.nat}</div>
</List.Item>
);
});
const Length100List = React.memo(({ data }) => {
return <List itemLayout="horizontal" dataSource={data} renderItem={(item) => <PureListItem item={item} />} />;
});
Посмотрите еще раз на эффект:
Сейчасcommit
Самый длинный — это когда мы нажимаем кнопку «Добавить», чтобы обновить данные. Что ж, доволен!
Метод оптимизации
-
shouldComponentUpdate()
Для разных бизнес-сценариев функция сравнения здесь будет написана по-разному, например, просто сравнениеprops
свойство , или как в примерах в этой статье сJSON.stringify
напрямую сравниватьprops
. Для сложных структур данных, если вам нужно заблокироватьreRender
, не рекомендуется выполнять глубокие сравнения или использоватьJSON.stringify
, что сильно влияет на КПД. может рассмотреть возможность использованияimmutableдля ускорения сравнения вложенных данных, наimmutable
использовать, вы можете просмотретьИзучите неизменяемость за 15 минут. Вы можете пойти, чтобы понять ихCustomComponent
PureComponent
-
shouldComponentUpdate
false
(имеется в виду хороший крюк Дафа); - Из-за функциональных компонентов и
hook
Использование таких сценариев оптимизации значительно сократилось;
import React from "react";
import { is } from "immutable";
export default class extends React.Component {
shouldComponentUpdate(nextProps = {}, nextState = {}) {
if (
Object.keys(this.props).length !== Object.keys(nextProps).length ||
Object.keys(this.state).length !== Object.keys(nextState).length
) {
return true;
}
for (const key in nextProps) {
if (!is(this.props[key], nextProps[key])) {
return true;
}
}
for (const key in nextState) {
if (!is(this.state[key], nextState[key])) {
return true;
}
}
return false;
}
}
-
React.PureComponent
React.PureComponent
полагаться наshouldComponentUpdate
реализован слойshallowEqual, только для поверхностного сравнения объектов, чтобы уменьшить возможность пропуска обновлений, но если объект содержит сложные структуры данных, это может привести к ложным выравниваниям, поэтомуPureComponent
будет больше использоваться в более простыхprops & state
на дисплее компонента.React.memo
То же, что и его принцип, только для函数组件
, возвращаемое значение функции обратного вызова такое же, какshouldComponentUpdate
Напротив; -
Hook
Реагировать, чтобы обеспечить такие
useEffect
,useMemo
,useCallback
Такие как функция крюка, они представленыmemoized
свойства, их вторым параметром является массив значений, при изменении данных массива значений,hook
函数会重新执行。 несмотря на то чтоhook
Решите некоторые болевые точки, такие как компоненты, ноhook
Сравните зависимости. Надеются все еще больные точки, и вот зависимость иногда очень долго, сообщество все еще должно принять официальный спрос - добавить пользовательские функции, но и данные официальные функции自定义hook
Это уже может помочь нам удовлетворить такие потребности.// customEquals: lodash.isEqual、Immutable.is、dequal.deepEqual 等; const useOriginalCopy = (value) => { const copy = React.useRef(); const diffRef = React.useRef(0); if (!customEquals(value, copy.current)) { copy.current = value; diffRef.current += 1; } return [diffRef.current]; };
Суммировать
О проекте РеактreRender
Оптимизация всегда была банальной проблемой, каждый может более-менее обобщить собственный опыт в проекте, например, пакетные обновления, непрозрачные пропсы, использование режима публикации-подписки. Более того, в функциональном программировании, поддерживаемом React, обычно количество кода в компоненте не должно быть слишком большим, что требует больше разработчиков для доработки компонента, и легче контролировать свойства и состояние компонента. непонятно, почему это произошлоreRender
когда,React Profiler
является ответом.
использованная литература
Реагировать на оптимизацию производительности
Use the React Profiler for Performance
Повысьте производительность приложения с помощью React Hooks и инструментов отладки
Изучите неизменяемость за 15 минут
Рекомендуемое чтение
Минимальные запасы для электронной коммерции — артикул и реализация алгоритма
Что нужно знать об управлении проектами
Как построить глобальную систему поиска кода от 0 до 1
Как создать платформу сборки и развертывания, подходящую для вашей команды
работы с открытым исходным кодом
- Zhengcaiyun интерфейсный таблоид
адрес с открытым исходным кодомwww.zoo.team/openweekly/(На главной странице официального сайта таблоида есть группа обмена WeChat)
Карьера
ZooTeam, молодая, увлеченная и творческая команда, связанная с отделом исследований и разработок продукции Zhengcaiyun, базируется в живописном Ханчжоу. В настоящее время в команде более 50 фронтенд-партнеров, средний возраст которых составляет 27 лет, и почти 30% из них — инженеры с полным стеком, настоящая молодежная штурмовая группа. В состав членов входят «ветераны» солдат из Ali и NetEase, а также первокурсники из Чжэцзянского университета, Университета науки и технологий Китая, Университета Хандянь и других школ. В дополнение к ежедневным деловым связям, команда также проводит технические исследования и фактические боевые действия в области системы материалов, инженерной платформы, строительной платформы, производительности, облачных приложений, анализа и визуализации данных, а также продвигает и внедряет ряд внутренних технологий. Откройте для себя новые горизонты передовых технологических систем.
Если вы хотите измениться, вас забрасывают вещами, и вы надеетесь начать их бросать; если вы хотите измениться, вам сказали, что вам нужно больше идей, но вы не можете сломать игру; если вы хотите изменить , у вас есть возможность добиться этого результата, но вы не нужны; если вы хотите изменить то, чего хотите достичь, вам нужна команда для поддержки, но вам некуда вести людей; если вы хотите изменить установившийся ритм, это будет "5 лет рабочего времени и 3 года стажа работы"; если вы хотите изменить исходный Понимание хорошее, но всегда есть размытие того слоя оконной бумаги.. , Если вы верите в силу веры, верьте, что обычные люди могут достичь необыкновенных вещей, и верьте, что они могут встретить лучшего себя. Если вы хотите участвовать в процессе становления бизнеса и лично способствовать росту фронтенд-команды с глубоким пониманием бизнеса, надежной технической системой, технологиями, создающими ценность, и побочным влиянием, я думаю, что мы должны говорить. В любое время, ожидая, пока вы что-нибудь напишете, отправьте это наZooTeam@cai-inc.com