Хабр, привет! Меня зовут Антон, я дизайнер b2b продуктов в X5 Tech. Мне нравится моя работа и я стараюсь проектировать реализуемые интерфейсы, поэтому постоянно закапываюсь в технические нюансы.

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

Введение

Нажимая на ссылку или вводя адрес в браузере, вам, наверняка, приходилось ждать, пока браузер бездействует. За время этой паузы браузер получает с сервера только HTML‑файл и построчно обрабатывает его, скачивая указанные в нём файлы. И только по окончанию этой операции отображает страницу. Тонкостей в этом процессе много, но перепечатывать их нет смысла, всё уже описано до меня. И чем сложнее страница, и чем больше на ней контента, тем дольше придётся ждать, когда браузер отобразит страницу.

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

Тем не менее, сгладить эту ситуацию помогают загрузочные экраны, можно сказать, обманывая систему. Чтобы браузер поскорее отобразил страницу, сервер ему отдаёт максимально простой HTML‑файл, в котором расположены только загрузочный экран и какой‑нибудь JS‑скрипт, чтобы загрузить контент страницы уже после отображения страницы. Если интересно узнать детали, то предлагаю вашему вниманию вот эту статью. Что интересно, контент можно запрашивать не только одним «куском», но и частями, загружая их параллельно и отображая их по мере загрузки. И есть понятие асинхронности, то есть параллельности с основным процессом, не блокируя его.

Запросы на сервер можно делать в любой момент: во время или после загрузки страницы, автоматически или при определённых действиях пользователя, единичные или разные. Это нужно в подходах с пагинацией, кнопками «показать ещё», ленивой загрузкой или виртуализацией списков, где снова будут полезны загрузочные экраны.

Задуматься о внедрении загрузочных экранов никогда не рано и никогда не поздно. На этапе проектирования вы уже можете понимать, что у вас будут большие объёмы данных или что пользователи будут пользоваться мобильным интернетом, или вы можете сомневаться в серверной составляющей и пиковых нагрузках. В процессе разработки продукта должны быть нагрузочные тестирования. А после его запуска всегда есть возможность собрать аналитические данные. Тем не менее, лучший момент для внедрения загрузочных экранов — это этап, когда продукт только проектируется, чтобы не пришлось переписывать скрипты для подготовки к асинхронной загрузке.

Когда и где нужны загрузочные экраны

Долгая загрузка — субъективное понятие, но давайте попробуем.

Если страницы вашего продукта загружаются дольше 3-х секунд, даже периодически, то стоит задуматься о загрузочных экранах. Если вы волнуетесь, что при быстрых загрузках загрузочный экран будет появляться на доли секунды, нервируя пользователей таким мерцанием — делайте плавную анимацию появления контента — 350–500 миллисекунд для всей страницы и 250–350 для отдельных блоков вполне достаточно.

И обязательно разберитесь в причинах долгой загрузки, чтобы рационально использовать бюджет вашего продукта для оптимизации бюджета на разработку:

  • вся страница долго загружается, например, когда сервер работает на грани своих возможностей или у пользователей медленный интернет;

  • только часть страницы загружается долго, например, большие таблицы и длинные списки;

  • единичные компоненты тормозят загрузку, вроде статистики, которую каждый раз необходимо считать в реальном времени или когда есть зависимость от сторонних сервисов с низкой производительностью.

Типы загрузочных экранов

Если поискать в интернете примеры загрузочных экранов для веб‑страниц, то найдётся бесконечное количество вариаций дизайна, но они укладываются всего в три типа.

Недетерминированная загрузка

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

С точки зрения дизайна, загрузочный экран может выглядеть как угодно, главное — чтобы пользователю было понятно, что идёт загрузка. Для решения этой задачи может хватить надписи «загрузка» или зацикленной анимации, второй вариант явно лучше справляется со своей задачей. Самые популярные решения — это спиннеры, абстрактные анимации, анимированные логотипы или стилизации под скелетоны.

Технически, недетерминированный загрузочный экран — самый простой вариант, так как тут потребуется только реализовать возможность использования загрузочных экранов и сам дизайн. Внутри можно разместить всё, что угодно: нативные HTML + CSS, SVG с inline‑анимацией, Lottie или Canvas.

Детерминированная загрузка

Это всё такая же заглушка, но сложная технически. В связи особенностями реализации решение встречается редко.

