Актуальный релиз „DataLife Engine 21.0 Final“ buildid 107

подробнее о релизе

Главная страница / Блог / Разное / Google PageSpeed Insights

Google PageSpeed Insights

19 сентября 2020 | 15:22 | Суббота
6 889
6
[ Рейтинг: 1.5 / Голосов: 17 ]

Содержание:

Google PageSpeed Insights


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

Первое что нужно сделать — это оптимизация изображений. Сделать это можно:


Потом можно выполнить сжатие CSS/JS файлов, например, плагином DLE-ASSET
Следующим этапом можно выполнить сжатие HTML кода страницы — плагин тут.
Ну так же не стоит забывать об отложенной загрузки изображений, в ДЛЕ с 13-й версии lazyload.js включен в дистрибутив CMS.
Отложенная загрузка некоторых скриптов, например, яндекс.метрики.

Чаще всего данных действий вполне достаточно, чтобы показатель по гуглспид был выше 50-60 для мобильной версии, а для ПК версии может быть 80-90+.

Но иногда можно и подтянуть показатели ещё и другими способами. Более подробно о них сейчас и напишу.

  1. ↑ Асинхронная загрузка JS (относится к разделу «Минимизируйте работу в основном потоке»)


    Здесь всё предельно просто — нужно добавить к скриптам async или defer, чтобы было, например, так:
    <script async src="/libs.js"></script>

    Асинхронную загрузку скриптов нельзя ставить на JQuery скрипты, на остальные скрипты можно это использовать, но всегда главное проверять работу скриптов после установки асинхронной загрузки, поскольку часто некоторые скрипты отказывают работать в таком режиме.
  2. ↑ Асинхронная загрузка CSS (так же относится к разделу «Минимизируйте работу в основном потоке»)


    Здесь немного посложнее чем со скриптами… Но выход есть, и один из вариантов должен сработать.

    Ранее я делал критический код стилей и выводил их непосредственно в коде шаблона, но, согласитесь, — это не всегда удобно, даже если делать это через {include… Поэтому продолжил поиски и тестирую их в данный момент на некоторых сайтах, в том числе и на данном блоге!
  3. ↑ Подключение шрифтов из CSS в main.tpl


    <style>
    @font-face {
    	font-family:'FontAwesome';
    	src:url('/uploads/mini/noimage.jpg#123;THEME}/fonts/fontawesome-webfont.eot');
    	src:url('/uploads/mini/noimage.jpg#123;THEME}/fonts/fontawesome-webfont.eot') format('embedded-opentype'),url('/uploads/mini/noimage.jpg#123;THEME}/fonts/fontawesome-webfont.woff2') format('woff2'),url('/uploads/mini/noimage.jpg#123;THEME}/fonts/fontawesome-webfont.woff') format('woff'),url('/uploads/mini/noimage.jpg#123;THEME}/fonts/fontawesome-webfont.ttf') format('truetype'),url('/uploads/mini/noimage.jpg#123;THEME}/fonts/fontawesome-webfont.svg') format('svg');
    	font-weight:normal;
    	font-style: normal;
    	font-display: swap;
    }
    </style>
    <link rel="preload" href="{THEME}/fonts/fontawesome-webfont.woff2" as="font" type="font/woff2" crossorigin>
  4. ↑ Критический CSS код в main.tpl

    (иногда с ним показатель гуглспид только уменьшается)
    Сгенерировать его можно на сайте https://jonassebastianohlsson.com/criticalpathcssgenerator/. Полученный результат вставляем в main.tpl, а подключение CSS стилей переносим в самый низ страницы.
  5. ↑ Чтобы повысить производительность при прокрутке страницы, используйте флаг `passive` для прослушивателей событий прикосновения и колеса мыши.


    Этот пункт относится к библиотеке jquery в DLE. Для исправления ошибки следовать инструкции гугла: найти в файле engine/classes/jsjquery.js все
    addEventListener
    и добавить по инструкции
    , {passive: true}

    Должно получится примерно так:
    Google PageSpeed Insights

    Всего нужно сделать 2 замены, код такого типа
    addEventListener(a,c,!0)
    трогать не надо, только там, где нет третьего параметра.

    Иногда способ выше работает криво с некоторыми скриптами. Нашёл код, который скрывает данное предупреждение и не ломает скрипты другие на сайте:
    <script>
    jQuery.event.special.touchstart = {
      setup: function( _, ns, handle ) {
          this.addEventListener("touchstart", handle, { passive: !ns.includes("noPreventDefault") });
      }
    };
    </script>

    Источник
    Ещё один код:
    <script>
    jQuery.event.special.touchstart = {
       setup: function( _, ns, handle ) {
           this.addEventListener("touchstart", handle, { passive: !ns.includes("noPreventDefault") });
       }
    };
    jQuery.event.special.touchmove = {
       setup: function( _, ns, handle ) {
           this.addEventListener("touchmove", handle, { passive: !ns.includes("noPreventDefault") });
       }
    };
    jQuery.event.special.wheel = {
       setup: function( _, ns, handle ){
           this.addEventListener("wheel", handle, { passive: true });
       }
    };
    jQuery.event.special.mousewheel = {
       setup: function( _, ns, handle ){
           this.addEventListener("mousewheel", handle, { passive: true });
       }
    };
    </script>

    Источник
  6. ↑ Задайте правила эффективного использования кеша для статических объектов


    Поскольку у меня сайт подключен к cloudflare, то решение нашёл такое: переходим в раздел Caching и в параметре «Browser Cache TTL» выбираем 1 год. Пробовал ставить и месяц и полгода, но данная рекомендация исчезла только с параметром в 1 год.
    Если у вас нет, то можно попробовать включить кеш статических данных в .htaccess, что в корне сайта, добавив в самый верх:
    # сжатие text, html, javascript, css, xml:
    <ifModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript
    </ifModule>
    # кеш браузера
    <ifModule mod_expires.c>
    ExpiresActive On
    #по умолчанию кеш в 5 секунд
    ExpiresDefault "access plus 1 days"
    # Включаем кэширование изображений и флэш на месяц
    ExpiresByType image/x-icon "access plus 1 month"
    ExpiresByType image/jpeg "access plus 4 weeks"
    ExpiresByType image/png "access plus 30 days"
    ExpiresByType image/gif "access plus 43829 minutes"
    ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
    # Включаем кэширование css, javascript и текстовых файлоф на одну неделю
    ExpiresByType text/css "access plus 604800 seconds"
    ExpiresByType text/javascript "access plus 604800 seconds"
    ExpiresByType application/javascript "access plus 604800 seconds"
    ExpiresByType application/x-javascript "access plus 604800 seconds"
    # Включаем кэширование html и htm файлов на один день
    ExpiresByType text/html "access plus 43200 seconds"
    # Включаем кэширование xml файлов на десять минут
    ExpiresByType application/xhtml+xml "access plus 600 seconds"
    # Нестандартные шрифты сайта
    ExpiresByType application/x-font-ttf "access plus 1 month"
    ExpiresByType font/opentype "access plus 1 month"
    ExpiresByType application/x-font-woff "access plus 1 month"
    ExpiresByType application/x-font-woff2 "access plus 1 month"
    ExpiresByType image/svg+xml "access plus 1 month"
    ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
    </ifModule>

    Другой код:
    //Пример фрагмента .htaccess (из плагина FastestCache) для решения ошибки "Задайте правила эффективного использования кеша для статических объектов" в PageSpeed
    //это просто пример! не копируйте его на свой сайт!
    //в данном примере задано время кеширования 1 Год
    // обычно это даёт + 2-4 балла по PageSpeed
    //© Калинский Евгений aka seojacky (https://t.me/big_jacky)
    //По вопросам оптимизации сайтов по требованиям PageSpeed пишите в Telegram https://t.me/big_jacky
    /*
    * Мои плагины для ускорения сайта:
    * True Lazy Analytics https://wordpress.org/plugins/true-lazy-analytics/
    * Helper Lite for PageSpeed https://wordpress.org/plugins/helper-lite-for-pagespeed/
    */
    # BEGIN LBCWpFastestCache
    <FilesMatch "\.(webm|ogg|mp4|ico|pdf|flv|jpg|jpeg|png|gif|webp|js|css|swf|x-html|css|xml|js|woff|woff2|otf|ttf|svg|eot)(\.gz)?$">
    <IfModule mod_expires.c>
    AddType application/font-woff2 .woff2
    AddType application/x-font-opentype .otf
    ExpiresActive On
    ExpiresDefault A0
    ExpiresByType video/webm "access plus 1 year"
    ExpiresByType video/ogg "access plus 1 year"
    ExpiresByType video/mp4 "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/ico "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType text/javascript "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
    ExpiresByType application/x-javascript "access plus 1 year"
    ExpiresByType application/font-woff2 "access plus 1 year"
    ExpiresByType application/x-font-opentype "access plus 1 year"
    ExpiresByType application/x-font-truetype "access plus 1 year"
    ExpiresByType application/pdf       "access plus 1 year"
    </IfModule>
    <IfModule mod_headers.c>
    Header set Expires "max-age=A10368000, public"
    Header unset ETag
    Header set Connection keep-alive
    FileETag None
    </IfModule>
    </FilesMatch>
    # END LBCWpFastestCache

    Источник
    Ещё один код:
    <IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault «access 7 days»
    ExpiresByType application/javascript «access plus 1 year»
    ExpiresByType text/javascript «access plus 1 year»
    ExpiresByType text/css «access plus 1 year»
    ExpiresByType text/html «access plus 7 day»
    ExpiresByType text/x-javascript «access 1 year»
    ExpiresByType image/gif «access plus 1 year»
    ExpiresByType image/jpeg «access plus 1 year»
    ExpiresByType image/png «access plus 1 year»
    ExpiresByType image/jpg «access plus 1 year»
    ExpiresByType image/x-icon «access 1 year»
    ExpiresByType application/x-shockwave-flash «access 1 year»
    </IfModule>
    <ifModule mod_headers.c>
    <filesMatch «\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$»>
    Header set Cache-Control «max-age=2592000, public»
    </filesMatch>
    <filesMatch «\.(css|js)$»>
    Header set Cache-Control «max-age=2592000, public»
    </filesMatch>
    <filesMatch «\.(xml|txt)$»>
    Header set Cache-Control «max-age=172800, public, must-revalidate»
    </filesMatch>
    <filesMatch «\.(html|htm|php)$»>
    Header set Cache-Control «max-age=172800, private, must-revalidate»
    </filesMatch>
    </ifModule>
    <IfModule mod_setenvif.c>
    BrowserMatch «MSIE» force-no-vary
    BrowserMatch «Mozilla/4.[0-9]{2}» force-no-vary
    </IfModule>
    

    Источник
  7. ↑ Кеширование файлов со сторонних ресурсов


    Не ко всем файлам это может быть примерено, но всё же часть внешних файлов можно пропустить через свой сервер, и кеш будет выставлен согласно настройке сервера или настройкам клайдфларе. Суть метода:
    • Создаем PHP файл в корне сайта с содержимым:
      <?php
      function downloadJs($file_url, $save_to)
      {
          $content = file_get_contents($file_url);
          file_put_contents($save_to, $content);
      }
      // Указываем URL, затем папку от корня сайта и имя файла с расширением.
      // Проверьте чтобы на папке были права на запись 777/755
      // Метрика
      downloadJs('https://mc.yandex.ru/metrika/watch.js', realpath("./js") . '/watch.js');
      // Google Analytics
      downloadJs('http://www.google-analytics.com/analytics.js', realpath("./js") . '/analytics.js');
      // Для скриптов без расширения
      downloadJs('http://code.jivosite.com/script/widget/NuT1gBLsC6', realpath("./js") . '/NuT1gBLsC6');
      ?>
    • Создаем папку js в корневой директории сайта.
      Для проверки работы скрипта — запускаем этот PHP файл, и в папке js должны будут появится указанные файлы.

      Данным методом сегодня избавился от файла tag.js и файлов шрифтов от гугла. Файл watch.js нигде в коде страницы не указан, watch.js. У себя данный файл нашёл в коде файла шаблона share.js.

      Если вы захотите так же прописать файлы шрифтов от гугла, то после этого нужно будет строку нужного шрифта заменить например на код
      <link href="/js/rubik" rel="preload">
      где rubik — это имя файла, которые вы прописали в PHP скрипте.
    • Далее нужно поставить данный файл на CRON, например строкой:
      wget -q -O - /dev/null https://site/downloadjsfile.php >/dev/null 2>&1

      Строка подключения на крон может отличаться в зависимости от настроек крона. Если данная команда не сработает — погуглите или обратитесь к справке вашего хостера или в ТП за помощью.
      Источник
  8. ↑ Яндекс метрика и гуглспид


    Подробнее тут
  9. ↑ Исправление шрифтов гугл


    Добавить к строке подключения шрифта
    &amp;display=swap
    Если это не поможет, то можно использовать способ ниже.
  10. ↑ Асинхронная загрузка шрифтов Google Fonts


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

    <link  href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic&subset=latin,cyrillic' rel='stylesheet' type='text/css'>

    Делаем все с помощью скрипта fonfaceobserver, который также загружаем асинхронно (весит всего 5 Кб в несжатом виде).

    Качаем здесь: https://github.com/bramstein/fontfaceobserver/

    Сам скрипт кладем например в папку /JS. Получится, что доступен он по ссылке «ваш сайт»/js/fontfaceobserver.js

    Далее в header добавляем вместо ссылки на гугл шрифт (для начала просто закомментируйте его)

    <!--подключаем шрифт-->
    <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
    <style>
    @import url(/uploads/mini/001/64/27aaa0f8cd739b3552613b410d6d80.jpg);
    /* шрифт по умолчанию, до тех пор пока не подгружен новый шрифт */
    .fonts-loaded {
    body {
    font-family: Ваш шрифт, sans-serif;
    }
    }
    </style>
    <script>
    var script = document.createElement('script');
    script.async = true;
    script.src = 'https://raw.githubusercontent.com/bramstein/fontfaceobserver/master/fontfaceobserver.js';
    script.onload = function () {
    // инициализация
    var font = new FontFaceObserver('Ваш шрифт');
    font.load().then(function () {
    document.documentElement.className += " fonts-loaded";
    });
    };
    document.head.appendChild(script);
    </script>


    Источник
  11. ↑ Загрузка CSS


    <link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">

    Такой метод нужно использовать не ко всем CSS стилям, а только к тем, которые не важны для начальной отрисовки страницы, иначе будет кривая загрузка страницы, пока не прогрузятся все стили и скрипты.
    Источник
    Лучше использовать:
    <link rel="preload" href="{THEME}/css/jquery.lazyloadxt.spinner.css" as="style" onload="this.rel='stylesheet'">

    Ещё один вариант для решения пункта «удалите ресурсы блокирующие отображение загрузки». Применение loadCSS.
    Пример кода:
    <!DOCTYPE html>
    <html>
        <head>
            <style>/* header.css */</style>
            <link rel="preload" as="style" href="font.css">
            <link rel="preload" as="style" href="article.css">
            <link rel="preload" as="style" href="comments.css">
            <link rel="preload" as="style" href="about.css">
            <link rel="preload" as="style" href="footer.css">
            <noscript>
                <link rel="stylesheet" href="font.css">
                <link rel="stylesheet" href="article.css">
                <link rel="stylesheet" href="comments.css">
                <link rel="stylesheet" href="about.css">
                <link rel="stylesheet" href="footer.css">
            </noscript>
        </head>
        <body>
            <header class="header"></header>
            <main class="article"></main>
            <section class="comments"></section>
            <section class="about"></section>
            <footer class="footer"></footer>
            <script>
                importCSS('font.css', 0, true);
                importCSS('article.css');
                importCSS('comments.css');
                importCSS('about.css');
                importCSS('footer.css');
            </script>
        </body>
    </html>

    Не забываем подключить loadCSS.js в секцию head.
    Источник
  12. ↑ Функция build_css в DLE


    В файле engine/modules/functions.php найти
    $css_array[] = "<link href=\"{$config['http_home_url']}{$value}?v={$v}\" rel=\"stylesheet\" type=\"text/css\">";

    и заменить на
    $css_array[] = "<link rel=\"preload\" href=\"{$config['http_home_url']}{$value}?v={$v}\" as=\"style\" onload=\"this.rel='stylesheet'\">";

    Главное обязательно потом проверить все стили, на которые могут повлиять css файлы, выводимы в ДЛЕ по умолчанию.
  13. ↑ Ещё один вариант отложенной загрузки Яндекс Мерики


    <script>
                ( function () {
                    'use strict';
                    // Флаг, что Метрика уже загрузилась.
                    var loadedMetrica = false,
                        // Ваш идентификатор сайта в Яндекс.Метрика.
                        metricaId     = 123456789,
                        // Переменная для хранения таймера.
                        timerId;
                    // Для бота Яндекса грузим Метрику сразу без "отложки",
                    // чтобы в панели Метрики были зелёные кружочки
                    // при проверке корректности установки счётчика.
                    if ( navigator.userAgent.indexOf( 'YandexMetrika' ) > -1 ) {
                        loadMetrica();
                    } else {
                        // Подключаем Метрику, если юзер начал скроллить.
                        window.addEventListener( 'scroll', loadMetrica, {passive: true} );
                        // Подключаем Метрику, если юзер коснулся экрана.
                        window.addEventListener( 'touchstart', loadMetrica );
                        // Подключаем Метрику, если юзер дернул мышкой.
                        document.addEventListener( 'mouseenter', loadMetrica );
                        // Подключаем Метрику, если юзер кликнул мышкой.
                        document.addEventListener( 'click', loadMetrica );
                        // Подключаем Метрику при полной загрузке DOM дерева,
                        // с "отложкой" в 1 секунду через setTimeout,
                        // если пользователь ничего вообще не делал (фоллбэк).
                        document.addEventListener( 'DOMContentLoaded', loadFallback );
                    }
                    function loadFallback() {
                        timerId = setTimeout( loadMetrica, 1000 );
                    }
                    function loadMetrica( e ) {
                        // Пишем отладку в консоль браузера.
                        if ( e && e.type ) {
                            console.log( e.type );
                        } else {
                            console.log( 'DOMContentLoaded' );
                        }
                        // Если флаг загрузки Метрики отмечен,
                        // то ничего более не делаем.
                        if ( loadedMetrica ) {
                            return;
                        }
                        (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://cdn.jsdelivr.net/npm/yandex-metrica-watch/tag.js", "ym");
                        ym( metricaId, "init", { clickmap:true, trackLinks:true, accurateTrackBounce:true });
                        // Отмечаем флаг, что Метрика загрузилась,
                        // чтобы не загружать её повторно при других
                        // событиях пользователя и старте фоллбэка.
                        loadedMetrica = true;
                        // Очищаем таймер, чтобы избежать лишних утечек памяти.
                        clearTimeout( timerId );
                        // Отключаем всех наших слушателей от всех событий,
                        // чтобы избежать утечек памяти.
                        window.removeEventListener( 'scroll', loadMetrica );
                        window.removeEventListener( 'touchstart', loadMetrica );
                        document.removeEventListener( 'mouseenter', loadMetrica );
                        document.removeEventListener( 'click', loadMetrica );
                        document.removeEventListener( 'DOMContentLoaded', loadFallback );
                    }
                } )()
        </script>
    В комментариях к коду всё подробно расписано, так что проблем возникнуть не должно.
    Код почищенный от комментариев:
    <script>
                ( function () {
                    'use strict';
                    var loadedMetrica = false,
                        metricaId     = 123456789,
                        timerId;
                    if ( navigator.userAgent.indexOf( 'YandexMetrika' ) > -1 ) {
                        loadMetrica();
                    } else {
                        window.addEventListener( 'scroll', loadMetrica, {passive: true} );
                        window.addEventListener( 'touchstart', loadMetrica );
                        document.addEventListener( 'mouseenter', loadMetrica );
                        document.addEventListener( 'click', loadMetrica );
                        document.addEventListener( 'DOMContentLoaded', loadFallback );
                    }  
                    function loadFallback() {
                        timerId = setTimeout( loadMetrica, 1000 );
                    }  
                    function loadMetrica( e ) {
                        if ( e && e.type ) {
                            console.log( e.type );
                        } else {
                            console.log( 'DOMContentLoaded' );
                        }
                        if ( loadedMetrica ) {
                            return;
                        }
                        (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://cdn.jsdelivr.net/npm/yandex-metrica-watch/tag.js", "ym");
                        ym( metricaId, "init", { clickmap:true, trackLinks:true, accurateTrackBounce:true });
                        loadedMetrica = true;
                        clearTimeout( timerId );
                        window.removeEventListener( 'scroll', loadMetrica );
                        window.removeEventListener( 'touchstart', loadMetrica );
                        document.removeEventListener( 'mouseenter', loadMetrica );
                        document.removeEventListener( 'click', loadMetrica );
                        document.removeEventListener( 'DOMContentLoaded', loadFallback );
                    }
                } )()
        </script>

    Источник
  14. ↑ Отложенная загрузка счетчика Liveinternet


    <!--LiveInternet counter--><script type="text/javascript">
    document.write('<a href="https://www.liveinternet.ru/click" '+
    'target="_blank"><img src="https://counter.yadro.ru/hit?t16.6;r'+
    escape(document.referrer)+((typeof(screen)=='undefined')?'':
    ';s'+screen.width+'*'+screen.height+'*'+(screen.colorDepth?
    screen.colorDepth:screen.pixelDepth))+';u'+escape(document.URL)+
    ';h'+escape(document.title.substring(0,150))+';'+Math.random()+
    '" alt="" title="LiveInternet: показано число просмотров за 24'+
    ' часа, посетителей за 24 часа и за сегодня" '+
    'border="0" width="88" height="31"><\/a>')
    </script><!--/LiveInternet-->

    заменить на
    <!--LiveInternet counter-->
    <script type="text/javascript">new Image().src = "https://counter.yadro.ru/hit?r"+escape(document.referrer)+((typeof(screen)=="undefined")?"" :";s"+screen.width+"*"+screen.height+"*"  + (screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+ ";h"+escape(document.title.substring(0,80))+ ";" +Math.random();</script>
    <!--/LiveInternet-->
    <!--LiveInternet logo-->
    <a href="https://www.liveinternet.ru/click" target="_blank">
    <img data-src="https://counter.yadro.ru/logo?16.6" border="0" width="88" height="31" alt="" title="Показано количество просмотров и посетителей"/>
    </a>
    <!--/LiveInternet-->
  15. ↑ Отложенная загрузка рекламных блоков РСЯ, disqus


    div с идентификационным номером вставляем в HTML-код вашего сайта между тегами
    <body>
    и 
    </body>
    в том месте, где должен отображаться рекламный блок.

    А содержимое тега
    <script></script>
    заворачиваем в нашу конструкцию и помещаем ее в footer сайта.
    <script>
            var event_status = false; // Статус события (ещё не произошло)
            window.addEventListener("load", function() {
                // Страница загрузилась полностью
                ["mouseover", "click", "scroll"].forEach(function(event) {
                    window.addEventListener(event, function() {
                        // Произошло нужное событие (mouseover, click или scroll) с объектом window
                        if(!event_status) {
                            // ВАШ КОД
                            window.yaContextCb.push(()=>{
                               Ya.Context.AdvManager.render({
                                 renderTo: 'yandex_rtb_R-A-588461-2',
                                 blockId: 'R-A-588461-2'
                               })
                            })
                            event_status = true; // Статус события (произошло)
                        }
                    }, {
                        once: true
                    });
                });
            });
    </script>

    Так же в данный код можно добавить и другие рекламные блоки из script.
    Источник
    Источник
  16. ↑ Отложенная загрузка рекламы Google Adsense


    Заменить код
    <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3964770956959018" crossorigin="anonymous"></script>
    

    на следующий
    <script type="text/javascript">//<![CDATA[
    var adsenseLazyload = false; window.addEventListener("scroll", function(){ if ((document.documentElement.scrollTop != 0 && adsenseLazyload === false) || (document.body.scrollTop != 0 && adsenseLazyload === false)) { (function() { var ad = document.createElement('script'); var att = document.createAttribute('data-ad-client'); att.value = 'ca-pub-3964770956959018'; ad.setAttributeNode(att ); ad.async = true; ad.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'; var sc = document.getElementsByTagName('head')[0]; sc.parentNode .insertBefore(ad, sc); })(); adsenseLazyload = true; } }, true)
    //]]></script>

    где 3964770956959018 - это идентификатор вашего рекламного блока.
    Источник #1 Источник #2
  17. ↑ Уменьшите влияние стороннего кода (googletagmanager.com)


    Заменить код:
    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXX"></script>
    <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());</pre>
    gtag('config', 'UA-XXXXXXXX');
    </script>

    на
    <script>
    var fired = false;
    window.addEventListener('scroll', () => {
    if (fired === false) {
    fired = true;
    setTimeout(() => {
     // Пример подключения скрипта, который просто использует вставку через <script src="..."></script>
     // В данном случае - это пример вставки гугл аналитикс
    var GTMObject = document.createElement("script");
    GTMObject.src = 'https://www.googletagmanager.com/gtag/js?id=<ID>';
    GTMObject.async = true;
    document.getElementsByTagName('head')[0].appendChild(GTMObject);
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', '<ID>');
    }, 5000);
    }
    },{passive: true});
    </script>

    Источник
  18. ↑ Удалите неиспользуемый код jаvascript - recaptcha v3


    Отложенная загрузка скрипта рекапчи, после скролинга станицы скрипт будет загружен. Установка через плагины.
    recaptcha-v3-scrolling.zip [810 b] (cкачиваний: 39)

    Источник
  19. ↑ Отложенная загрузка виджета ВК, статистики гугла, яндекса и ли


    Подробнее тут (не проверена работа скриптов)
    Скопировал код на склучай, если не будет сайт доступен.
  20. ↑ Отложенная загрузка vk_groups


    Код
    <script type="text/javascript">
    							VK.Widgets.Group("vk_groups", {mode: 1, width: 280, height: 400, color1: "FFFFFF", color2: "000000", color3: "5181B8"}, 208692565);
                                </script>

    нужно заменить на
    <script>
    let ok = false;                    
    window.addEventListener('scroll', function() {
        if (ok === false) {
            ok = true;    
            setTimeout(() => {                    
                let script = document.createElement('script');
                script.src = 'https://vk.com/js/api/openapi.js?168';
                document.getElementById('vk_groups').after(script);    
                script.onload = function() {
                    VK.Widgets.Group("vk_groups", {mode: 3, width: "auto"}, 208692565);
                }
            }, 1000)
        }
    });    
    </script>

    Источник - не помню 😊 Но код рабочий и гуглспид не ругается на виджет группы ВК.
  21. ↑ Предзагрузите изображение для элемента "Отрисовка самого крупного контента"


    <link rel="preload" as="image" href="img.jpg" />
  22. ↑ Элемент "Отрисовка самого крупного контента"


    В head:
    [aviable=main|cat|xfsearch]{custom limit="2" order="date" sort="desc" template="main-img-head"}[/aviable]
    [aviable=showfull]<link rel="preload" as="image" href="[xfvalue_poster]">[/aviable]

    main-img-head.tpl:
    <link rel="preload" as="image" href="[xfvalue_poster]">

    В некоторых случаях в head  нужно прописать для полной новости примерно так:

    [aviable=showfull]
    [miniposter=fullstory]<link rel="preload" as="image" href="[xfvalue_poster]" fetchpriority="high" media="all">[/miniposter]
    <style>
      /* Критические стили для постера - убираем все анимации/трансформации */
      .fix-full_left img,
      img[alt*="Постер"] {
        opacity: 1 !important;
        visibility: visible !important;
        transform: none !important;
        transition: none !important;
        animation: none !important;
        content-visibility: visible !important;
        contain: none !important;
      }
      /* Убираем любые обертки, которые могут скрывать */
      .fix-full_left {
        opacity: 1 !important;
        visibility: visible !important;
        display: block !important;
      }
      body::before {
        [miniposter=fullstory]content: url('/uploads/mini/noimage.jpg');[/miniposter]
        display: none;
      }
    </style>
    [/aviable]
  23. ↑ Largest Contentful Paint


    Здесь для сторонних ресурсов стоит использовать preconnect или dns-prefetch.
    <link rel="dns-prefetch" href="https://mc.yandex.ru">
    <link rel="preconnect" href="https://mc.yandex.ru" crossorigin>
    <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
    <link rel="dns-prefetch" href="https://fonts.googleapis.com">

    Более подробно по данным и аналогичным тегам - тут.
  24. ↑ Устраните ресурсы, блокирующие отображение + fonts.googleapis.com


    <link rel="preload" href="https://fonts.googleapis.com/css?family=Open+Sans:300&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
    <noscript><link href="https://fonts.googleapis.com/css?family=Open+Sans:300&display=swap" rel="stylesheet" type="text/css"></noscript>

    Источник
  25. ↑ Минимизируйте работу в основном потоке + js


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


    Нужно убрать на это изображение
    loading=lazy
    при data-src данной проблемы замечено небыло. Так опытным путем и выявил данную проблему, потому что в поисковике по конкретной фразе данной проблемы было всего пару страниц, в которых ничего не сказано о решении данной проблемы.
  27. ↑ Ещё один вариант отложенной загрузки внешних скриптов js


    <script>
    let ok = false;                    
    window.addEventListener('scroll', function() {
        if (ok === false) {
            ok = true;    
            setTimeout(() => {                    
                let script = document.createElement('script');
                script.src = 'https://site/file_id.js';
                document.getElementById('id-block-id').after(script);    
            }, 1000)
        }
    });    
    </script>
    <div id="id-block-id"></div>

    Скрипт проверил на одной рекламе - +40 показатель по гуглспид сразу прибавляет, т.к. не загружает скрипт сарзу при загрузке основного контента. Подойдёт не под все коды реклам, нужно проверять каждый случай на корректное отображение вывода рекламы.
  28. ↑ Чистка fontawesome.css от лишних иконок


    Подробнее тут
  29. ↑ продолжение следует…



изучаемая и проверяемая инфа:
для шрифтов: https://techblog.sdstudio.top/blog/pagespeed-insights-nastroyte-predvaritel-nuyu-zagruzku-klyuchevyh-zaprosov
https://habr.com/ru/post/436966/
https://fooobar.com/questions/313160/how-to-load-css-asynchronously
https://github.com/filamentgroup/loadCSS

UPD
https://webformyself.com/proverka-proizvoditelnosti-sajta-s-lighthouse/
LazyLoad script: https://gist.github.com/mihdan/4a6cebc2614a62797b9d7806a628af0b

12-03-2026, 18:40: Обновил немного п.22
Комментарии:
ℹ️
 

  1. Steam Shop 4 сентября 2026 02:10
    Steam Shop

    Мне кажеться вообще не возможно сделать всё в зелень, одно правишь другое ломаеться....

    1. byroot AdMin 4 сентября 2026 02:22
      byroot

      Года 2-3 назад данный шаблон был 99/100 и ПК и МОБ версии, потом уже пошли изменения в алгоритмах расчета и показатель упал, обновлять что-то ещё я просто не стал уже. Сделать можно, если избавиться от всех сторонних скриптов на сайте.

      --------------------
      🎬🎬🎬 Мои услуги по DLE 👉👉👉 https://byroot.ru/uslugi.html 🎬🎬🎬
  2. Док 30 сентября 2022 14:42
    Док

    Манипуляция с обрезом и сжатием картинок актуальна разве для dle 15.2?

    1. byroot AdMin 30 сентября 2022 18:23
      byroot
      Если это уменьшает размер загружаемого контента - то конечно актуально!
      --------------------
      🎬🎬🎬 Мои услуги по DLE 👉👉👉 https://byroot.ru/uslugi.html 🎬🎬🎬
  3. Тунар 18 февраля 2021 00:25
    Тунар
    Статья вроде и хорошая но все как то поверхностно, не понятно вообще как пункт 7 (сам php файл будет взаимодействовать с dle)
    1. byroot AdMin 20 февраля 2021 10:45
      byroot
      По ссылке ИСТОЧНИК более подробнее расписан данный способ. Суть его в том, что все файлы будут загружаться на сайт, следовательно и ссылки всех внешних скриптов и файлов можно заменить на внутренние. Например, если был путь в счетчике https://mc.yandex.ru/metrika/watch.js, то заменяем его на путь внутри сайта, например https://byroot.ru/js/watch.js
      --------------------
      🎬🎬🎬 Мои услуги по DLE 👉👉👉 https://byroot.ru/uslugi.html 🎬🎬🎬
Модули для создания киносайта и не только на базе DataLife Engine, и многое другое...
Просто блог Евгения Попова, он же - byroot © 2015-2026 | Карта сайта