Реальный сценарий оптимизации использования данных в приложениях SwiftUI

Недавно я открыл исходный код для моей читалки HackerNews для macOS, которая полностью написана на SwiftUI для macOS. Анализ моего сценария может помочь объяснить кэширование данных и предотвращение потерь данных.

Если вы хотите получить более подробное представление о коде, вы можете следить за ним в репозитории проекта на GitHub.

Сценарий

Hacker News - это хорошо известный веб-сайт, на котором хранятся новости, сообщаемые пользователями на платформе. Каждая отдельная история будет представлена ​​структурой Item, как указано в документации HN API. Мы хотим получать доступные элементы, чтобы пользователь мог их прочитать наиболее эффективным способом.

Первоначальная реализация без использования кеша

Приложение имеет ItemCell представление , которое берет ItemId из родительского представления, и как только оно появляется на экране, оно автоматически получает элемент и покажите его мне. Такой подход делает использование данных очень низким и снимает большую нагрузку на серверную часть, потому что фактически будут извлечены только отображаемые элементы.

Боковая панель приложения позволяет пользователю перемещаться между пятью различными категориями историй. Как вы понимаете, некоторые новости потенциально могут принадлежать к нескольким категориям, поэтому, когда пользователь переключается между категориями, он в основном запрашивает те же элементы, которые были получены ранее.

Такой подход без какой-либо фоновой логики может резко увеличить использование данных, снизить общую производительность приложения, а также оказать сильное давление на бэкэнд HackerNews, который без необходимости будет предоставлять нам одну и ту же информацию несколько раз.

Кэширование данных

Что мы могли бы сделать для решения проблемы, так это кешировать загруженные элементы по их идентификаторам. Таким образом, элементы будут извлечены только один раз, и приложение не будет тратить данные на бесполезные повторяющиеся запросы к бэкэнду.

Реализация

Мы знаем, что каждый элемент уникально идентифицируется ItemId, который является целочисленной переменной. Следовательно, мы могли бы использовать эти данные для хранения и извлечения элемента из кеша.

На момент написания реализация NSCache принимает только типы классов, поэтому нам нужно создать простую оболочку класса для структуры Item, если мы хотим сохранить ее в объекте кэша. В этом сценарии нам не нужно оборачивать наш ключ (ItemId), потому что есть более короткий способ сделать это: преобразовать его в String.

Теперь сохранять и извлекать объекты довольно просто. Нам нужен объект кеширования с двумя функциями: одна для кэширования объекта, а другая для возврата объектов, если они будут найдены. Я также реализовал общий шаблон проектирования singleton, чтобы убедиться, что я всегда использую один и тот же объект кеша.

Теперь у нас есть все, что нам нужно для кэширования элементов и проверки их наличия в памяти перед его извлечением. Функция выборки будет проверять попадание / промах в кеш перед фактическим извлечением данных. Получение будет происходить только в том случае, если мы получим промах в кеше для запрошенного объекта, и когда элемент получен правильно, нам нужно только сохранить его в кеше. В следующий раз, когда мы попытаемся получить этот элемент, он будет немедленно извлечен из кеша без какой-либо дополнительной выборки.

Заключение

Оптимизация - это то, что вы всегда должны искать - как для ваших пользователей, так и для других сторонних сервисов, которые вы можете использовать в своем приложении.

С помощью очень простого объекта мы на самом деле добились довольно больших улучшений. Теперь выбранный элемент будет кэширован и готов к извлечению со стоимостью O (1) в следующий раз, когда он вам понадобится.