Как стать автором
Обновить

Прозрачное кеширование изображений во Flash/Flex

Время на прочтение3 мин
Количество просмотров612
Вкратце — эта техника ускоряет показ множества одинаковых изображений (с одинаковым url), избавляет от повторных загрузок и экономит память. Решения из google-поиска не впечатлили, т.к. там предлагаются только самые базовые варианты без учёта частностей, к тому же их внедрение в проект не тривиально.
В данном решении достаточна замена Image на ImageCached для достижения эффекта. В конце поста ссылка на тестовое приложение, наглядно показывающее преимущество кеширования.

С чего всё начиналось:
В текущем проекте очень много работы с графикой, и столкнулся со следующей проблемой — каждый экземпляр класса Image с одинаковым URL создаёт под себя загрузчик и грузит себя (пусть даже и из кеша). Особенно хорошо это заметно при организации drag'n'drop'а картинок, когда при перетаскивании создаётся proxy картинки, картинка подгружается не сразу, и в результате заметно моргание.
Собств-но с этого полусекундного моргания и родился этот пост.

Кеш изображений, описанный в большинстве примеров, основан на том, что свойству source класса Image может быть присвоен как URL адрес, так и объект класса Bitmap (в общем случае реализатор интерфейса IDisplayObject).

Идея проста — в случае, если изображение с таким source уже было загружено — подставлять вместо URL bitmap загруженного изображения.
вариант 1:
— если в кеше нет изображения с таким url, то начать его загрузку
— иначе взять из кеша загруженный Bitmap и установить его как source
при завершении загрузки:
— установить загруженный bitmap как source
— поместить загруженный bitmap в кеш
Этот вариант вообщем был достаточен для проекта, но есть у него частность, которая при текущих мощностях сомнительна, но «не красива».
Дело в том, что при асинхроннной загрузке, 20 одновременно выводимых картинок с одинаковым (и незакешированным) URL приведут в 1ом варианте к 20 созданиям загрузчика. Посему был создан

вариант 2:
— если в кеше нет записи с таким URL, то создать её, поставить объект в очередь ожидания и начать загрузку
— если в кеше есть запись с таким URL и есть данные, то установить их как source
— если в кеше есть запись с таким URL и нет даных, поставить объект в очередь ожидания
загрузчик варианта2:
— поместить загруженный bitmap в кеш
— пройтись по ожидающим объектам, установить им загруженный bitmap как source и удалить из списка ожидания

Этот вариант корректно обрабатывает одновременную загрузку одного URL несколькими объектами, однако и у него есть частность.
Пример — форма со списком элементов и окно, в котором показывается картинка текущего элемента. При быстром проходе по списку, source у картинки может меняться быстрее чем сможет загрузиться предыдущее изображение что приводит к разсинхронизации кеша.
Решение собств-но в одну строчку
вариант3:
— если объект есть в очереди ожидания, то удалить его из очереди (загрузчик всё равно поместит в кеш предыдущую картинку, но source не будет обновлён устаревшими данными)
… далее как в варианте2…
В результате все изображения будут кешироваться, но как source установится только последнее.

Реализация:
Класс ImageCached расширяющий класс Image, с переопределением setter'а для свойства source (код ниже)

Итог:
В проекте класс Image find-and-replace'ом заменён на ImageCached и о нём забыто.
По коду сразу скажу — это мой первый проект на flash/as3/flex, аналога std:map для кеша не нашёл, буду рад критике.

Тестовое приложение — click

Создаёт два изображения, сразу после этого обменивает им source друг на друга, при движении мышки создаёт под курсором Image/ImageCached со временем жизни в 2 секунды.
Переключение между Image и ImageCached — по клику (также вызывается garbage collector)
Выводится график потребления памяти (компонент нагуглен)

Собств-но хорошо видно как скачет память и общее быстродействие при использовании Image и положительный эффект от ImageCached.

Исходники — click, ну или можно в приложении правый клик -> View Source
Теги:
Хабы:
Всего голосов 5: ↑4 и ↓1+3
Комментарии4

Публикации

Истории

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
10 – 11 октября
HR IT & Team Lead конференция «Битва за IT-таланты»
МоскваОнлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн