Эта статья будет интересна, кто столкнулся с разного рода проблемами после обновления Google PageSpeed и претензиям со стороны заказчиков или начальника, почему упал бал или возникло такое количество замечаний. А так же тем, кто производит оптимизацию сайтов.
В первую очередь стоит упомянуть, что вот в этой статье, на мой взгляд, всё очень грамотно и доступно расписано.

Я же от себя добавлю больше практических советов, а так же будет интересно послушать вашу точку зрения и увидеть ваши наработки.

Перечислю о чём я буду говорить в этой статье:

  1. CSS и JS
    • подключение файлов
    • загрузка библиотек
    • трюки

  2. Fonts
    • подключение шрифтов
    • отображение шрифтов во время загрузки страницы

  3. Изображения
    • разные форматы (jpg, png, webp, base64)
    • sprite

И если ты остался на этой статье до этого момента, то тебе скорее всего интересно (или у тебя заглючила кнопка «назад») Ниже подробнее о каждом пункте.

CSS и JS


JS

  1. Обязательным будет свойство async для подключаемых скриптов (кроме jQuery). Это точно избавит вас от замечания в GPSpeed по поводу асинхронной загрузки скриптов.
  2. Совет банальный, но он очень толковый — старайтесь использовать сложные и массивные библиотеки по минимуму.
  3. Свои настройки js библиотек (slick, fancybox) или небольшие фрагменты кода, которые выполняют разные задачи лучше заливать на сервер одним файлом. В моём случае, и скрипт для отправки почты, и маска для input и анимация и всё-всё находится в одном файле build.js ( которому я так же задаю async.
  4. Этот совет ситуативный, то есть под ситуацию смотрите. Если у вас сразу после открытия страницы на её первом экране выполняется какой-то скрипт, то его будет правильнее подключить отдельно и не давать ему async

CSS

  1. Тут немного посложнее. К тегу link вам необходимо будет добавить такое свойство

    <link media="none" onload="if(media!="all") media="all"" rel="stylesheet" type="text/css", href= main.css>

    Именно в таком виде ваши css файлы будут подключаться лишь после дерева DOM. Грубо говоря, это тот же async только для .css
  2. Очень важный и действенный совет! Он добавляет от 5 до 10 баллов гарантированно. Нужно разделить ваш main.css на два файла. В первом будут только те стили, которые подгружаются для того контента, который виден сразу после открытия страницы. Это top bar, header, первая картинка, первая form и тд. В общем то, что вы поместили на «лицо» вашего сайта. Во втором уже всё остальное.

Шрифты


Я обнаружил новое для себя css свойство для шрифтов

font-display

А конкретно, его параметр swap, который не дожидаясь подгрузки вашего красивого и тяжёлого шрифта показывает текст в браузере используя встроенный в этот же браузер шрифт (например sans-serif). Это сразу же убирает одну из ошибок в GPSpeed.

Выглядеть это будет так

 @font-face {
    font-family: 'FontName';
    src: local('FontName'), url('FontName.woff') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
    }

Так же есть такой скрипт (для его работы нужно подключить fontfaceobserver.js):

<script>
    var html = document.documentElement;

    if (sessionStorage.fontsLoaded) {
    html.classList.add("fonts-loaded");
    } else {
    var script = document.createElement("script");
    script.src = "../js/fontfaceobserver.js";
    script.async = true;
    script.onload = function() {
      var regular = new FontFaceObserver("FontName");
      var bold = new FontFaceObserver("FontName", {
        weight: "bold"
      });
      var light = new FontFaceObserver("FontName", {
        weight: "300"
      });
      Promise.all([
        regular.load(),
        bold.load(),
        light.load()
      ]).then(function() {
        html.classList.add("fonts-loaded");
        sessionStorage.fontsLoaded = true;
      });
    };
    document.head.appendChild(script);
    }
    </script>

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

Подключение шрифтов


  1. В основном встречаются два вида подключения — с помощью ссылки (например на google fonts, или же локально, на сервере. Так вот, по поводу второго способа, его так же можно поделить на 2: отдельным css файлом (с помощью link подключаем fonts.css) и напрямую через код (через ваш style.css).
    И поскольку сейчас мы ведём речь именно об оптимизации сайта для GPSpeed, то я убедился в том, что лучше подключаться шрифты через ваш главный файл css.
  2. И ещё один совет, который помогает — положите файлы со шрифтами (woff, ttf и тд) рядом с вашим файлом css, который его запрашивает. Раньше у меня была отдельная папка на сервере для шрифтов, но потом я переместил их скорость загрузки шрифтов увеличилась в 2 раза. (по данным GPSpeed на подключение шрифта Muller раньше у меня уходило 180ms, сейчас 70-90ms)

Изображения, картинки и т.д.


За следующие 2 совету ручаюсь, помогли не только мне, а всему офису и даже друзьям отдалённо работающим.

1. Загружайте абсолютно все картинки <img> с помощью lazyloading. Выглядеть это будет так


<img class="yourClass lazy" data-src="../images/image.jpg" alt="Описание"/>

И не забудьте подключить lazyload.min.js

2. Если у вас на странице много svg элементов, то их лучше добавлять чистым кодом, без лишнего обращения к тегу img. Кроме того, svg необходимо ужимать, например, с помощью этого сайта jakearchibald.github.io/svgomg (не реклама).

3. Банально, но не забывайте ужимать ВСЕ картинки на сайте. Даже те, которые весят 5кб. Хоть эти 3 кб которые вы выиграйте никак не повлияют на скорость загрузки, вы избавитесь от ошибки на GPSpeed, и добавите себе до 10 баллов.

!Теперь проблемный момент — форматы изображений. А именно нас волнует webp, JPEG 2000, JPEG XR. Ведь сейчас это один из рекомендуемых GPSpeed-ом шрифтов. Как известно, они до сих пор не поддерживается некоторыми браузерами, среди которых достаточно популярный Mozila Firefox. Хоть они и объявили, что в марте будет полная поддержка этого формата, нам всё-равно ещё год ждать, пока все юзеры этого браузера обновятся до последней версии… Я перерыл кучу сайтов, кучу скриптов, но толкового ничего не нашёл. По этому теперь настало моё время задать вопрос вам: используете ли вы формат webp или любые другие новые форматы изображений? И как вы это делаете?

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


  1. tuxi
    21.01.2019 18:07

    используете ли вы формат webp или любые другие новые форматы изображений? И как вы это делаете?
    Да используем. Написали свой API и сервис для перекодировки ( с кешем, с валидацией, с ресайзингом и прочими фишками).
    Я все никак статью не могу закончить для Хабра. У меня есть реальные статистические данные, основанные на выборке размером в 2 млн изображений и с разной степенью сжатия.
    Для того чтобы в GooglePage Speed получить за изображения хороший бонус, нужно именно webp ему давать. Порядка 10 баллов в среднем дается за это.


    1. BigDflz
      22.01.2019 19:33

      сделал кадрирование-поворот-ресайзинг github.com/JonHappy/JonHappy.github.io, сохраняет в jpg, но простая смена на webp — сохранит в webp, и можно сделать оба формата. интересуют отзывы/рекомендации.


      1. tuxi
        22.01.2019 20:47

        Мы тоже crop по белому фону сделали :)


    1. Spawnet Автор
      22.01.2019 12:39

      С нетерпением жду от Вас статью на эту тему! Не хочется ждать ещё целый год обновления пользователей Mozilla Firefox.
      (если статья ещё не скоро будет, то буду крайне признателен, если в личку дадите необходимую информацию или же её крупицы)


  1. lemproix
    21.01.2019 18:38

    Вроде для Апача есть модуль "mod_pagespeed" который умеет перекодировать часто запрашиваемые изображение в webp, если клиент поддерживает данный формат


    1. Spawnet Автор
      22.01.2019 12:48

      Сложно)) Лучше бы всё в ручную делать, локально. Это лично моё предпочтение.


    1. zikkuratvk
      23.01.2019 17:59

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


  1. Sovigod
    21.01.2019 18:44
    +1

    Для webP используем pagespeed для nginx. Найти легко. Базовая настройка в 3 строки. webP будет отдаваться только тем браузерам которые умеют его показывать, остальные получат исходный формат. И делаем мы так уже года 2.


    1. Spawnet Автор
      22.01.2019 11:34

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


  1. keslo
    21.01.2019 18:45

    del


    1. Spawnet Автор
      22.01.2019 12:49

      Это к чему комментарий?


  1. keslo
    21.01.2019 18:46

    Спасибо за советы.
    Часто приходится встречаться с подгрузкой JS с cdn.js. Видимо нужно в bundle собирать такие вещи.


    1. Spawnet Автор
      22.01.2019 12:49

      Пожалуйста. Надеюсь что и правда помог.


  1. ddidwyll
    21.01.2019 19:06

    Сейчас проверил, действительно упал с 100/100 до 99/100 для пет-проекта, беда.


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


    1. Spawnet Автор
      22.01.2019 11:36

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


  1. galaxy
    22.01.2019 19:52
    +2

    И ещё один совет, который помогает — положите файлы со шрифтами (woff, ttf и тд) рядом с вашим файлом css, который его запрашивает. Раньше у меня была отдельная папка на сервере для шрифтов, но потом я переместил их скорость загрузки шрифтов увеличилась в 2 раза

    Чего, блин??


    1. Spawnet Автор
      22.01.2019 11:46

      Мне казалось, что я достаточно понятно всё объяснил. Постараюсь ещё раз. Вот здесь my-files.ru/sfw6dd вы можете видеть, что до файлов со шрифтами есть путь, который занимает хоть и не весомые 160ms, но всё-таки мы можем сократить его вдвое. А сделать это можно просто переместив
      эти файлы (шрифты) рядом с вашим main.css или style.css. Тогда время подгрузки будет от 70 до 90ms.


      1. dumistoklus
        22.01.2019 16:36

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


        1. 4tlen
          24.01.2019 17:03

          Все знают что каждый слэш в адресе добавляет 50-70мс!


      1. mvs
        23.01.2019 18:34

        Покажите, пожалуйста, заголовки сервера при отдаче /css/header.css и /css/MullerLight.woff


  1. Max2UP
    21.01.2019 23:05

    используете ли вы формат webp или любые другие новые форматы изображений?
    используем. Файлы генерируются для всех версий(на сервер cwebp, локально gulp с imagemin-webp), а дальше — либо используется тэг picture(идеальный случай) либо правило в nginx/.htaccess которое подставляет файлы в новом формате, если браузер его поддерживает.

    На скорость загрузки страницы это конечно катострафически влияет даже визуально.


    1. JoyLink
      22.01.2019 03:26

      Можете поделится правилом для nginx? У меня так и не вышло насьроить (


      1. Max2UP
        22.01.2019 03:30

        map $http_accept $webp_suffix {
                default   "";
                "~*webp"  ".webp";
        }
         
        server {   
            location ~* ^/.+\.(png|jpg|jpeg)$ {
              access_log off; expires max;
              try_files $uri$webp_suffix $uri =404;
            }
        }
        


        А вот так примерно на сервере можно преобразовывать.
        find $i -name "*.j*g" | parallel -eta cwebp -preset photo -q 90 {} -o {}.webp
        


    1. Spawnet Автор
      22.01.2019 11:52

      Я знаю про picture, но что-то у меня не получилось. Я здесь же на Хабре нашёл статью, попробовал сделать тоже самое, но не вышло.
      habr.com/ru/post/237991

      <picture>
              <source srcset="images/400.webp" type="image/webp">
              <img src="images/400.jpg"
                width="400" height="300" 
              >
            </picture>


      Вы как-то по другому это делаете?


    1. Spawnet Автор
      22.01.2019 12:54

      И ещё, .htaccess. У Вас получилось всё сделать так, что бы работало? У нас не очень.


  1. tuxi
    21.01.2019 23:33

    Выложил для общего доступа урезанную версию нашего сервиса.

    http://webputil.com:8080/api/v1/service/webp/create

    данные передаются в заголовках запроса (по ряду причин так было удобнее для этого примера)

    X-IMAGE-TOKEN: "85bc92d82651affe7c905d1634751b87" - через пару дней станет невалидным
    X-IMAGE-SOURCE: ссылка на jpg ресурс, должна иметь расширение .jpg или .jpeg, get параметры игнорируются
    X-IMAGE-WIDTH: желаемая ширина
    X-IMAGE-HEIGHT: желаемая высота (можно передать 0 если будем только по ширине ресайзить)
    X-IMAGE-QUALITY: от 0 до 100, целое число
    X-IMAGE-CACHE-EXPIRY: 1s(econd), 1m(inute), 1h(our), 1d(ay) - время кеширования результата

    в ответе помимо тела ответа, есть два заголовка
    X-IMAGE-CACHE: HIT
    X-IMAGE-URL: ссылка на закешированный результат

    За последствия «хабраэффекта» снимаю с себя всякую ответственность :), там небольшая одноядерная vps


  1. servekon
    22.01.2019 10:57

    Lazyload совершенно не совместим с использованием навигации по тексту с помощью ссылок-якорей(#Элемент), потому-что нет возможности сразу всем картинкам задать их высоту. Есть решения данного вопроса?


    1. Spawnet Автор
      22.01.2019 12:45

      Да, есть решения:
      1) Определить какие именно картинки двигают контент по мере подгрузки и дать их родителям фиксированную ширину. Этим вы полностью избавите от этих скачков.
      Плюсы — скорость решения, гарантия избавления себя от этой проблемы.
      Минусы — адаптив, ведь придётся убирать фиксированные размеры. И это может быть не очень грамотно, но мы сейчас ведё речь об оптимизации, а не красоте вёрстки.
      2) Изначально делать дизайн и вёрстку так, что бы картинки не были главными в определении размера блока. Пусть либо текст, либо какой-нибудь другой контент будет больше картинки в блоке.
      3) Использование sprite. Там ведь изначально есть заданная ширина и высота, потому что там не картинка как img, а background.


  1. youloveazamat
    22.01.2019 12:02

    По поводу шрифтов, попробуйте еще


     <link rel="preload" href="путь до файла" as="font" type="font/woff2" crossorigin="anonymous" />

    Но чистый svg не всегда подходит, а именно для иконок. С этим БЭМ ничего нельзя нормально инлайново подключать


    1. Spawnet Автор
      22.01.2019 12:47

      Спасибо за совет. Но здесь сработает только для тех, кто подключает шрифты отдельным файлом, например, fonts.css. А я предпочитаю подключать их напрямую чистым кодом в main.css. Но я обязательно проверю Ваш способ, может так будет даже лучше.


      1. youloveazamat
        22.01.2019 12:59

        Мы делаем так, но делаем только для одного(основного) шрифта с кеглем обычно 400. И загрузка идет уже не после загрузки html, а вместе с ней


  1. KonstantinGreat
    22.01.2019 14:31

    добавил бы к статье (must have) использовать:

    кеширование (настройки nginx для всех типов шрифтов, скриптов, картинок и других типов файлов)
    gzip сжатие
    перенос скриптов в footer (конечно минификация и возможно канкатинация, но тут надо смотреть, как вот автор советует — основное отображение в один файл и портянки в другой)
    скрипты карт вешать на действия пользователей или с максимально допустимой отложенностью
    var script = document.createElement('script');
                script.type = 'text/javascript';
                script.src = 'https://api-maps.yandex.ru/2.1/?lang=ru_RU';
                document.body.appendChild(script);
    

    лучше чем async, а timeout на определенное время вообщем может убрать учет скрипта из google анализа

    – svg вместо спрайтов (визуально точно лучше)


    1. Spawnet Автор
      22.01.2019 14:36

      1) Кеширование, Gzip, правильное расположение скриптов это даже упоминать не надо, давно уже должно быть у всех по дефолту)). Но лишний раз можно напомнить, для совсем новичков.
      2) Карты да, тут можно либо подключать её по кнопке, например, вообще делать отдельной страницей (на сам Яндекс или Google).
      3) Sprite я использую не только для иконок, а даже для картинок размером до 200кб. Когда их много в одной секции и на них нету никакого функционала (например в секции положительных сторон компании, где обычный текст, и картинка для красоты, но она 400px d ширину). В результате мы убрали лишние запросы на сервер, и одна большая картинка будет меньше весить, чем те по отдельности.


  1. sinneren
    22.01.2019 16:46

    Кажется, у вас опечатки в коде про тег link.


  1. demimurych
    22.01.2019 20:32

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

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

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

    Далее по советам.
    Атрибут async — имеет смысл только в том случае, если скрипты по каким-то причинам расположены в head документа. Если скрипты расположены в footer то async бесполезен чуть более чем полностью.

    Реплика
    async для подключаемых скриптов (кроме jQuery)
    говорит как раз о том, что автор до конца не понимает как это работает.

    Если Ваши скрипты висят в footer то атрибут async ничем Вам уже не поможет.

    И ещё один совет, который помогает — положите файлы со шрифтами (woff, ttf и тд) рядом с вашим файлом css, который его запрашивает.

    Это ничему не помогает.
    Если у Вас вышло по другому, то тут проблема совсем не в области оптимизации, а в плоскости неадекватности работы Вашей системы. Может что-то с кешированием, может что-то с диском что привело к задержке, может с дефрагментацией.

    И не забудьте подключить lazyload.min.js

    который из пары десятков? и почему нужно брать именно этот? А как это повлияет на индексирование этих изображений?

    О webp.
    Уже очень давно для всех типичных популярных серверов есть конфигурации, когда в случае если браузер передает заголовок о поддержке webp, то именно это формат ему и отдается. И так делать нужно.

    Конечно, очень хотелось бы все делать «по уму», и размечать изображения через picture с разными source, а не морочить себе голову с конфигурацией веб сервера. Но если Вы, действительно занимаетесь оптимизацией, то боритесь в том числе и за сложность DOM дерева. А лишний source это лишний узел.

    Аналогично, совет с инлайном SVG. Однозначно рекомендовать встраивать SVG инлайн может только человек, который не понимает, что такой трюк, помимо того что сокращает количество запросов еще и раздувает дом дерево. И делать такое нужно лишь в случае, если есть необходимо манипулировать таким svg, или издержки на дополнительный запрос, перекрывают издержки на дополнительную память инлайнового svg.
    Во всех прочих случаях нужно взвешивать все за и против — есть запас по узлам, можно и инлайн, нет — только внешний src.


    1. Spawnet Автор
      23.01.2019 13:33

      Спасибо за критику и комментарий. Я внимательно прочитал и с частью из сказанного Вами согласен. Но Вы, видимо, не поняли мой главный посыл статьи. Я там прямо указал, что это оптимизация сайта для GooglePage Speed (PageSpeed Insights — Google Developers, называйте как хотите, главное что бы мы понимали о чём речь). Я НЕ говорил, что это самые грамотные, самые толковые советы для оптимизации сайта по самым лучшим решениям 2019 года, и которые спасут и Вашу вёрстку и сайт. Нет. Я лишь увидел, что после обновления GPSpeed сайт, который имел 90/100 получил оценку в 63/86 баллов. И после того как я применил всё сказанное в моей статье к этому сайту, то вернул на компьютере стабильно 100, а на телефоне колеблется от 86 до 93 (видимо зависит ещё от скорости и загруженности сервера и собственно компьютера и сети в момент проверки).
      Вы спросите почему я так топлю за эти баллы, так это просто требование руководства))


      1. BigDflz
        23.01.2019 13:46

        вот тут бы услышать мнения по пунктам разногласия — требования руководства — это одно, а реальное улучшение это другое,
        вот только без перехода на личности. просто мнения и аргументы
        что б было что выбирать, а не методом научного тыка.
        (сомнения в GooglePage Speed есть давно, но только на уровне интуиции… )


        1. Spawnet Автор
          23.01.2019 17:58

          Чистая работа и теория с практикой. Никаких обид и перехода на личности)
          Читая мой ответ всё время держите в голове, что я делал оптимизацию ИСКЛЮЧИТЕЛЬНО для GP Speed (дальше GPS).
          И внизу ещё есть комментарий, на который я дал развёрнутый ответ, может там будет что-то для Вас тоже интересно.
          В первую очередь приведу пример двух сайтов. В первом ничего из моих советов не применено, во втором все пункты выполнены. drive.google.com/open?id=1EcFVkhNQki8J2ZGwKxPyMu-U_3TfJdVS; drive.google.com/open?id=1iUctTHwwbw80vK6Z-stKVvVJDpFrwFnL
          1) async — он необходим для того, что бы отработать замечание из GPS которое звучит так: «Сократите время выполнения кода JavaScript», а так же «Минимизируйте работу в основном потоке».
          2) Шрифты будут хоть на незначительное время, но быстрее загружаться. Как и говорил, вместе 180ms у меня сейчас 70-90ms.
          3) В DOM структуре сайта остаётся и тег img и alt описание, и title. Вы просто не подгружаете её пока не видите. Робот поисковика всё-равно её увидит. (я не разработчик поисковиков, но думаю что это так). Потому что я в google картинка и Яндекса есть наши картинки, если сузить поиск, хотя бы прописав её alt или ссылку на сайт.
          Почему именно этот, потому что он проверенный мною и у меня ни разу не было с ним проблем.
          4) По поводу webp, нам пришлось отключить pagespeed на нашем сервере, не смотря на то, что он все картинки преобразовывал в webp из-за того, что по сухим цифрам на GPS скорость при включенном pagespeed на 10 баллов меньше. И так было со всеми сайтами. От 10 до 5 баллов плюс после отключения.
          5) Опять-таки, увеличение структуры DOM из-за 50 лишних узлов плохо не повлияет на скорость загрузки страницы и на оценку в GPS. А вот 5 лишних svg иконок могут попасть в раздел «Оптимизация, и там будут просить их отложить, скрыть, использовать формат нужны и тд. Как только я начал на сайте все svg переводить в код, то ни разу больше не было рекомендаций от GPS по этому поводу.


  1. m11z
    23.01.2019 13:09

    Много ньюансов, альтернативных способов, предостережений и объяснений
    JS
    1. Обязательным будет свойство async для подключаемых скриптов (кроме jQuery). Это точно избавит вас от замечания в GPSpeed по поводу асинхронной загрузки скриптов.

    1.1. Данная рекомендация не обязательна, используйте на свой страх и риск, устанавливая флаги с async вы должны точно знать логику работы js на данной странице.

    1.2. Если у вас есть инлайн скрипты которые используют что-то из js файла с async флагом все сломается т.к. на время чтения DOM данный файл не загружен/прочитан, это же касается и js файлов которые грузятся без async флага.

    1.3. Все js файлы c async флагом грузятся в том же порядке в котором были спарсены в html.

    1.4. Все js файлы которые были вставлены как инекция в html(то как вставляют счетчики гугл аналитикс, например) будут загружены в том же порядке что и объявлены в html(они асинхронны по умолчанию).

    1.5. В старых браузерах defer используется как фалбэк для async. Defer “отодвигает” событие DOMContentLoaded пока все файлы с данным флагом не будут прочитаны.

    1.6. Уже стандарт хранить ресурсы js/css в футере.

    2. Совет банальный, но он очень толковый — старайтесь использовать сложные и массивные библиотеки по минимуму.

    2.1. Если все же вынуждены и данные скрипты используются на большинстве страниц, положите их все в отдельный файл даже если в итоге он будет 100кб. Файл кэшируется что в долгосрочной перспективе(путешествие пользователя по сайту) выгодно.

    2.2. Старайтесь не использовать jquery библиотеки если есть аналогичные на чистом js.

    2.3. Важно: Основная проблема «сложных и массивных библиотек» это цена парса/компиляции кода, 1кб js не равен 1кб картинки (в плане скорости загрузки/интерактивности сайта). Прежде чем ваш js код выполнится браузер делает очень много работы на ним и чем раньше он это закончит тем быстрее приложение станет интерактивно (главный поток станет idle). Поэтому 100кб jquery в разы медленней чем 100кб чистого js который в свою очередь в разы медленней чем обработка 100кб картинки.

    3. Свои настройки js библиотек (slick, fancybox) или небольшие фрагменты кода, которые выполняют разные задачи лучше заливать на сервер одним файлом. В моём случае, и скрипт для отправки почты, и маска для input и анимация и всё-всё находится в одном файле build.js ( которому я так же задаю async.

    3.1. Страница должна грузить только тот js который необходим на данной странице, ничего лишнего (логика которая используется на другой странице, не нужна).

    3.2. Практически идеальный вариант для боевых условий это AMD подход и CommonJS в частности (если говорим о front-end).

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

    Простите, не понял о чем вы, что за скрипт на первом экране?

    CSS
    1. Тут немного посложнее. К тегу link вам необходимо будет добавить такое свойство
    <link media="none" onload="if(media!="all") media="all"" rel="stylesheet" type="text/css", href= main.css>

    Именно в таком виде ваши css файлы будут подключаться лишь после дерева DOM. Грубо говоря, это тот же async только для .css

    Не советую так делать (это даже не костыль, а подпорка какая-то).

    1.1. После каждого обновление CSSOM будет происходит отрисовка страницы, в данном случае страница ПОЛНОСТЬЮ отрисуется еще раз после того как media сменится.

    1.2. Если у вас больше 1го css на странице вы не сможете сделать нормальную стратегию загрузки.

    1.3. Сам гугл рекомендует LoadCSS.js (https://github.com/filamentgroup/loadCSS)

    1.4. На самом деле стили загрузятся последними (onload событие) а не «после древа DOM» (DOMContentLoaded событие)

    2. Очень важный и действенный совет! Он добавляет от 5 до 10 баллов гарантированно. Нужно разделить ваш main.css на два файла. В первом будут только те стили, которые подгружаются для того контента, который виден сразу после открытия страницы. Это top bar, header, первая картинка, первая form и тд. В общем то, что вы поместили на «лицо» вашего сайта. Во втором уже всё остальное.

    Не совсем понял о чем тут речь, если речь о критическом css то стоит обратить внимание на следующее:

    2.1. Если пользователь нажал обновить страницу находясь в нижней части сайта (если длина сайта 4 экрана, например) браузер может восстановить позицию скролла на 3ем экране на котором все будет развалено т.к. критический css уже применен и страница отрисована но еще не применены стили для всей страницы (браузер всегда старается как можно раньше хоть что-то отрисовать).

    2.2. Такой метод подходит очень, очень узкому типу сайтов, по моему опыту только лэндингам, сайтам визиткам и всем сайтам которые по PWA патерну сделаны.

    Шрифты
    Я обнаружил новое для себя css свойство для шрифтов

    font-display

    А конкретно, его параметр swap, который не дожидаясь подгрузки вашего красивого и тяжёлого шрифта показывает текст в браузере используя встроенный в этот же браузер шрифт (например sans-serif). Это сразу же убирает одну из ошибок в GPSpeed.

    1. font-display canIuse 25% global. На нее полагаться нельзя.

    2. Сайт который 2 раза рендерит шрифт? Это звучит как антисовет.

    3. Sans-serif это не шрифт, это тип гарнитуры, фактически это значит «гарнитура без засечек». Но какой шрифт именно там будет вы не знаете, что скорей всего приведет к сильному «дерганью» при рендере страницы.

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

    5. Рекомендую dns-prefetch и prefetch в частности. Подробнее можно почитать Robin Rendle (https://css-tricks.com/prefetching-preloading-prebrowsing/).

    Подключение шрифтов
    1. В основном встречаются два вида подключения — с помощью ссылки (например на google fonts, или же локально, на сервере. Так вот, по поводу второго способа, его так же можно поделить на 2: отдельным css файлом (с помощью link подключаем fonts.css) и напрямую через код (через ваш style.css).
    И поскольку сейчас мы ведём речь именно об оптимизации сайта для GPSpeed, то я убедился в том, что лучше подключаться шрифты через ваш главный файл css.

    1.1. Тут можно быть и более настойчивым. Шрифты ВСЕГДА должны грузится с того же сервера с которого и css. Путь должен быть относительный без абсолютных ссылок.

    2. И ещё один совет, который помогает — положите файлы со шрифтами (woff, ttf и тд) рядом с вашим файлом css, который его запрашивает. Раньше у меня была отдельная папка на сервере для шрифтов, но потом я переместил их скорость загрузки шрифтов увеличилась в 2 раза. (по данным GPSpeed на подключение шрифта Muller раньше у меня уходило 180ms, сейчас 70-90ms)

    Вы уверены?

    Изображения, картинки и т.д.

    За следующие 2 совету ручаюсь, помогли не только мне, а всему офису и даже друзьям отдалённо работающим.

    1. Загружайте абсолютно все картинки с помощью lazyloading. Выглядеть это будет так


    И не забудьте подключить lazyload.min.js

    Лично я рекомендую lazysizes.js

    2. Если у вас на странице много svg элементов, то их лучше добавлять чистым кодом, без лишнего обращения к тегу img. Кроме того, svg необходимо ужимать, например, с помощью этого сайта jakearchibald.github.io/svgomg (не реклама).

    2.1. Если у вас на сайте много svg элементов и это иконки — используйте svg inline sprites подход, он наиболее выгоден.

    2.2. Если у вас на сайте много svg элементов и это картинки — используйте их как img src, так они хотя бы кэшируются.


    1. Spawnet Автор
      23.01.2019 13:59

      Спасибо за критику и комментарий. Я выше уже ответил человеку на развёрнутую критику, прочитайте мой ответ. Он по сути и Вас тоже касается.

      Но Вам я немного дополню по пунктам.
      1) JS. Я там одним предложением, которое вы не поняли (Простите, не понял о чем вы, что за скрипт на первом экране?) и имел ввиду то, что Вы описали 6-ю пунктами) Просто вы более обширно обозначили что нужно добавлять async на свой риск и учитывать выполнение скрипта в разных время и в разных местах.
      А по поводу первого экрана — просто пример клиент хочет пустить зимой снег на СТАРТОВЫЙ экран, прям на header. Так вот этому скрипту можно и не задавать async, как вы и сказали. Но если он захочет его пустить где-нибудь в середине или в конце, то ОБЯЗАТЕЛЬНО нужно ему дать async.
      GTM я думаю всё и так знают что работает стабильно и загружается асинх. по этому я не упоминал это.
      Во 2-3 пункте js прям хорошие толковые советы, я их даже допишу в статью, если буду делат «часть 2, с Вашего позволения. Но мы с Вами и так понимаем, что это достаточно банальные вещи. Я же это делаю для совсем новичков.

      2) CSS
      1.1 А с чего вы это взяли? Я и на localhost и на сервере проверил в самхы разных разрешениях весь сайт. Ничего ни разу не подгружалось и не перерисовывалось. Всё согласно УЖЕ ЗАРАНЕЕ подгруженным media запросом становилось на свои места. По этому это замечание не имеет место быть.
      1.2 Тут я же не понял. В чём проблема и по очереди загружать. У меня ещё не встречалось такого, что бы целый файл css не нужен был с самого начала. Это что же за элемент или случай такой, ради которого нужен отдельный css, который нужно подгружать позже… в общем не понятно. Страница загрузилась и весь css загрузился по очереди, точка.
      1.3 LoadCSS.js протестирую. Пока не работал с этим.
      2.1-2.2 Совершенно верно. Я показывал это руководству, это не проблема. У нас лендинги, по этому перезагрузка страницы у нас вообще не производится. Разве что пользователь сам её сделает. И всё скачен, но благо это длится 1-4 секунды. Не красиво, но таково требование. По этому сначала стартовый экран, а потом уже main.css. И да, мне нужно было об этом упомянуть в статье, о скачках.

      ШРИФТЫ
      1-4 font-display ну и что, что он 25%. Прописать то всё-равно нужно и дальше продолжать оптимизировать этот аспект. Пусть себе висит в @ font
      -face и помогает где может, он ничего не нарушит. И пока грузится страница используется ВСТРОЕННЫЙ в браузер шрифт и ничего второго не рендерится. Он ообще не на сервере находится, нечему рендерится. И даже если там что-то при каждом открытии любого сайта рендерится (arial, robots, sans-serif и тд), то это даже не заметно, там милисекунда и готово. тут дело вкуса — во время подгрузки шрифта пустое место или отображение текста хоть как-то. И напомню, что это отдельное замечание в GPSpeed, для которого эта статья и предназначалась.
      5 Это тоже протестирую.
      Подключение шрифтов. 2 Вы быстрее пробежите 40 метров или 200? А зачем тогда заставлять main.css бегать в лишнюю папку, и там искать файлы? Пусть они сразу будут вплотную друг к другу. И да, по цифрам я уверен, лично проверил. Хоть это и милисекунды, но так ведь и добивается оптимизация, по крупицам.

      ИЗОБРАЖЕНИЯ
      1 — 2.1 lazysizes.js — не работал с этим, протестирую.