#angularjs #memory-management #memory-leaks #single-page-application #angular-ui-router
#angularjs #управление памятью #утечки памяти #одностраничное приложение #angular-ui-router
Вопрос:
Одностраничные приложения требуют тщательного управления событиями, элементами DOM и объектами javascript во избежание утечек.
Мы собираемся управлять утечками памяти и устранять их как можно лучше. Тем не менее, приложение большое, использует много библиотек и может оставаться открытым в течение нескольких дней.
Нам нужен предохранительный клапан.
Я ищу идеи о том, как ненавязчиво запускать обновление страницы в одностраничном приложении, чтобы принудительно освободить память.
Одна из идей состоит в том, чтобы определить, когда пользователь простаивает более N
минуты, и затем выполнить обновление, потому что это вряд ли их прервет. Большая часть состояния приложения сохраняется в URL-адресе с помощью AngularJS ui-router, так что это будет работать некоторое время.
Проблема в том, что, хотя какое-то состояние находится в маршрутизаторе, не все это будет. У пользователя могут быть несохраненные изменения или открыто какое-либо модальное или всплывающее меню, которое не находится в состоянии URL. Решением может быть обнаружение изменений пользователя и запрет обновления, если произошли какие-либо изменения, которых нет в URL. Я не вижу, как реализовать это в целом. Может быть, мы просто помещаем все, что хоть немного важно, в состояние URL.
Другая идея состоит в том, чтобы отслеживать событие изменения состояния приложения $stateChangeStart
и каждый Nth
раз выполнять фактическую навигацию браузера по этому URL-адресу вместо простого изменения состояния приложения. Это никогда не приведет к потере «вложенного состояния», но вызовет более медленный отклик на изменение страницы и мерцание экрана. Возможно, каждые 20 изменений экрана, это нормально.
У кого-нибудь есть идеи получше?
Ответ №1:
Просто идея о несохраненных изменениях и данных:
У меня есть одностраничное приложение, в котором в одном разделе есть несколько вкладок, каждая из которых содержит форму. Когда каждая форма становится «грязной», она запускает уведомление для главного контроллера и устанавливает флаг для этой формы. Когда пользователь сохраняет определенную форму, флаг сбрасывается. Если пользователь пытается перейти — перед изменением маршрута он проверяет, установлен ли какой-либо из флагов, а затем уведомляет пользователя через модальный, что какая-то конкретная информация не была сохранена. Затем пользователь может решить, следует ли продолжить изменение маршрута или вернуться назад и сохранить данные.
Это можно легко изменить, чтобы выполнить ту же проверку при обновлении страницы, и если есть несохраненные данные, либо отмените обновление страницы, либо сохраните изменения в локальном хранилище браузера для отзыва после завершения обновления страницы.
Комментарии:
1. Мне вроде как нравится идея настройки
isDirty
состояния, чтобы приложение знало, что не нужно пытаться обновить. Это потребовало бы, чтобы каждый потенциально загрязняющий компонент знал (а разработчик помнил), чтобы установить этот флаг, что имеет последствия, которые появляются только после многих минут бездействия пользователя.2. Я устанавливаю флаг только тогда, когда форма становится «грязной», наблюдая за ее
$dirty
свойством ( docs.angularjs.org/api/ng/type/form.FormController ) Я не просматриваю каждое отдельное поле, хотя это может потребоваться в вашем приложении. Вы можете автоматически сохранять любые «грязные» данные, а затем обновлять.3. О, я понимаю. Да, если бы я активно использовал формы, это было бы хорошим общесистемным местом для подключения к нему. Но есть также расширяющиеся / сворачивающиеся деревья папок, модальности в слоях, выпадающие списки и всевозможные другие пользовательские элементы управления. Возможно, это все же правильный подход. Я могу установить состояние «грязный» при любом взаимодействии пользователя с элементом управления пользовательского интерфейса.