РЕДАКТИРОВАТЬ Похоже, что это связано с проблемой в React и будет исправлено в будущем выпуске. https://github.com/facebook/react/issues/18066
Учитывая таблицу в реакции, которая отображает данные из API, которые могут быть обновлены с совершенно новой информацией, я наблюдал утечку отсоединенного узла DOM (наблюдайте зеленые цифры ):
Вот код, выполненный в формате GIF (код, указанный ниже для потомков). Чтобы увидеть утечку, go на полную страницу , откройте chrome dev инструменты, откройте вкладку «Performance Monitor» и быстро нажмите кнопку «Regen», как показано на рисунке.
В этом коде и поле , где узлы не генерируются в al oop, утечка не происходит.
Единственная разница - {rows}
массив в jsx. Смущающая часть заключается в том, что {rows}
не является глобальной переменной, поэтому я не вижу, как это помешало бы старым узлам быть G C 'd.
Почему используется локальная переменная rows
приводит к утечке отсоединенного узла DOM?
Примечание. Кажется, что узлы DOM устанавливаются на 21 000, но в любом случае их не должно быть так много, как вы можете видеть, они начинаются с 7 000 после первого поколения таблицы. В моем приложении из реальной жизни эти отсоединенные узлы сохраняются даже благодаря навигации (с реагирующим маршрутизатором), что заставляет меня поверить, что это фактическая утечка, а не просто узлы, ожидающие получения G C 'd.
Полный код, имитирующий утечку:
import React, { useState } from "react";
export default function App() {
const [count, setCount] = useState(0);
return (
<div className="App">
<button onClick={() => setCount(prev => prev + 1)}>Regen</button>
<FTable count={count} />
</div>
);
}
function Cell() {
const num = Math.floor(Math.random() * 100);
return <td>{num}</td>;
}
function FTable(props) {
const { count } = props;
const rows = [];
if (count > 0) {
for (let i = 0; i < 1000; i++) {
rows.push(
// Use a different key for each time the
// table is regenerated to simulate a new API
// call bringing in new data
<tr key={`${i} ${count}`}>
<Cell row={i} />
<Cell row={i} />
<Cell row={i} />
</tr>
);
}
}
return (
<div>
<table>
<tbody>{rows}</tbody>
</table>
</div>
);
}