Оптимизация доставки CSS: как отложить загрузку css?

Я пытаюсь оптимизировать доставку CSS, следуя документации Google для разработчиков https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery#example

Как вы можете видеть в примере вложения небольшого CSS файла, критический CSS вложен в голову и исходный файл small.css загружается после загрузки страницы.

<html>
  <head>
    <style>
      .blue{color:blue;}
    </style>
    </head>
  <body>
    <div class="blue">
      Hello, world!
    </div>
  </body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>

Мой вопрос относительно этого примера:

Как загрузить большой файл css после загрузки страницы?

Ответ 1

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

function loadStyleSheet(src) {
    if (document.createStyleSheet){
        document.createStyleSheet(src);
    }
    else {
        $("head").append($("<link rel='stylesheet' href='"+src+" />"));
    }
};

Просто вызовите это в вашей функции $(document).ready() или window.onload и все готово.

Для # 2, почему бы вам не попробовать это? Отключите Javascript в вашем браузере и посмотрите!

Кстати, удивительно, как далеко может зайти простой поиск в Google; для запроса "post load css" это был четвертый хит... http://www.vidalquevedo.com/how-to-load-css-stylesheets-dynamically-with-jquery

Ответ 2

Небольшая модификация функции, предоставляемой Fred, чтобы сделать ее более эффективной и свободной от jQuery. Я использую эту функцию в производстве для своих веб-сайтов.

        // to defer the loading of stylesheets
        // just add it right before the </body> tag
        // and before any javaScript file inclusion (for performance)  
        function loadStyleSheet(src){
            if (document.createStyleSheet) document.createStyleSheet(src);
            else {
                var stylesheet = document.createElement('link');
                stylesheet.href = src;
                stylesheet.rel = 'stylesheet';
                stylesheet.type = 'text/css';
                document.getElementsByTagName('head')[0].appendChild(stylesheet);
            }
        }

Ответ 3

В дополнение к ответу Фреда:

Решение с использованием jQuery и Noscript

<html>
  <head>
    <style>
      .blue{color:blue;}
    </style>
    <script type="text/javascript" src="../jquery-1.4.2.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
        if($("body").size()>0){
                if (document.createStyleSheet){
                    document.createStyleSheet('style.css');
                }
                else {
                    $("head").append($("<link rel='stylesheet' 
                    href='style.css' 
                    type='text/css' media='screen' />"));
                }
            }
        });
    </script>
    </head>
  <body>
    <div class="blue">
      Hello, world!
    </div>
  </body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>

из http://www.vidalquevedo.com/how-to-load-css-stylesheets-dynamically-with-jquery

Использование чистого Javascript и Noscript

<html>
  <head>
    <style>
      .blue{color:blue;}
    </style>
    <script type="text/javascript">
          var stylesheet = document.createElement('link');
          stylesheet.href = 'style.css';
          stylesheet.rel = 'stylesheet';
          stylesheet.type = 'text/css';
          document.getElementsByTagName('head')[0].appendChild(stylesheet);
    </script>
    </head>
  <body>
    <div class="blue">
      Hello, world!
    </div>
  </body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>

Ответ 4

Попробуйте этот фрагмент

автор утверждает, что он был опубликован Google PageSpeed ​​Team

<script>
    var cb = function() {
    var l = document.createElement('link'); l.rel = 'stylesheet';
    l.href = 'yourCSSfile.css';
    var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h); };
    var raf = requestAnimationFrame || mozRequestAnimationFrame ||
              webkitRequestAnimationFrame || msRequestAnimationFrame;
    if (raf) raf(cb);
    else window.addEventListener('load', cb);
</script>

Ответ 5

ВНИМАНИЕ: body{background-image: url("http://example.com/image.jpg");} в CSS файлах сделает ваши CSS файлы все еще блокирующими рендеринг.

Если вы перепробовали все решения, описанные выше, и по-прежнему получаете предупреждение о блокировке рендеринга из PageSpeed, тогда у вас, вероятно, есть это правило стиля в файлах CSS. После нескольких часов тестов выясняется, что это правило - то, что заставляет ВСЕ мои css быть помеченными как ресурсы, блокирующие рендеринг, в представлении PageSpeed. Я обнаружил, что та же проблема обсуждалась ранее.

Я не знаю, почему body{background-image: url(...) делает это для всех файлов css !, хотя у меня есть разные ресурсы изображений в файле для кнопок, значков и т.д.

Я исправил это, переместив это правило из файла .css и поместив его во встроенные стили. К сожалению, вам придется нарушить план CSS и поместить правило во все HTML файлы макетов, а не в 1 CSS файл, который импортируется во все ваши HTML-макеты, но 90-е и зеленый цвет в представлении PageSpeed этого заслуживают.