Сокращение времени загрузки страниц с помощью CSS.

Несмотря на всё большее распространение широкополосного доступа к Интернету, проблемы скорости загрузки HTML-страниц всё ещё не безразличны многим пользователям Сети, особенно на просторах бывшего Союза. CSS (Cascading Style Sheets) может помочь в этом деле, сэкономив нам время и трафик.

1. Избегайте использования таблиц для разметки страницы

Вот шесть причин, по которым лучше использовать CSS, а не таблицы, для разметки страниц:

  • Браузеры анализируют таблицы дважды: первый раз для того, чтобы оценить структуру таблицы, и второй - для определения их содержимого.
  • Таблицы отображаются сразу полностью, а не по мере загрузки.
  • Таблицы заставляют использовать прозрачные картинки для определения ширины колонок и т.п.
  • CSS требует гораздо меньше кода, чем перегруженные таблицы.
  • Весь CSS-код может быть вынесен во внешний файл, который будет грузиться всего один раз и храниться в кэше браузера.
  • При помощи CSS можно контролировать очерёдность загрузки элементов страницы.
2. Не используйте картинки для отображения текста

Большинство кнопок и надписей можно отобразить при помощи CSS. Взгляните на пример:

a:link.example, a:visited.example, a:active.example { color:#fff; background:#f90; font-size:1.2em; font-weight:bold; text-decoration:none; padding:0.2em; border:4px #00f outset } a:hover.example { color:#fff; background:#fa1; font-size:1.2em; font-weight:bold; text-decoration:none; padding:0.2em; border:4px #00f inset

Этот CSS определяет простую кнопку, которая меняет свой вид при наведении курсора. Таким образом можно создавать и более сложные объекты.

3. Загрузка картинок через CSS

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

И соответствующий CSS:

Pretty-image { background: url(filename.gif); width: 200px; height: 100px }

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

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

4. Использование контекстных стилей

Данный код неэффективен:

This is a sentence

This is another sentence

This is yet another sentence

This is one more sentence

.text { color: #03c; font-size:2em }

Вместо того, чтобы присваивать класс каждому параграфу, их можно сгруппировать в одном элементе DIV с тем же классом:

This is a sentence

This is another sentence

This is yet another sentence

This is one more sentence

.text p { color: #03c; font-size:2em }

Этот код указывает браузеру, что каждый параграф внутри элемента с классом text будет иметь цвет #03c и размер шрифта в 2em.

Вы могли заметить, что цвет здесь указан всего тремя символами, а не шестью. В данном случае #03c является сокращённым написанием значения цвета #0033cc.

5. Использование сокращений

Шрифт

Лучше написать:

font: 1em/1.5em bold italic serif

font-size: 1em; line-height: 1.5em; font-weight: bold; font-style: italic; font-family: serif

Границы

border: 1px black solid

border-width: 1px; border-color: black; border-style: solid

Фон

background: #fff url(image.gif) no-repeat top left

background-color: #fff; background-image: url(image.gif); background-repeat: no-repeat; background-position: top left;

Отступы и границы

Используйте:

margin: 2px 1px 3px 4px; (верх, вправо, низ, влево)

Аналогично:

margin: 5em 1em 3em; (верх, влево и вправо, низ)

margin: 5% 1%; (верх и низ, влево и вправо)

Эти правила применяются к атрибутам margin, border и padding.

6. Минимизирование пробелов, переводов строк и комментариев

Каждый символ - буква или пробел - занимают один байт. Каждый лишний символ только увеличивает размер страниц. Поэтому старайтесь поменьше нажимать Enter и Tab в процессе вёрстки. Кроме того, не забывайте объединять CSS-стили.

7. Используйте относительные ссылки

Абсолютные ссылки занимают намного больше места, чем относительные. А кроме того, создаёт дополнительную нагрузку на браузер, что более важно. Пример абсолютной ссылки: . Гораздо правильней будет написать < a href=»filename.htm»> . Но что если нужный файл находится в другом каталоге? Вот несколько примеров, которые помогут вам разобраться в этом вопросе:

8. Не увлекайтесь применением тегов META

Большинство тегов META соврешенно ненужные. Если интересно, можно взглянуть на все существующие варианты . Самые важные теги (keywords и description) используются для оптимизации поисковых машин. При использовании атрибута content в теге META старайтесь не превышать размера в 200 символов. Большие описания и множество ключевых слов могут быть восприняты поисковыми машинами как спам.

9. Выносите CSS и JavaScript в отдельные файлы

Все это знают, но не всегда пользуются. Вот так выглядит вызов CSS из внешнего файла:

И соответственно JavaScript:

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

10. Ставьте / (слэш) в конце ссылок на каталоги

Необходимо писать так.

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

Обычная загрузка CSS на сегодня …содержание…

CSS блокирует отрисовку, заставляя пользователя смотреть на белый экран до полной загрузки all-of-my-styles.css .

Обычно принято объединять весь CSS сайта в один-два ресурса, что значит, что пользователь скачивает много правил, которые не применяются к текущей странице. Это потому, что сайт включает в себя разные типы страниц со множеством «компонентов», а отдача CSS на уровне отдельных компонентов в HTTP/1 ухудшает быстродействие.

Это не проблема в случае SPDY и HTTP/2, где можно передавать много небольших ресурсов с минимальными издержками, и кешировать их независимо.

…содержание…

Это решает вопрос избыточности, но для этого вам нужно уже при выводе знать, что будет на странице, что может мешать потоковой отдаче. Кроме того, браузеру всё еще приходится загружать весь CSS до того, как он может что-либо отобразить. Медленная загрузка /site-footer.css задержит отрисовку всего .

Современный подход к загрузке CSS // https://github.com/filamentgroup/loadCSS !function(e){"use strict" var n=function(n,t,o){function i(e){return f.body?e():void setTimeout(function(){i(e)})}var d,r,a,l,f=e.document,s=f.createElement("link"),u=o||"all" return t?d=t:(r=(f.body||f.getElementsByTagName("head")).childNodes,d=r),a=f.styleSheets,s.rel="stylesheet",s.href=n,s.media="only x",i(function(){d.parentNode.insertBefore(s,t?d:d.nextSibling)}),l=function(e){for(var n=s.href,t=a.length;t--;)if(a[t].href===n)return e() setTimeout(function(){l(e)})},s.addEventListener&&s.addEventListener("load",function(){this.media=u}),s.onloadcssdefined=l,l(function(){s.media!==u&&(s.media=u)}),s} "undefined"!=typeof exports?exports.loadCSS=n:e.loadCSS=n}("undefined"!=typeof global?global:this) /* Стили для «шапки» страницы, плюс: */ .main-article, .comments, .about-me, footer { display: none; } loadCSS("/the-rest-of-the-styles.css");

В этом коде мы заготовили немножко встроенных стилей, которые дают нам быструю начальную отрисовку и скрывают те элементы, для которых у нас еще нет стилей, а остальной CSS мы потом подгружаем асинхронно с помощью JavaScript. Этот остальной CSS переопределит display: none для.main-article и т.п..

Более приближенный к жизни пример - моя оффлайновая вики , где это сработало на ура:

На 3G первая отрисовка на 0,6 секунды быстрее.
Полные результаты до и после .

Но есть и пара недостатков:

Нужна (небольшая) JavaScript-библиотека

К сожалению, это из-за реализации в WebKit. Как только добавляется на страницу, WebKit блокирует отрисовку до загрузки файла стилей, даже если его добавили скриптом.

В Firefox и IE/Edge, файлы стилей, добавленные скриптом, грузятся полностью асинхронно. Стабильная версия Chrome пока еще ведет себя как WebKit, но в Canary мы перешли на поведение Firefox/Edge.

Вы ограничены двумя фазами загрузки

В предыдущем примере встроенный CSS скрывает содержимое, у которого еще нет стилей, с помощью display:none , затем асинхронно загружаемый CSS открывает его. Если развить эту идею до двух и более CSS-файлов, они могут загружаться не по порядку, вызывая «перескоки» содержимого по ходу загрузки:

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

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

Способ проще и лучше … … … … …

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

Допустим, CSS для «шапки» сайта, статьи и «подвала» загрузился, а всё остальное только грузится, вот как тогда будет выглядеть страница:

  • «Шапка»: отобразилась
  • Статья: отобразилась
  • Комментарии: не отобразились, CSS перед ними еще не загрузился (/comment.css)
  • Раздел «обо мне»: не отобразился, CSS перед ним еще не загрузился (/comment.css)
  • «Подвал»: не отобразился, CSS перед ним еще не загрузился (/comment.css), даже несмотря на то, что его собственный CSS уже загружен

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

Нужно быть внимательными при использовании систем раскладки, где она определяется содержимым (напр. таблиц и флексбоксов), чтобы избежать «скачков» контента по ходу загрузки. Это не новая проблема, но с постепенной отрисовкой натыкаться на нее придется чаще. Можно исправить поведение флексбоксов хаками, но CSS-гриды - гораздо лучшая система для раскладки всей страницы (флексбоксы при этом великолепны для небольших компонентов).

Изменения в Chrome

Нынешнее поведение Chrome/Safari обратно совместимо, они лишь блокируют отрисовку дольше, чем нужно. С поведением Firefox всё чуточку сложнее, но есть обходной путь…

Фикс для Фокса

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

Чтобы это сработало, элемент должен не быть пустым, пробела в нем вполне достаточно.

Firefox и Edge с IE покажут вам чудесную постепенную отрисовку, тогда как Chrome и Safari будут показывать белый экран до полной загрузки всего CSS. Нынешнее поведение Chrome и Safari не хуже, чем при размещении всех стилей в , так что можно начать применять этот метод уже сейчас. В ближайшие месяцы Chrome перейдет на подход Edge, и быструю отрисовку увидит больше пользователей.

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

Все мои мысли были направлены на решение основной проблемы:

В общем случае [при использовании data:URL], загрузка страницы не ускорится, а даже может замедлиться, потому что фоновые картинки (включенные через data:URL) будут грузиться в один поток, а не в несколько при обычном использовании спрайтов. Если фоновых картинок достаточно много (несколько десятков Кб), то это окажется существенным.

Данная статья как раз посвящена тому, как можно достаточно успешно справиться с указанной проблемой. Интересно? Тогда, поехали.

Постановка задачи

При использовании data:URL итоговый CSS-файл занимает довольно большой объем (фактически, размер всех картинок*1,2...1,5 + базовый CSS). И это в виде архива. Если файл не заархивирован, то его дополнительный размер увеличивается многократно (в 2,5-3 раза относительно размера всех фоновых изображений), но это не так существенно, ибо пользователей с отключенным сжатием для CSS-файлов сейчас единицы.

Что нам, фактически, нужно? Во-первых, нужно разделить весь массив CSS-правил на относящиеся к фоновым изображениям и не относящиеся. Во-вторых, сообщить браузерам, что они могут отобразить страницу без первого массива правил (ведь если в нем содержатся только фоновые изображения, то они могут и подождать чуть-чуть).

Чего мы таким образом добиваемся? Фактически, используя такой подход, мы создаем другой контейнер для фоновых изображений (не ресурсное изображение, а CSS-файл), который удобнее использовать в большинстве случаев. Мы объединяем все фоновые картинки не через CSS Sprites, а через data:URL, и можем загрузить их все одним файлом (в котором каждая картинка будет храниться совсем отдельно). При этом избегаем любых проблем с позиционированием фона.

Теоретическое решение

Все гениальное просто, поэтому мы можем загружать в начале странице легкий-легкий CSS-файл (безо всяких фоновых изображений, только базовые стили, чтобы только отобразить страницу корректно), потом по комбинированному window.onload грузить в 2-4 потока динамические файлы стилей.

Возможные минусы: после загрузки каждого дополнительного CSS-файла будет перерисовка страницы. Если таких файлов всего 1 или 2, то отображение страницы произойдет значительно быстрее.

Почему мы не распараллелим загрузку файлов стилей в самом начале документа? Потому что два файла будут загружаться медленнее, чем один. К тому же мы ратуем за максимально быстро отображение страницы в браузере пользователя, поэтому исходный объем загружаемого CSS должен быть минимальным (можно также рассмотреть варианты по включению его в сам HTML).

На практике

На практике все оказалось не сильно сложнее. Мы загружаем в head страницы (до вызовов любых внешних файлов) наш «легкий» CSS:

А затем добавляем в комбинированный window.onload (в самое начало) создание нового файла стилей, который дополняет уже загрузившийся фоновыми изображениями:

Function combinedWindowOnload() { load_dynamic_css("background-images.css"); ... }

В результате мы имеем максимально быстрое отображение страницы, а затем стадию пост-загрузки, которая вытянет и с сервера все дополнительные картинки (тут уже сам браузер постарается), стилевые правила и скрипты.

А доступность?

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

С маленьким нюансом: noscript не может находиться в head , а link не может находиться в body . Если мы соблюдаем стандарты (все же иногда лучше довериться профессионалам и не ставить браузеры в неудобное положение, когда они встретятся с очередным отклонением от спецификации), то стоит искать обходные пути.

После небольших экспериментов с коллекцией styleSheets и другими DOM-объектами, было выделено следующее изящное решение, обеспечивающее работу схемы во всех браузерах (замечание: после многоличсленных экспериментах было решено остановиться на HTML-комментариях: они оказались наилучшим способом запретить загрузку указанного CSS-файла):

/* если мы сможем создать динамический файл стилей */ if (document.getElementsByTagName) { /* то добавляем в загрузку облегченную версию */ document.write("\x3clink href="light-light.css" rel="stylesheet" type="text/css" media="all"/>"); /* после этого начинаем HTML-комментарий */ document.write("\x3c--"); }

В результате брайзер с включенным JavaScript запишет начало комментария, а закроет его только после (комментарии не могут быть вложенными). При выключенном JavaScript не отработает, обработается и добавится в очередь загрузки, а последний комментарий будет просто комментарием.

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

Грабли, грабли, грабли...

В ходе тестирования в Internet Explorer обнаружилось, что если добавлять файл стилей сразу параллельно со скриптами (в функции, которая для него срабатывает по onreadystatechange), то IE «морозит» первоначальную отрисовку страницы (т.е. показывает белый экран), пока не получит «свеженький» файл стилей. Для него пришлось вставить фиктивную задержку следующим образом:

SetTimeout("load_dynamic_css("background-images.css")",0);

В Safari же логика отображения страницы в зависимости от загружаемых файлов отличается ото всех браузеров. Подробнее можно прочитать эту заметку о FOUC проблеме и возможных решениях . Если в двух словах, то можно жестко определить начальный набор файлов, необходимых для отображения страницы на экране (HTML/CSS/JS), а можно начать загружать все файлы в порядке приоритетности (и выполняя все их зависимости) и проверять время от времени, можно ли уже отобразить страницу (выполняя все вычисления в фоновом режиме без обновления экрана). В общем, у Safari второй подход, поэтому ничего лучше выноса загрузки динамического CSS-файла с фоновыми картинками после срабатывания window.onload (который, на самом деле, срабатывает раньше, чем во всех остальных браузерах) придумать не удалось. Зато первоначальная картинка в браузере появляется быстрее.

Итак, если брать сразу комбинированный window.onload и добавлять в него загрузку стилей, то получится примерно такая конструкция:

/* объявляем функцию по динамической загрузке стилей и скриптов первый параметр - путь к файлу, второй - тип файла К сожалению, функция объявлена глобальна */ function loadDynamic (src,type){ var node=document.createElement(type?"link":"script"); node = document.getElementsByTagName("head").appendChild(node); /* если передаем второй параметр, то это таблица стилей */ if(type){ node.setAttribute("rel","stylesheet"); node.setAttribute("media","all") } node.setAttribute("type","text/"+(type?"css":"javascript")); node.setAttribute(type?"href":"src",src) } (function(){ /* немного модифицированная версия обработчика */ function combinedWindowOnload(){ if(arguments.callee.done){return} arguments.callee.done=true; if(document.getElementsByTagName){ /* если не Safari, то загружаем CSS с фоновыми изображениями динамически */ if(!/WebKit/i.test(navigator.userAgent)){ /* для обхода IE добавляем псевдо-задержку */ setTimeout("loadDynamic("background-images.css",1)",0); } /* ставим на поток загрузку всех наших скриптов */ loadDynamic("some_scripts.js"); } } /* дальше идет стандартный кроссбраузерный код с */ ... /* навешиваем на window обработчик по событию Onload, спасибо lusever за компактный вид */ window(/*@cc_on "on"+@*/"load",function(){ /* если Safari, то загружаем наконец этот CSS */ if(/WebKit/i.test(navigator.userAgent)){ loadDynamic("background-images.css",1); } /* добавочный вызов WindowOnload для "старых" браузеров */ combinedWindowOnload() },false) })()

Выигрыш

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

Описанная техника (кроссбраузерный data:URL + динамическая загрузка файлов стилей) позволяет добиться всех преимуществ технологии CSS Sprites, не затягивая загрузку страницы. При этом обладает очевидными плюсами: не нужно лепить все картинки в один файл, можно работать с каждой совершенно отдельно, что позволяет добиться большей семантичности кода и большего удобства использования сайтов. к тому же это несколько сократит CSS-код за счет уничтожения необходимости использовать background-position .

Я пытаюсь исключить 2 файла CSS, которые блокируют рендеринг на моем сайте, - они появляются в Google Page Speed ​​Insights. Я придерживался разных методов, ни один из которых не был успешным. Но недавно я нашел сообщение о Thinking Async и когда я применил этот код: он устранил проблему.

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

4 ответов

Уловкой запуска асинхронной загрузки стилей является использование элемента и установка недопустимого значения для атрибута media (я использую media = "none", но любое значение будет делать). Когда медиа-запрос оценивается как false, браузер все равно будет загружать таблицу стилей, но он не будет ждать, пока контент будет доступен до отображения страницы.

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

Этот метод загрузки CSS будет доставлять полезный контент посетителям намного быстрее, чем стандартный подход. Критический CSS все еще может быть использован с обычным блокирующим подходом (или вы можете встроить его для максимальной производительности), а некритические стили могут быть постепенно загружены и применены позже в процессе синтаксического анализа/рендеринга.

Этот метод использует JavaScript, но вы можете обслуживать не-JavaScript-браузеры, обертывая эквивалентные блокирующие элементы в элементе :

Вы можете увидеть операцию в www.itcha.edu.sv

вы можете попробовать получить его несколькими способами:

1. Использование media="bogus" и a на ноге

2. Включение DOM по-старому

(function(){ var bsa = document.createElement("script"); bsa.type = "text/javascript"; bsa.async = true; bsa.src = "https://s3.buysellads.com/ac/bsa.js"; (document.getElementsByTagName("head")||document.getElementsByTagName("body")).appendChild(bsa); })();

3.если вы можете попробовать плагины, которые вы могли бы попробовать loadCSS

// include loadCSS here... function loadCSS(href, before, media){ ... } // load a file loadCSS("path/to/mystylesheet.css");

Будущее представляется preload keyword для link элементов.

Версия синхронизации

Версия Async

К сожалению...

Известные браузеры, которые еще не поддерживают эту функцию включают Edge и iOS Safari.

Однако...

loadCSS представляется потенциальным решением, которое позволяет вам использовать preload сегодня (с резервными копиями).

Доброго времени суток, уважаемые читатели Хабрахабра! Меня зовут Александр Шевченко, я начинающий веб-разработчик. Перейдём к делу. Анимации в CSS3 - давно не новинка. Однако, иногда можно сделать что-то простое эффектным. Сегодня мы по этому принципу создадим небольшую анимацию загрузки.

Шаг 1. Плавное появление самого экрана загрузки

Да-да. Перед тем, как приступить к основной части, мы сделаем анимацию появления самого экрана загрузки.

Body { animation: body-opacity-change 1s ease-in-out 0s 1 forwards; opacity: 0; background-color: transparent; } @keyframes body-opacity-change { from { opacity: 0; background-color: transparent; } to { opacity: 1; background-color: #1b1c2c; } }
Шаг 2. Основная часть экрана загрузки

Теперь приступаем к самому экрану загрузки. Давайте сделаем основными компонентами анимации четыре отпрыгивающих шара.

/* CSS */ div.circle { border-radius: 50%; background: #fff; width: 13px; height: 13px; display: inline-flex; align-items: center; justify-content: center; margin-top: 40%; }

Шаг 3. Применяем стили к шарам

Теперь начинается кульминация нашей небольшой работы. При помощи псевдоклассов:nth-child, :first-child и:last-child кастомизируем наши шары.
Внимание! При создании анимации к каждому шару применяйте разную длительность самой анимации дабы шары подпрыгивали в разное время с разной скоростью.

/* Первый шар */ div.circle:first-child { animation: upload 0.8s cubic-bezier(0.39, 0.56, 0.57, 1) 0s infinite alternate-reverse; background-color: #4285f4; margin-right: 6px; } /* Второй шар */ div.circle:nth-child(2) { animation: upload 1.3s cubic-bezier(0.39, 0.56, 0.57, 1) 0s infinite alternate-reverse; background-color: #34a853; margin-right: 3px; } /* Третий шар */ div.circle:nth-child(3) { animation: upload 1.1s cubic-bezier(0.39, 0.56, 0.57, 1) 0s infinite alternate-reverse; background-color: #fbbc05; margin-left: 3px; } /* Четвёртый шар */ div.circle:last-child { animation: upload 1.45s cubic-bezier(0.39, 0.56, 0.57, 1) 0s infinite alternate-reverse; background-color: #ea4335; margin-left: 6px; }
Шаг 4. Создаём ключевые кадры анимации

И таким образом, предпоследний шаг в нашем проекте - ключевые кадры анимации шаров.

@keyframes upload { from { transform: translateY(35px); } to { transform: translateY(-35px); } }
Шаг 5. Объединяем код

Последний штрих, конечно, самый банальный, однако всё же без него никак.

Экран загрузки /* Тело страницы */ body { animation: body-opacity-change 1s ease-in-out 0s 1 forwards; opacity: 0; background-color: transparent; margin: 0; } /* Шары */ div.circle { border-radius: 50%; background: #fff; width: 13px; height: 13px; display: inline-flex; align-items: center; justify-content: center; margin-top: 40%; } /* 1-ый шар */ div.circle:first-child { animation: upload 0.8s cubic-bezier(0.39, 0.56, 0.57, 1) 0s infinite alternate-reverse; background-color: #4285f4; margin-right: 6px; } /* 2-ой шар */ div.circle:nth-child(2) { animation: upload 1.3s cubic-bezier(0.39, 0.56, 0.57, 1) 0s infinite alternate-reverse; background-color: #34a853; margin-right: 3px; } /* 3-ий шар */ div.circle:nth-child(3) { animation: upload 1.1s cubic-bezier(0.39, 0.56, 0.57, 1) 0s infinite alternate-reverse; background-color: #fbbc05; margin-left: 3px; } /* 4-ый шар */ div.circle:last-child { animation: upload 1.45s cubic-bezier(0.39, 0.56, 0.57, 1) 0s infinite alternate-reverse; background-color: #ea4335; margin-left: 6px; } /*--- Кейфреймы анимаций ---*/ /*-- Загрузка страницы --*/ @keyframes body-opacity-change { from { opacity: 0; background-color: transparent; } to { opacity: 1; background-color: #1b1c2c; } } /*-- Анимация шаров --*/ @keyframes upload { from { transform: translateY(35px); } to { transform: translateY(-35px); } }
Демонстрация: код в песочнице SoloLearn
Надеюсь, что это поможет Вам при создании Вашего веб-сайта. Это был самый простой пример экрана загрузки и поэтому я советую Вам не ограничивать свою фантазию. На этом желаю Вам удачи в вёрстке и прощаюсь.