Является ли рекомендация включать CSS до того, как JavaScript окажется недействительным?

В бесчисленных местах онлайн я видел рекомендацию включать CSS до JavaScript. Обоснование обычно этой формы:

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

Мое фактическое тестирование показывает что-то совсем другое:

Мой тестовый жгут

Я использую следующий Ruby script для генерации определенных задержек для различных ресурсов:

require 'rubygems'
require 'eventmachine'
require 'evma_httpserver'
require 'date'

class Handler  < EventMachine::Connection
  include EventMachine::HttpServer

  def process_http_request
    resp = EventMachine::DelegatedHttpResponse.new( self )

    return unless @http_query_string

    path = @http_path_info
    array = @http_query_string.split("&").map{|s| s.split("=")}.flatten
    parsed = Hash[*array]

    delay = parsed["delay"].to_i / 1000.0
    jsdelay = parsed["jsdelay"].to_i

    delay = 5 if (delay > 5)
    jsdelay = 5000 if (jsdelay > 5000)

    delay = 0 if (delay < 0) 
    jsdelay = 0 if (jsdelay < 0)

    # Block which fulfills the request
    operation = proc do
      sleep delay 

      if path.match(/.js$/)
        resp.status = 200
        resp.headers["Content-Type"] = "text/javascript"
        resp.content = "(function(){
            var start = new Date();
            while(new Date() - start < #{jsdelay}){}
          })();"
      end
      if path.match(/.css$/)
        resp.status = 200
        resp.headers["Content-Type"] = "text/css"
        resp.content = "body {font-size: 50px;}"
      end
    end

    # Callback block to execute once the request is fulfilled
    callback = proc do |res|
        resp.send_response
    end

    # Let the thread pool (20 Ruby threads) handle request
    EM.defer(operation, callback)
  end
end

EventMachine::run {
  EventMachine::start_server("0.0.0.0", 8081, Handler)
  puts "Listening..."
}

Вышеупомянутый мини-сервер позволяет устанавливать произвольные задержки для файлов JavaScript (как сервера, так и клиента) и произвольных задержек CSS. Например, http://10.0.0.50:8081/test.css?delay=500 дает мне 500 мкс задерживает передачу CSS.

Я использую следующую страницу для тестирования.

<!DOCTYPE html>
<html>
  <head>
      <title>test</title>
      <script type='text/javascript'>
          var startTime = new Date();
      </script>
      <link href="#" onclick="location.href='http://10.0.0.50:8081/test.css?delay=500'; return false;" type="text/css" rel="stylesheet">
      <script type="text/javascript" src="http://10.0.0.50:8081/test2.js?delay=400&amp;jsdelay=1000"></script> 
  </head>
  <body>
    <p>
      Elapsed time is: 
      <script type='text/javascript'>
        document.write(new Date() - startTime);
      </script>
    </p>    
  </body>
</html>

Когда я сначала включаю CSS, страница занимает 1,5 секунды для рендеринга:

CSS first

Когда я включаю JavaScript сначала, страница занимает 1.4 секунды для рендеринга:

JavaScript first

Я получаю аналогичные результаты в Chrome, Firefox и Internet Explorer. В Opera, однако, порядок просто не имеет значения.

Что, по-видимому, происходит, так это то, что интерпретатор JavaScript отказывается запускать, пока не будет загружен весь CSS. Таким образом, кажется, что включение JavaScript в первую очередь более эффективно, так как поток JavaScript получает больше времени выполнения.

Мне что-то не хватает, рекомендуется ли размещать CSS-код до того, как JavaScript включится неверно?

Ясно, что мы могли бы добавить async или использовать setTimeout, чтобы освободить поток рендеринга или поместить код JavaScript в нижний колонтитул или использовать загрузчик JavaScript. Здесь речь идет о упорядочении существенных битов JavaScript и бит CSS в голове.

Ответ 1

