Справочная информация: Мое приложение React зависало на мобильном телефоне. Инструменты Chrome dev указали, что сборка мусора не сработала. Заглядывая в кучу, все верхние конструкторы по оставшемуся размеру ссылались на наблюдатель пересечения (использовался для бесконечной прокрутки во многих моих компонентах реакции).
Вопрос : Как я могу go исправить утечки памяти, вызванные пересечением наблюдателя? Есть ли способ запустить сборку мусора, когда компоненты размонтированы?
Пример компонента с использованием Обзора пересечения для бесконечной прокрутки:
import React, { useEffect, useState, useRef, useCallback } from 'react'
import { Link } from 'react-router-dom'
import { uuid, fabricateTimeStamp, getRandom } from '../containers/helperFunctions'
import { avatarQuery } from '../words'
import quote from 'inspirational-quotes'
import history from '../history'
import { thumbsUp, thumbsDown, arrowDrop } from './svgs'
import {
fetchAvatars as callAvatarsAPI,
fetchVideos as callVideosAPI } from '../containers/api'
const ActivityFeed = (props) => {
const [firstRenderDone, setFirstRenderDone] = useState()
const [comments, setComments] = useState([])
useEffect(() => {
const mobile = window.innerWidth <= 600
if (mobile) fetchAvatars('woman', 3)
if (!mobile) fetchAvatars('woman', 6)
if (history.location.pathname.includes('/video/') || history.location.pathname.includes('/search/')) {
document.querySelector('.activityFeedContainer').classList.toggle('hide')
}
}, [])
// if user clicks nav button, remove all comments generated by infinite scroll
useEffect(() => {
setComments(prevState => (prevState.slice(0, 8)))
}, [props.button])
// INFINITE SCROLL
// Callback is triggered when ref is set in mapCommentsToHTML
const observer = useRef()
const lastActivityPost = useCallback(lastPostNode => {
observer.current = new IntersectionObserver(entries => {
const lastPost = entries[0]
if (lastPost.isIntersecting) fetchAvatars(getRandom(avatarQuery), 6)
})
if (lastPostNode) observer.current.observe(lastPostNode)
})
const fetchAvatars = async (query, amount) => {
let response = await callAvatarsAPI(query, amount)
response = response.data.hits
mapCommentsToHTML(response)
}
const mapCommentsToHTML = (response) => {
const picsMappedToHTML = response.map((pic, index) => {
return (
<div className="commentWrapper" key={uuid()} ref={response.length === index + 1 ? lastActivityPost : null}>
<div className="avatarPlaceholder--comments">
{props.page === 'channel'
? <img
className="avatarPlaceholder--img"
src={
props.userAvatar.previewURL ? props.userAvatar.previewURL
: props.userAvatar.userImageURL === "" ? 'https://i.imgur.com/ZwDgXSF.jpg'
: props.userAvatar.userImageURL}
alt="An Activity Feed User Avatar" />
: <Link to={`/channel/${pic.id}`}>
<img
className="avatarPlaceholder--img"
src={pic.previewURL}
alt="An Activity Feed User Avatar" />
</Link>
}
</div>
<div className="commentContainer" >
<Link to={`/channel/${pic.id}`}>
<h5 className="commentorName">{props.page === 'channel' ? props.userName : pic.user}</h5>
</Link>
<span className="dateOfComment">{fabricateTimeStamp(index)}</span>
<p className={`${props.page}-comment`}>{quote.getQuote().text}</p>
<div className="thumbs">
<span className="thumbsUpIcon">
{thumbsUp(16)}
</span>
<span className="thumbsDownIcon">
{thumbsDown(16)}
</span>
</div>
<p className="replyText">REPLY</p>
<div className="viewReplies">
<span className="arrowDrop">
{arrowDrop()}
</span>
View {Math.floor(Math.random() * 50) + 2} Replies
</div>
</div>
</div>
)
})
setComments(prevState => ([...prevState, ...picsMappedToHTML]))
}
return (
<aside className="activityFeedContainer">
<h1 className={`${props.page}--activity-feed-title`}>Activity Feed</h1>
<hr className="home--activityfeed-hr" />
<div className="commentSection--activityfeed">
{comments}
</div>
</aside>
)
}
export default ActivityFeed
Chrome Производительность Временная шкала (падение @ 27 секунд связано с щелчком по тегу <a>
, который вызывал обновление страницы sh)
![Memory Leak](https://i.stack.imgur.com/pJogD.png)
Снимки кучи:
![Heap Snapshot 4](https://i.stack.imgur.com/z3NK8.png)