Как исправить IntersectionObserver, вызывающий утечку памяти в моем веб-приложении OpenLayers?

Итак, я разрабатываю веб-приложение под названием MSC AniMet. Это приложение написано с использованием Vue2 и Vuetify2, и по сути это большая карта OpenLayers с множеством добавленных к ней материалов и функций, которая работает со слоями WMS.

Недавно я сделал обновление, чтобы добавленные слои обновлялись всякий раз, когда появлялась новая информация, чтобы у вас всегда были слои погоды с самой последней информацией, и вы могли использовать приложение в качестве информационной панели. Казалось, все работало нормально, пока через 3 дня после запуска хром на приборной панели не вылетел с сообщением «Недостаточно памяти».

После некоторого расследования я обнаружил, используя инструменты разработчика Chrome, что виновником, по-видимому, был IntersectionObserver, который занимал все больше и больше памяти с угрожающей скоростью. Вот два снимка, сделанные с разницей в 15 минут:

Проблема в том, что я не использую IntersectionObserver внутри своего кода, поэтому понятия не имею, что является причиной этого. У меня такое ощущение, что это связано с OpenLayers, но это только мое предположение, учитывая, какие библиотеки я использую:

├── @mdi/[email protected]
├── @mdi/[email protected]
├── @vue/[email protected]
├── @vue/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

Вот постоянная ссылка на веб-сайт для воспроизводимого примера: https://eccc-msc.github.io/msc-animet/?layers=RADAR_1KM_RRAI%3B0.75%3B0%3B1%3B0%3B1,RADAR_1KM_RSNO%3B0.75%3B0%3B1%3B0%3B0,RADAR_COVERAGE_RRAI %3B0.75%3B0%3B1%3B0%3B0&extent=-19416707,2902733,-620801,11820999

В контроллере времени над кнопкой воспроизведения есть небольшой значок шестеренки, там вы можете установить циклическую анимацию, а затем просто нажать кнопку воспроизведения. Если вы проверите использование памяти, вы увидите, что IntersectionObserver со временем увеличивается.

Я помещу ссылки на github, чтобы показать, что делает цикл в коде и что называется:

  1. Кнопка «Воспроизвести» запускает https://github.com/ECCC-MSC/msc-animet/blob/main/src/comComponents/Time/AnimationControls/PlayPauseControls.vue#L84 , который затем вызывает https:// github.com/ECCC-MSC/msc-animet/blob/main/src/comComponents/Time/AnimationControls/PlayPauseControls.vue#L131 для запуска анимации
  2. Кнопка «Воспроизвести» увеличивает DateIndex, что запускает этот наблюдатель: https://github.com/ECCC-MSC/msc-animet/blob/main/src/comComponents/Time/TimeControls.vue#L388
  3. Это вызывает этот метод: https://github.com/ECCC-MSC/msc-animet/blob/main/src/comComponents/Time/TimeControls.vue#L183 , который затем обновляет здесь параметр TIME слоев ️ 🔁 https://github.com/ECCC-MSC/msc-animet/blob/main/src/comComponents/Time/TimeControls.vue#L378
  4. Наконец, метод ожидает события завершения рендеринга карты и выдает событие https://github.com/ECCC-MSC/msc-animet/blob/main/src/comComponents/Time/TimeControls.vue#L248, которое снова перехватывается на шаге 2, который снова увеличивает DateIndex, и это весь цикл.

Я попробовал обновить openlayers до последней версии (9.1), и это ничего не изменило (кроме еще одного несвязанного критического изменения, поэтому сейчас я придерживаюсь версии 6.15.1). Я также пробовал закомментировать многие импортированные файлы, например h264-mp4-encoder, но это не повлияло на проблему Intersect.

Я думаю, что такие вещи будет сложно отлаживать теперь, когда на их основе построено множество вещей. Возможно, попробуйте устранить неполадку, используя git bisect, и определите, когда у вас началась утечка памяти. В противном случае я не уверен, есть ли у вас способ проследить, что может быть с помощью наблюдателя пересечений, возможно, выполняя поиск по каждому пакету, который вы используете? Хотя, может быть, они, возможно, даже не так называют, а как-то связано с визуализацией. Может быть, попытаться воспроизвести его, медленно перестраивая с нуля? Возможно, это облегчит поиск виновного?

kissu 03.05.2024 17:54

Не могу найти ничего под названием «IntersectObserver» в старом репозитории, так что, возможно, что-то еще: github.com/…

BR75 06.05.2024 12:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
127
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Просмотрев библиотеки, которые я использовал, и посмотрев, какие из них содержат IntersectionObserver, я обнаружил, что v-progress-linear vuetify использует его. Этот компонент использовался в моем коде при загрузке слоя: я увеличивал флаг loading при загрузке слоя, а когда он загружался, я уменьшал его. v-progress-linear появлялся, когда флаг был выше 0 и по какой-то причине использовался IntersectionObserver, который в конечном итоге занимал все больше и больше памяти. Поскольку я находился в цикле, в котором всегда загружал новые временные шаги, эта полоса загрузки всегда была активной. Я удалил этот компонент в своей ветке и проблема действительно исчезла.

Обновлено: изучил проблему, и это была просто родительская проблема. VProgressLinear использует IntersectionObserver, который проверяет пересечения со своим родителем. По какой-то причине размещение его внутри карты openlayers делает его очень неприятным, и если я просто уберу его из этого div, все будет в порядке.

Edit2: Неважно, перемещение его из div просто сделало его появление немного медленнее, но утечка памяти все еще существует. Вместо этого решил переопределить индикатор выполнения с нуля, поскольку v-progress-bar vuetify, похоже, всегда вызывает утечки памяти, что бы я ни пытался. На основе этого кода https://medium.com/@kapilkumar0037/indeterminate-progress-bar-using-css-in-angular-0fd5f0151795.

Другие вопросы по теме