Это очень интересный вопрос. Я всегда ставил свой CSS <link href="..."> перед моим JS <script src="...">, потому что "я читал один раз, чтобы это было лучше". Итак, вы правы; пришло время провести какое-то настоящее исследование!

Я установил свой собственный тестовый жгут в Node (код ниже). В принципе, я:

  • Убедитесь, что HTTP-кеширование не было, поэтому браузер должен будет выполнять полную загрузку каждый раз при загрузке страницы.
  • Чтобы имитировать реальность, я включил jQuery и H5BP CSS (так что там было достойное количество script/CSS для разбора)
  • Настройте две страницы - одну с CSS до script, одну с CSS после script.
  • Записано, сколько времени потребовалось для внешнего script в <head> для выполнения
  • Записано, сколько времени потребовалось для встроенного script в <body>, что аналогично DOMReady.
  • Отложить отправку CSS и/или script в браузер на 500 мс.
  • Провести тест 20 раз в 3 основных браузерах.

Результаты

Сначала, когда файл CSS задерживается на 500 мсек:

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 583ms  36ms  | 559ms  42ms  | 565ms 49ms
St Dev      | 15ms   12ms  | 9ms    7ms   | 13ms  6ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 584ms  521ms | 559ms  513ms | 565ms 519ms
St Dev      | 15ms   9ms   | 9ms    5ms   | 13ms  7ms

Затем я установил jQuery для задержки на 500 мс вместо CSS:

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 597ms  556ms | 562ms  559ms | 564ms 564ms
St Dev      | 14ms   12ms  | 11ms   7ms   | 8ms   8ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 598ms  557ms | 563ms  560ms | 564ms 565ms
St Dev      | 14ms   12ms  | 10ms   7ms   | 8ms   8ms

Наконец, я установил оба jQuery и CSS для задержки на 500 мсек:

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 620ms  560ms | 577ms  577ms | 571ms 567ms
St Dev      | 16ms   11ms  | 19ms   9ms   | 9ms   10ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 623ms  561ms | 578ms  580ms | 571ms 568ms
St Dev      | 18ms   11ms  | 19ms   9ms   | 9ms   10ms

Заключение

Во-первых, важно отметить, что я работаю в предположении, что у вас есть сценарии, расположенные в <head> вашего документа (в отличие от конца <body>). Существуют различные аргументы в отношении того, почему вы можете ссылаться на ваши сценарии в <head> по сравнению с концом документа, но это выходит за рамки этого ответа. Это строго о том, должен ли <script> идти до <link> в <head>.

В современных браузерах DESKTOP похоже, что привязка к CSS сначала никогда обеспечивает прирост производительности. Помещение CSS после script дает вам тривиальный выигрыш, когда и CSS, и script задерживаются, но дает вам большую прибыль при задержке CSS. (Отображается столбцами last в первом наборе результатов.)

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

Почему?

Исторически, когда браузер столкнулся с тегом <script>, указывающим на внешний ресурс, браузер будет останавливать синтаксический анализ HTML, получить script, выполнить его, а затем продолжить синтаксический анализ HTML. Напротив, если браузер столкнулся с <link> для внешней таблицы стилей, он продолжит анализ HTML, пока он извлекает файл CSS (параллельно).

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

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

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

Поддержка браузера

Спекулятивный синтаксический анализ был впервые реализован в: (наряду с процентом пользователей настольных браузеров по всему миру, использующих эту версию или больше с января 2012 года)

  • Chrome 1 (WebKit 525) (100%)
  • IE 8 (75%)
  • Firefox 3.5 (96%)
  • Safari 4 (99%)
  • Opera 11.60 (85%)

В общей сложности примерно 85% настольных браузеров, используемых сегодня, поддерживают спекулятивную загрузку. Постановка скриптов перед CSS будет иметь ограничение производительности для 15% пользователей во всем мире; YMMV на основе вашей конкретной аудитории сайта. (И помните, что число сокращается.)

