Итак, я разрабатываю веб-приложение под названием 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, чтобы показать, что делает цикл в коде и что называется:
Я попробовал обновить openlayers до последней версии (9.1), и это ничего не изменило (кроме еще одного несвязанного критического изменения, поэтому сейчас я придерживаюсь версии 6.15.1). Я также пробовал закомментировать многие импортированные файлы, например h264-mp4-encoder, но это не повлияло на проблему Intersect.
Не могу найти ничего под названием «IntersectObserver» в старом репозитории, так что, возможно, что-то еще: github.com/…
Просмотрев библиотеки, которые я использовал, и посмотрев, какие из них содержат 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.
Я думаю, что такие вещи будет сложно отлаживать теперь, когда на их основе построено множество вещей. Возможно, попробуйте устранить неполадку, используя
git bisect
, и определите, когда у вас началась утечка памяти. В противном случае я не уверен, есть ли у вас способ проследить, что может быть с помощью наблюдателя пересечений, возможно, выполняя поиск по каждому пакету, который вы используете? Хотя, может быть, они, возможно, даже не так называют, а как-то связано с визуализацией. Может быть, попытаться воспроизвести его, медленно перестраивая с нуля? Возможно, это облегчит поиск виновного?