Я работаю над проектом ReactJS + Redux, который в основном извлекает некоторые данные (сотни / тысячи или элементы) из API и отображает их в пользовательском интерфейсе.
Проблема, с которой я столкнулся, заключается в том, что после 20-30 действий и многократных повторных списков использование памяти увеличивается до 1 ГБ, и я не могу понять, почему.
Я пытался отлаживать это сам, но я действительно новичок в устранении утечек памяти в коде внешнего интерфейса. Что я заметил, так это то, что число узлов удваивается при каждом повторном рендеринге списка.
Что я делал:
- Загрузить инструмент и отобразить полный список элементов (вызов GET API)
- Добавление нового элемента в список (вызов API POST)
- Перерисовать список (получить его снова из API)
- Повторите примерно 10-20 раз
- Использование памяти увеличивается до 1 ГБ (начиная с 120 МБ)
Я запускаю код в работе без опций отладки и плагинов для браузера.
const render = Component => {
ReactDOM.render(
(
<Provider store={store}>
<BrowserRouter>
<AppContainer>
<Component />
</AppContainer>
</BrowserRouter>
</Provider>
),
document.getElementById('root')
)
}
let store = createStore(reducers, {}, applyMiddleware(thunk))
render(App)
редуктор для списка предметов
import {
FETCH_ITEMSLIST_BEGIN,
FETCH_ITEMSLIST_SUCCESS,
FETCH_ITEMSLIST_FAILURE,
} from '../actions/itemsList'
const initialState = {
data: [],
loading: false,
error: null
}
export default function itemsList(state = initialState, action) {
switch(action.type) {
case FETCH_ITEMSLIST_BEGIN:
return {
...state,
loading: true,
error: null
}
case FETCH_ITEMSLIST_SUCCESS:
return {
...state,
loading: false,
data: action.data
}
case FETCH_ITEMSLIST_FAILURE:
return {
...state,
loading: false,
error: 'ERROR: ' + action.data + ' dispatched by: ' + action.type,
data: []
}
default:
return state
}
}
редуктор для удаления элемента
import {
ITEM_DELETE_RESET,
ITEM_DELETE_BEGIN,
ITEM_DELETE_SUCCESS,
ITEM_DELETE_FAILURE,
ITEM_DELETE_DISPLAY_CONFIRMATION,
ITEM_DELETE_HIDE_CONFIRMATION
} from '../actions/itemDelete'
import { FETCH_ITEMSLIST_SUCCESS } from '../actions/itemsList'
import { UPDATE_ITEM_SELECTED } from '../actions/selectedItem'
import { TAB_PANNEL_SWITCHED } from '../actions/itemDetailsPanel'
const initialState = {
loading: false,
error: false,
success: false,
itemId: null,
displayConfirmation: false
}
export default function itemDelete(state = initialState, action) {
switch(action.type) {
case ITEM_DELETE_RESET:
return {
...state,
loading: false,
error: false,
success: false,
displayConfirmation: false
}
case ITEM_DELETE_BEGIN:
return {
...state,
loading: true,
error: false,
success: false,
displayConfirmation: false
}
case ITEM_DELETE_SUCCESS:
return {
...state,
loading: false,
error: false,
success: action.response,
displayConfirmation: false
}
case ITEM_DELETE_FAILURE:
return {
...state,
loading: false,
error: action.response,
success: false,
displayConfirmation: false
}
case FETCH_ITEMSLIST_SUCCESS:
return {
...state,
loading: false,
error: false,
success: false,
displayConfirmation: false
}
case ITEM_DELETE_DISPLAY_CONFIRMATION:
return {
...state,
displayConfirmation: true
}
case ITEM_DELETE_HIDE_CONFIRMATION:
case UPDATE_ITEM_SELECTED:
case TAB_PANNEL_SWITCHED:
return {
...state,
displayConfirmation: false
}
default:
return state
}
}
Позже отредактируйте:
Для проверки я нажимаю на элемент в списке, который открывает боковую панель и изменяет URL-адрес страницы. Затем я закрываю боковую панель, изменяя URL-адрес. Я думал, что это может быть актуально