Дизайн детерминированного загрузочного экрана ограничивается только его задачей — дать пользователю информацию о прогрессе загрузки. Он может быть отображён в текстовом формате в виде процентов, времени, объёма данных или любых других единиц, или графически, воспроизводя анимацию синхронно со статусом загрузки, от 0 до 100 процентов.

Этот загрузочный экран является той же заглушкой, применяемой ко всему экрану или области, но при этом самый сложный в реализации и переиспользовании. Дело в том, что нужно узнавать список файлов для конкретной загрузки, их общий объём, и каким‑то образом следить за прогрессом их загрузки, при этом управляя анимацией. Все эти процессы неудобны и трудоёмки.

Скелетон

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

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

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

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

Альтернативы загрузочным экранам

Если ваш продукт является чем‑то сложным и с очень долгой загрузкой, а вам нужен действительно уникальный опыт, то стоит обратить внимание на опыт других индустрий или пытаться хитрить. В общем, попробую задать вектор для вашей WebGL‑игры, 3D‑редактора или чего‑то ещё. Приведу свои размышления вне, так сказать, общего зачёта.

Фоновая

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

Например, пока пользователь выбирает файл из каталога с целью его отредактировать, можно загружать ресурсы редактора. Или игровую локацию во время настройки игрового персонажа.

Отвлекающая

Внимание пользователя можно отвлекать от процесса загрузки, давая доступ к чему‑то, что заинтересует пользователя. Главное — не увлекаться, чтобы процесс загрузки не стал тем, ради чего пользователь пользуется вашим продуктом.

Как пример: во время загрузки можно предлагать пользователям какую‑нибудь мини‑игру, вроде крестиков‑ноликов. Или показывать советы и хитрости по функционалу, как поштучно, так и давать доступ к целому справочнику.

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

Внедрение в дизайн

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

Обязательно обсудите свои идеи с разработчиками клиентской и, на всякий случай, серверной составляющих продукта. Обе «стороны» особенно важны, если вы хотите отображать прогресс загрузки. Разберитесь, позволяют ли бюджет и сроки сдачи продукта реализовать загрузочные экраны.

Если в основе вашего продукта не лежит современный JS‑фреймворк, то готовьтесь к тому, что не всегда есть возможность быстро и просто реализовать даже простейший загрузочный экран, и могут потребоваться значительные доработки в коде.

Не бойтесь подходить к разработчикам и задавать много глупых вопросов, просто просите рассказать вам, что и как будет работать простыми словами, уточняйте то, что не понимаете. Лучше всего провести встречу всей командой. Весьма вероятно, что такой рассказ даст вам новые, лучшие, идеи для загрузочного экрана, которые не только сделают экран эстетически более приятным, но и более удобным для разработки.

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

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

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

Выводы и сравнительная страница загрузчиков

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

Недетерменированный

Детерменированный

Скелетон

Техническая сложность

★☆☆☆☆

★★★★

★★★☆☆

Загрузка менее 2 с

★☆☆☆☆

☆☆☆☆☆

★★☆☆☆

Загрузка от 2 до 10 с

★★★★★

★☆☆☆☆

★★★★★

Загрузка превышает 10 с

★★★☆☆

★★★★★

★★★☆☆

Информативность

★☆☆☆☆
идёт загрузка страницы

★★☆☆☆
информирует о прогрессе

★★★☆☆
структура и тип контента

Фактическое ускорение загрузки

загрузка может быть оптимизирована

загрузка может быть оптимизирована

загрузка может быть оптимизирована;
контент доступен раньше, но частично;

Ощущение ускорения загрузки

зависит от дизайна

если смотреть на часы, время начинает замедляться

отвлекает изучением структуры контента

Применение на весь экран

Локальное применение

Обозначение выполнения операций

Доступность контента

ℹ️
по мере загрузки

Прочее

максимально прост для разработчиков и привычен для пользователей

позволяет оценить время загрузки или выполнения операции

создаёт ощущение более быстрой загрузки


Спасибо, что дочитали статью до конца. Очень надеюсь, что было интересно и полезно. Жду ваших комментариев и/или вопросов.

