Мы часто сталкиваемся с необходимостью отображать списки на основе данных. Вы, вероятно, делали такой код сотни тысяч раз.
Но если вам нужно отображать тысячи фрагментов данных одновременно, это неизбежно приведет к зависанию браузера, пропуску кадров или даже зависанию.
В этой статье будет представлено использованиеreact-virtualizedдля эффективного отображения больших списков данных.
Давайте начнем!
Сначала создайте приложение React
create-react-app virtualization
Приложение отобразит 1000 комментариев следующим образом:
Внедряем сторонние библиотекиlorem-ipsumдля создания фиктивных данных:
cd virtualization
npm install --save lorem-ipsum
существуетsrc/App.js
введен вlorem-ipsum
:
import loremIpsum from 'lorem-ipsum';
Затем создайте массив из 1000 элементов данных:
const rowCount = 1000;
class App extends Component {
constructor() {
super();
this.list = Array(rowCount).fill().map((val, idx) => {
return {
id: idx,
name: 'John Doe',
image: 'http://via.placeholder.com/40',
text: loremIpsum({
count: 1,
units: 'sentences',
sentenceLowerBound: 4,
sentenceUpperBound: 8
})
}
});
}
//...
}
Каждая из приведенных выше данных содержитid
,用户名
,图片
,随机生成4~8个字评论
.
существуетrender()
Используйте этот массив в:
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<div className="list">
{this.list.map(this.renderRow.bind(this))}
</div>
</div>
);
}
УвеличиватьrenderRow()
для создания столбцов:
renderRow(item) {
return (
<div key={item.id} className="row">
<div className="image">
<img src={item.image} alt="" />
</div>
<div className="content">
<div>{item.name}</div>
<div>{item.text}</div>
</div>
</div>
);
}
существуетsrc/App.css
Добавить точечный стиль:
.list {
padding: 10px;
}
.row {
border-bottom: 1px solid #ebeced;
text-align: left;
margin: 5px 0;
display: flex;
align-items: center;
}
.image {
margin-right: 10px;
}
.content {
padding: 10px;
}
Хорошо, запускаем проектyarn start
Вы можете увидеть следующий экран:
Вид на элементы, мы можем видетьDOM
Загружено многоdiv
:
Проверим производительность
Если вы используете Chrome, всего несколько шагов, чтобы быстро проверить производительность:
- Открытые инструменты разработчика
- Нажмите Command+Shift+P (Mac) или Control+Shift+P (Windows, Linux), чтобы открыть меню команд.
- войти
render
, выберите из раскрывающегося спискаShow Rendering
. - нажмите
render
закладка,FPS Meter
Отметьте перед. - список прокрутки
Мы видим, что частота кадров падает с 60 до примерно 38 по мере прокрутки полосы прокрутки. Это все равно всего 1000 штук данных.Если данные увеличить, то браузер зависнет или вообще зависнет.
Давайте взглянемreact-virtualizedКак это улучшает производительность?
react-virtualizedпринцип
Основной принцип: визуализируйте только то, что видите.
Вышеупомянутое приложение отображает 1000 комментариев, но на экране отображается только 10 или около того фрагментов данных, поэтому рендеринг остальных 990 — пустая трата времени.
Если мы отображаем только видимые комментарии, когда мышь прокручивается, чтобы увидеть больше, новые узлы заменяют старые. Это прекрасно решает проблему узких мест производительности.
Как это использовать?
первый вsrc/App.js
в, импортList
Компоненты:
import { List } from "react-virtualized";
заменятьrender()
Оригинальный код:
<div className="list">
{this.list.map(this.renderRow.bind(this))}
</div>
использоватьList
компоненты
const listHeight = 600;
const rowHeight = 50;
const rowWidth = 800;
//...
<div className="list">
<List
width={rowWidth}
height={listHeight}
rowHeight={rowHeight}
rowRenderer={this.renderRow.bind(this)}
rowCount={this.list.length} />
</div>
переписатьrenderRow()
:
renderRow({ index, key, style }) {
return (
<div key={key} style={style} className="row">
<div className="image">
<img src={this.list[index].image} alt="" />
</div>
<div className="content">
<div>{this.list[index].name}</div>
<div>{this.list[index].text}</div>
</div>
</div>
);
}
запустить приложениеyarn start
:
Элементы просмотра:
Вы можете видеть, что отображаются только видимые элементы.
Как производительность?
Протестируйте тем же методом, что и выше:
Видно, что она в основном держится на уровне около 60 кадров. Отличное выступление (^_^)
Вышеупомянутое простоreact-virtualizedПростое приложение, вы можете попробовать, если вы заинтересованы!
Спасибо за прочтение!
Эта статья переведена сEsteban HerreraизRendering large lists with React Virtualized