В мобильных браузерах немного сложно получить окончательные номера просто из-за того, насколько гетерогенен мобильный браузер и ландшафт ОС. Поскольку спекулятивный рендеринг был реализован в WebKit 525 (выпущен в марте 2008 г.), и почти каждый полезный мобильный браузер основан на WebKit, мы можем заключить, что "большинство" мобильных браузеров должны его поддерживать. Согласно quirksmode, iOS 2.2/Android 1.0 использует WebKit 525. Я понятия не имею, как выглядит Windows Phone.

ОднакоЯ проверил тест на своем устройстве Android 4, и пока видел цифры, похожие на результаты на рабочем столе, я подключил его к фантастическому новому удаленному отладчику в Chrome для Android и вкладка "Сеть" показали, что браузер действительно ожидал загрузки CSS до полной загрузки JavaScripts – Другими словами, даже самая новая версия WebKit для Android, похоже, не поддерживает спекулятивный синтаксический анализ. Я подозреваю, что он может быть отключен из-за ограничений по ЦП, памяти и/или сети, присущих мобильным устройствам.

Код

Простите неряшливость – это Q & D.

app.js

var express = require('express')
, app = express.createServer()
, fs = require('fs');

app.listen(90);

var file={};
fs.readdirSync('.').forEach(function(f) {
    console.log(f)
    file[f] = fs.readFileSync(f);
    if (f != 'jquery.js' && f != 'style.css') app.get('/' + f, function(req,res) {
        res.contentType(f);
        res.send(file[f]);
    });
});


app.get('/jquery.js', function(req,res) {
    setTimeout(function() {
        res.contentType('text/javascript');
        res.send(file['jquery.js']);
    }, 500);
});

app.get('/style.css', function(req,res) {
    setTimeout(function() {
        res.contentType('text/css');
        res.send(file['style.css']);
    }, 500);
});


var headresults={
    css: [],
    js: []
}, bodyresults={
    css: [],
    js: []
}
app.post('/result/:type/:time/:exec', function(req,res) {
    headresults[req.params.type].push(parseInt(req.params.time, 10));
    bodyresults[req.params.type].push(parseInt(req.params.exec, 10));
    res.end();
});

app.get('/result/:type', function(req,res) {
    var o = '';
    headresults[req.params.type].forEach(function(i) {
        o+='\n' + i;
    });
    o+='\n';
    bodyresults[req.params.type].forEach(function(i) {
        o+='\n' + i;
    });
    res.send(o);
});

css.html

<!DOCTYPE html>
<html>
    <head>
        <title>CSS first</title>
        <script>var start = Date.now();</script>
        <link rel="stylesheet" href="style.css">
        <script src="jquery.js"></script>
        <script src="test.js"></script>
    </head>
    <body>
        <script>document.write(jsload - start);bodyexec=Date.now()</script>
    </body>
</html>

js.html

<!DOCTYPE html>
<html>
    <head>
        <title>CSS first</title>
        <script>var start = Date.now();</script>
        <script src="jquery.js"></script>
        <script src="test.js"></script>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <script>document.write(jsload - start);bodyexec=Date.now()</script>
    </body>
</html>

test.js

var jsload = Date.now();


$(function() {
    $.post('/result' + location.pathname.replace('.html','') + '/' + (jsload - start) + '/' + (bodyexec - start));
});

jquery.js был jquery-1.7.1.min.js

Ответ 2

Есть две основные причины, по которым CSS стоит перед JavaScript.

  • Старые браузеры (Internet Explorer 6-7, Firefox 2 и т.д.) блокируют все последующие загрузки, когда они начнут загружать script. Поэтому, если у вас есть a.js, за которым следует b.css, они загружаются последовательно: сначала a, затем b. Если у вас есть b.css, за которым следует a.js, они загружаются параллельно, поэтому страница загружается быстрее.

  • Ничего не отображается до тех пор, пока не будут загружены все таблицы стилей - это верно во всех браузерах. Скрипты разные - они блокируют рендеринг всех элементов DOM, которые находятся ниже тега script на странице. Если вы поместите свои скрипты в HEAD, значит, вся страница заблокирована от рендеринга, пока не будут загружены все таблицы стилей и все сценарии. Хотя имеет смысл блокировать весь рендеринг для таблиц стилей (так что вы получаете правильное стилирование в первый раз и избегаете вспышки неокрашенного содержимого FOUC), нет смысла блокировать рендеринг всей страницы для скриптов. Часто скрипты не влияют ни на какие элементы DOM, ни на часть элементов DOM. Лучше всего загружать скрипты как можно ниже на странице, или даже лучше загружать их асинхронно.