Комментарии (12)


  1. vilgeforce
    27.06.2024 10:10
    +4

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


    1. CitizenOfDreams
      27.06.2024 10:10
      +1

      Такими темпами нужно будет делать загрузочный экран для загрузочного экрана!

      Так это уже давно пройденный этап - помните вебсайты, которые встречали посетителя надписью "подождите, пока загрузится Flash-анимация"?


      1. vilgeforce
        27.06.2024 10:10

        У меня был отключен Flash. Но когда в 24-м я вижу многосекундный запуск Teams на мощной рабочей станции - я хочу посадить разрабов на тупой кол и табличку им перед глазами: "подождите, скоро вы отмучаетесь"


  1. zx80
    27.06.2024 10:10

    Ребята подскажите пожалуйста, как запретить сайтам определять моё железо (материнку и т.п.) ? Может быть есть какое-нибудь дополнение для браузера?


    1. artptr86
      27.06.2024 10:10

      Для начала давайте разберёмся как вообще сайт может определить материнку. У вас есть образец такого сайта или скрипта?


      1. randomsimplenumber
        27.06.2024 10:10

        Фингерпринтинг. Модель материнской платы нет, а уникальные особенности железа да.


        1. artptr86
          27.06.2024 10:10

          Фингерпринтинг в браузере обычно отслеживает не уникальные особенности железа (скрипт вряд ли до низкого уровня доберётся), а программную среду: браузер, операционную систему, системное время, часовой пояс и так далее. Но тут есть нюанс, что если какое-либо расширение пытается заблокировать фингерпринтинг по какому-либо параметру, то обнаружение этой блокировки — само по себе маркер пользователя, потому что такими расширениями пользуются единицы.


          1. randomsimplenumber
            27.06.2024 10:10

            Там по особенностям отрисовки шрифтов вроде как наличие GPU можно определить. Прямого доступа к железу у js нет, но коссвенно можно чего угадать.


      1. zx80
        27.06.2024 10:10

        Огромное количество сайтов занимается определением железа посетителей - это всякие Avito, Ebay, Microsoft, Google, которые любят банить подозрительных пользователей. Ну вот например, при авторизации в свой аккаунт Гугол прислал мне предупреждение о подозрительном входе:

        B85M-D3V - это модель материнки. Меня сильно удивляет, что туземцы с Хабра об этом не знают - я думал тут профессионалы веб-программирования...

        Из-за токсичных аборигенов с Хабра у меня низкая карма, поэтому я могу отвечать только не чаще 1 раза в сутки...


        1. artptr86
          27.06.2024 10:10

          А это не сайт определяет железо, а браузер Хром передаёт в Гугл сведения о системе. Если пользоваться другим браузером, то в предупреждении о подозрительном входе будет показываться только user agent.


  1. SadOcean
    27.06.2024 10:10
    +2

    Я хотел традиционно пошутить про то, что лучше бы сайты такими толстыми не делали.

    Но статья на самом деле толковая и упоминает как про это, так и про то, что есть все же случаи, когда загрузка нужна.

    Я бы добавил, что стоит разделять задачи на несколько основных категорий, условно, быстрые и медленные.
    - Обычная загрузка сайта.
    Тут как раз хорош совет в целом сделать его поменьше и пошустрее, но, очевидно, у сайта есть функции, меньше которых оптимизировать дорого.
    В этом смысле индикатор загрузки / скелетон - лишь небольшой трюк + индикатор правильности работы сайта. Поэтому ему нет смысла быть детерменированным и стараться показать время.
    - Специализированные задачи. Мы формируем важный годовой отчет, строим графики по аналитике за пол года, отправляем корабли на Марс или запускаем большую и красивую игру с 2 гб текстур.
    Эту операцию нельзя оптимизировать с нашей точки зрения, пользователю остается только ждать.
    В этом случае имеет смысл использовать детерменированные индикаторы.
    Но так же важно в этом случае по возможности отделить эту функциональность от остальной страницы.
    График грузится в рабочей области, таблица обновляет скелет таблицы - остальная часть сайта/приложения на самом деле может работать как обычно и быть отзывчивой.
    То есть помимо загрузки нужно подумать и об архитектуре и абстрагировании этой медленной части.


    1. Impossiblenickname Автор
      27.06.2024 10:10

      Спасибо за комментарий и идеи.

      Если честно, то о сайтах даже и не задумывался, в силу специфики своей работы)

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

      Про архитектуру — тут моё упущение, отдельное спасибо, что обратили на это внимание! Относительно недавно писал внутреннюю статью про скелетоны, где и раскрывал эту тему. Но постеснялся повторяться. Надо бы это исправить)