`

Кэширование SVG-спрайта в localStorage

Автор оригинальной статьи - Osvaldas Valutis

Варианты включения SVG в HTML

Есть два варианта включения SVG в HTML с помощью тега <use>.

Вариант #1

В первом случае используется внешний файл, из которого мы можем включить SVG-графику следующим образом:

Плюсы:

  • файл sprite.svg будет закэширован браузером.

Минусы:

  • такая техника включения SVG не будет работать в IE11 и ниже (к счастью есть решение JS fallback).
  • при каждом включении придется повторять путь к файлу.

Вариант #2

Во втором случае, вся SVG-графика прописана в самом HTML-файле страницы.

Заметьте, что при определении SVG, я использую тег <symbol>, в котором я один раз устанавливаю свойство viewbox вместо того чтобы делать это при каждом включении SVG изображения. Также важно, чтобы определения графики в HTML-дереве находилось выше её включения (<use>), иначе может не сработать в некоторых браузерах.

Плюсы:

  • работает в IE9 и выше.
  • не нужно повторять путь и имя файла при каждом включении SVG-изображения.

Минусы:

  • Определения SVG-графики теперь часть HTML-документа и не кэшируется браузерами как отдельная сущность.

Что если в вашем проекте используется много SVG графики, например на 100кб? Это значит, что при каждой загрузке новой страницы, на ней будет подгружаться дополнительные 100кб данных. Представьте пользователя мобильного браузера, который переходил с одной страницы вашего сайта на другую 10 раз, он потратит дополнительный 1мб траффика, что явно не блещет производительностью.

Так можем ли мы закэшировать SVG-спрайт и в то же время избавиться от постоянных обращений к внешнему файлу при включении SVG-графики?

localStorage

localStorage дает возможность хранить данные веб-страниц в самом браузере пользователя. Ограничение хранилища обычно составляет 5мб на домен, что вполне достаточно для хранения SVG-спрайта.

Далее представляю JavaScript код, который позволяет это осуществить. И работает он следующим образом:

При первой загрузке сайта скрипт:

  1. Считывает содержание SVG-спрайта;
  2. Включает считанные данные в HTML-документ;
  3. Записывает данные в localStorage.

При каждой следующей загрузке сайта:

  1. Считывает данные из localStorage;
  2. Включает данные (SVG-графику) в HTML-документ.

Если localStorage не поддерживается браузером, выключен или переполнен, то скрипт всё равно считывает SVG-файл и включает данные в HTML-документ.

 

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

Просмотр хранящихся данных в localStorage
Просмотр хранящихся данных в localStorage

Конфигурация скрипта

В скрипте есть лишь две строки для настройки.

Я не использую SVG-спрайты с расширением .svg, вместо этого я храню его как HTML-документ. Мой svg.html обычно выглядит так:

В переменной revision вы можете менять номер версии SVG-спрайта. От нее зависит, то когда скрипт должен просканировать файл на изменения и заменить старые данные в localStorage пользователя на новые. Например, при изменении SVG-файла, вы также должны изменить значение переменной revision, чтобы изменения стали видны на сайте.

Вы можете обновлять версию вручную или автоматизировать это с помощью PHP (Python, Ruby или любого другого серверного ЯП). Если вы поместили код скрипта прямо в HTML код (который находится в PHP файле), то вы можете использовать PHP функцию, которая возвращает время изменения файла (в качестве временной метки Unix).

Если же вы сохранили скрипт в отдельном файле, например setLocalStorage.js, то можно воспользоваться глобальной переменной JavaScript.

Отсутствие поддержки SVG в браузере

Если браузер не поддерживает SVG, то мы можем рассчитывать на растровые изображения и JS fallback. Нам понадобится атрибут data-img для определения пути к изображению, например:

JS fallback сконвертирует предыдущую строку в эту:

Затем, если вы не используете html5shiv, вы должны зарегистрировать HTML теги <svg> и <use>, чтобы fallback мог работать с ними. Следующий код должен находится в начале HTML-документа, лучше до первого появления тега <script>:

В заключении нужно добавить сам код JS fallback, который должен быть помещен в конце HTML-документа (Я позаимствовал несколько строк со страницы  svg4everybody).