Приятно создавать примеры с Cuzillion. Например, эта страница имеет script в HEAD, поэтому вся страница пуста, пока она не загрузится. Однако, если мы переместим script в конец блока BODY, заголовок страницы отобразится, поскольку эти элементы DOM произойдут над тегом script, как вы можете видеть на на этой странице.

Ответ 3

Я бы не особо подчеркивал результаты, которые у вас есть, я считаю, что это субъективно, но у меня есть причина объяснить вам, что лучше поставить CSS до js.

Во время загрузки вашего сайта есть два сценария, которые вы увидите:

CASE 1: белый экран > неэкранированный веб-сайт > стиль веб-сайтa > взаимодействие > стиль и интерактивный веб-сайт

CASE 2: белый экран > неизданный веб-сайт > взаимодействие > стиль веб-сайтa > стиль и интерактивный веб-сайт


Я, честно говоря, не могу представить, чтобы кто-то выбирал Case 2. Это означало бы, что посетители, использующие медленные интернет-соединения, столкнутся с неустановленным веб-сайтом, который позволяет им взаимодействовать с ним с помощью Javascript (так как это уже загружено). Кроме того, количество времени, затрачиваемое на незакрепленный веб-сайт, будет максимизировано таким образом. Зачем кому-то это нужно?

Он также работает лучше, чем состояния jQuery

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

Когда файлы загружаются в неправильном порядке (сначала JS, затем CSS), любой Javascript-код, основанный на свойствах, заданных в файлах CSS (например, ширина или высота div), не будет загружен правильно. Похоже, что с неправильным порядком загрузки правильные свойства "иногда" известны Javascript (возможно, это вызвано состоянием гонки?). Этот эффект кажется большим или меньшим в зависимости от используемого браузера.

Ответ 4

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

Цель правила "put stylesheets at the top и scripts the bottom" заключается в том, что в целом это лучший способ добиться оптимального прогрессивного рендеринга, который имеет решающее значение для пользователя.

Все остальное в стороне: если ваш тест действительно, и вы действительно делаете результаты, противоречащие популярным правилам, это не удивительно. Каждый веб-сайт (и все, что требуется, чтобы все это отображалось на экране пользователя) различно, и Интернет постоянно развивается.

Ответ 5

Я включаю файлы CSS перед Javascript по другой причине.

Если моему Javascript необходимо выполнить динамическую калибровку некоторого элемента страницы (для тех угловых случаев, когда CSS действительно является основным в обратном направлении), тогда загрузка CSS после того, как JS русифицирует, может привести к условиям гонки, где элемент изменяется прежде чем стили CSS будут применены и, таким образом, выглядят странно, когда стили наконец начнутся. Если я загружаю CSS заранее, я могу гарантировать, что все будет выполняться в заданном порядке и что окончательный макет - это то, что я хочу.

Ответ 6

Является ли рекомендация включать CSS до того, как JavaScript недействителен?

Нет, если вы считаете это просто рекомендацией. Но если вы относитесь к этому как к жесткому и быстрому правилу?, да, это неверно.

Из https://developer.mozilla.org/en-US/docs/Web/Reference/Events/DOMContentLoaded

Загрузка таблицы стилей выполняется script, поэтому, если у вас есть <script>после <link rel="stylesheet" ...> страница не завершит разбор - и DOMContentLoaded не будет срабатывать - пока таблица стилей не будет загружена.

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

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

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

Этот вопрос, в частности, относится ко всем объявлениям, размещаемым на веб-сайтах. Мне было бы очень приятно, если бы авторы сайта отображали только разделители разделов для рекламного контента и следили за тем, чтобы их сайт был загружен и интерактивен, прежде чем вводить объявления в событие onload. Даже тогда я хотел бы видеть, что объявления загружаются серийно, а не сразу, потому что они влияют на мою способность даже прокручивать содержимое сайта, пока загружаются раздутые объявления. Но это всего лишь одна точка зрения.

  • Знайте своих пользователей и то, что они ценят.
  • Знайте своих пользователей и их среду просмотра.
  • Знайте, что делает каждый файл, и каковы его предварительные требования. Выполнение всех работ будет иметь приоритет над скоростью и красивой.
  • Используйте инструменты, показывающие сетевую временную линию при разработке.
  • Тест в каждой среде, которую используют пользователи. Может потребоваться динамическое (серверная сторона при создании страницы) изменить порядок загрузки в зависимости от среды пользователя.
  • В случае сомнений измените порядок и меру снова.
  • Возможно, что смешивание стилей и скриптов в порядке загрузки будет оптимальным; не все из них, а затем все остальные.
  • Экспериментируйте не только с каким заказом для загрузки файлов, но и где. Глава? В теле? После тела? DOM готов/загружен? Загруженный?
  • Рассмотрите варианты асинхронного и отсрочки, когда это необходимо, чтобы уменьшить чистую задержку, которую пользователь испытает, прежде чем сможет взаимодействовать со страницей. Тест, чтобы определить, помогают ли они или причиняют боль.
  • При оценке оптимального порядка загрузки всегда учитываются компромиссы. Превосходное и отзывчивое - всего лишь одно.

Ответ 7

Я не совсем уверен, как ваше тестирование "рендеринга" при использовании java script. Однако рассмотрим этот

Одна страница на вашем сайте - 50 тыс., что не является необоснованным. Пользователь находится на восточном побережье, а ваш сервер находится на западе. MTU определенно не 10k, поэтому будет несколько поездок туда и обратно. Для получения вашей страницы и таблиц стилей может потребоваться 1/2 секунды. Обычно (для меня) javascript (через плагин jquery и т.д.) Гораздо больше, чем CSS. Theres также, что происходит, когда ваше подключение к Интернету задыхается на полпути на странице, но позволяет игнорировать это (иногда это происходит со мной, и я считаю, что css оказывает, но я не уверен на 100%).

Так как css находится в голове, могут быть дополнительные подключения, чтобы получить его, что означает, что он может закончить до того, как страница сделает. В любом случае во время типа оставшейся части страницы и файлов javascript (что намного больше байтов) страница неустановлена, что делает сайт/соединение медленным.

ДАЖЕ ЕСЛИ интерпретатор JS отказывается начинать до тех пор, пока CSS не будет выполнен, чтобы загрузить код javascript, особенно если далеко от сервера вырезается время css, что сделает сайт не очень красивым.

Небольшая оптимизация, но для этого и есть причина.

Ответ 8

Обновлено 2017-12-16

Я не был уверен в тестах в OP. Я решил немного поэкспериментировать и в конечном итоге перебор некоторых мифов.

Синхронный <script src...> блокирует загрузку ресурсов под ним, пока он не будет загружен и выполнен

Это уже не верно. Посмотрите на водопад, созданный Chrome 63:

<head>
<script src="//alias-0.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=1"></script>
<script src="//alias-1.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=2"></script>
<script src="//alias-2.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=3"></script>
</head>

Чистый инспектор Chrome - > водопад

<link rel=stylesheet> не будет блокировать загрузку и выполнение скрипты под ним

Это неверно. Таблица стилей не будет блокировать загрузку, но она заблокирует выполнение script (небольшое объяснение здесь). Посмотрите диаграмму производительности, созданную Chrome 63:

<link href="//alias-0.redacted.com/payload.php?type=css&amp;delay=666" rel="stylesheet">
<script src="//alias-1.redacted.com/payload.php?type=js&amp;delay=333&amp;block=1000"></script>

Инструменты разработчика Chrome - > производительность


Учитывая вышеизложенное, результаты в OP можно объяснить следующим образом:

Сначала CSS:

CSS Download  500ms:<------------------------------------------------>
JS Download   400ms:<-------------------------------------->
JS Execution 1000ms:                                                  <-------------------------------------------------------------------------------------------------->
DOM Ready   @1500ms:                                                                                                                                                      ◆

JS Во-первых:

JS Download   400ms:<-------------------------------------->
CSS Download  500ms:<------------------------------------------------>
JS Execution 1000ms:                                        <-------------------------------------------------------------------------------------------------->
DOM Ready   @1400ms:                                                                                                                                            ◆

Ответ 9

Стив Соудерс уже дал окончательный ответ, но...

Интересно, есть ли проблема с исходным тестом Sam и повторением Josh.

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

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

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

В новых браузерах второе TCP-соединение открывается созерцательно, поэтому накладные расходы на соединение снижаются/уходят, в старых браузерах это неверно, а второе соединение будет иметь накладные расходы при открытии.

Довольно, как это сделать, если это влияет на результаты тестов, я не уверен.

Ответ 10

Я думаю, что это не будет верно для всех случаев. Потому что css будет загружать параллельно, но js can not. Рассмотрим для одного и того же случая,

Вместо того, чтобы иметь один css, возьмите 2 или 3 файла css и попробуйте это,

1) css..css..js 2) css..js..css 3) js..css..css

Я уверен, что css..css..js даст лучший результат, чем все остальные.

Ответ 11

Вот краткое изложение всех основных ответов выше (или, возможно, ниже:)

Для современных браузеров поместите css везде, где вам это нравится. Они проанализировали ваш html файл (который они называют спекулятивным разбором) и начнут загрузку css параллельно с синтаксисом html.

Для старых браузеров сначала ставьте css сверху (если вы не хотите сначала показывать голую, но интерактивную страницу).

Для всех браузеров поместите javascript как можно дальше на страницу, так как он остановит разбор вашего html. Предпочтительно загружать его асинхронно (т.е. Вызов ajax)

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

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

Ответ 12

Мы должны помнить, что новые браузеры работали над своими механизмами Javascript, их синтаксическими анализаторами и т.д., оптимизируя общие проблемы кода и разметки таким образом, что проблемы, возникающие в древних браузерах, таких как <= IE8, больше не актуальны, а не только в отношении разметки, но также и для использования переменных JavaScript, селекторов элементов и т.д. Я вижу в недалеком будущем ситуацию, когда технологии достигли точки, где производительность больше не является проблемой.

Ответ 13

Лично я бы не стал уделять слишком много внимания такой "народной мудрости". То, что могло быть правдой в прошлом, может быть не совсем верно. Я бы предположил, что все операции, связанные с интерпретацией и рендерингом веб-страницы, полностью асинхронны ( "выборка" и "действие на нее" - это две совершенно разные вещи, которые могут обрабатываться разными потоками и т.д.) И в любом случае полностью вне вашего контроля или вашей озабоченности.

Я бы поставил ссылки CSS в "головной" части документа вместе с любыми ссылками на внешние скрипты. (Некоторые скрипты могут потребовать, чтобы их помещали в тело, и если да, обязывайте их.)

Помимо этого... если вы заметите, что "это кажется более быстрым/медленным, чем это, в этом/этом браузере", рассматривайте это наблюдение как интересное, но неактуальное любопытство и не позволяйте ему влиять на ваши проектные решения. Слишком много слишком сильно меняется. (Кто-нибудь хочет сделать какие-либо ставки на сколько минут будет до того, как команда Firefox выйдет с еще одним промежуточным выпуском своего продукта? Да, я тоже.)