Как заставить браузер (IE и Chrome) запрашивать изображения перед сценариями?
Примечание.. Если вы читаете это в первый раз, вы можете перейти непосредственно к UPDATE, так как он более точно решает проблему.
Итак, у меня есть веб-страница.
В голове у меня есть фоновое изображение CSS:
<style>
#foo { background-image:url(foo.gif); }
</style>
В нижней части страницы загружаются мои скрипты:
<script src="jquery.js"></script>
<script src="analytics.js"></script>
Поскольку сценарии расположены в нижней части страницы, а CSS вверху страницы, я предположил, что браузеры сначала загружают изображение. Однако, похоже, это не так.
Это скриншот из инструментов Chrome Dev:
http://www.vidasp.net/media/cssimg-vs-script.png
Как вы можете видеть, изображение загружается после скриптов.
(Вертикальная синяя линия - это событие page load DOMContentLoaded. Огромный 45-минутный промежуток - это время, в течение которого Chrome анализирует исходный код jQuery.)
Теперь, мой первый вопрос:
Является ли это стандартным поведением в браузерах? Фоновые изображения CSS всегда загружаются после всех скриптов на странице?
Если да, как я могу убедиться, что эти изображения загружаются перед сценариями? Есть ли простое и удобное решение этой проблемы?
ОБНОВЛЕНИЕ
Я сделал тестовый пример. Это исходный код HTML:
<!DOCTYPE html>
<html>
<head>
<style> body { background-image: url(image1.jpg) } </style>
</head>
<body>
<div> <img src="image2.jpg"> </div>
<script src="http://ajax.googleapis.com/ajax/.../jquery.min.js"></script>
<script src="http://vidasp.net/js/tablesorter.js"></script>
</body>
</html>
Как вы можете видеть, у меня есть одно фонового изображения CSS, одно регулярное изображение и два сценария. И теперь результаты:
ИНТЕРНЕТ-ЭКСПЛОРЕР (9 бета)
http://www.vidasp.net/media/loadorder-results/ie2.png
http://www.vidasp.net/media/loadorder-results/ie1.png
Internet Explorer сначала запрашивает обычное изображение, затем два сценария и изображение CSS.
FIREFOX (3.6)
http://www.vidasp.net/media/loadorder-results/firefox2.png
http://www.vidasp.net/media/loadorder-results/firefox1.png
Firefox делает это правильно. Все ресурсы запрашиваются в том порядке, в котором они отображаются в исходном коде HTML.
ХРОМ (последняя стабильная)
http://www.vidasp.net/media/loadorder-results/chrome2.png
http://www.vidasp.net/media/loadorder-results/chrome1.png
Chrome демонстрирует проблему, которая заставила меня написать этот вопрос в первую очередь. Сценарии запрашиваются перед изображениями.
OPERA (11)
http://www.vidasp.net/media/loadorder-results/opera1.png
http://www.vidasp.net/media/loadorder-results/opera2.png
Как и Firefox, Opera делает это правильно, также. :D
Подводя итог:
- Firefox и Opera запрашивают ресурсы, как они появляются в исходном коде.
Исключения, поэтому это правило:
- Internet explorer запрашивает фоновые изображения CSS
- Chrome запрашивает скрипты перед изображениями, даже если сценарии появляются позже в исходном коде
Теперь, когда я изложил этот вопрос, позвольте мне перейти к моему вопросу:
Как заставить IE и Chrome запрашивать изображения перед сценариями?
Ответы
Ответ 1
Самые последние браузеры для такой непредсказуемой параллельной предварительной загрузки вещей в наши дни по соображениям производительности и в основном разрушают любую возможность создания порядка загрузки компонентов. Это, конечно, происходит после загрузки полной DOM.
Такая же история, как с JQuery ленивая загрузка изображений, которая была сломана на некоторое время.
Ответ 2
Учтите, что браузер не может ничего сделать, пока он не построит DOM. Поэтому сначала он анализирует всю страницу, ТОГДА загружает изображения (даже если они из CSS).
Вы можете загружать изображения в сегменты DATA, встроенные в CSS или на страницу, что может ускорить их, , или вы можете ввести ссылку jQuery после загрузки страницы (например, установить таймер на 500 мс) но, очевидно, это повлияет на удобство использования.
Теперь я уверен, что все зависит от реализации, вы всегда можете найти браузер, который будет загружать изображения по мере их появления, но подумайте над тем, что значит построить DOM, а затем заполнить его.
http://en.wikipedia.org/wiki/Data_URI_scheme
Если SO не разделяет его, между этим кодом и красной точкой должна быть красная точка:\
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4Tzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0vr4MkhoXe0rZigAAAABJRU5ErkJggg==" alt="Red dot" />
Итак, что я имел в виду, используйте схему URI DATA
Ответ 3
Возможная опция - загрузить все те изображения, которые вам нужны в начале вашего script. См. эту статью TechRepublic для получения дополнительной информации.
Ответ 4
Мы решили эту проблему, используя .load внутри jQuery-вызова .ready
что-то вроде:
jQuery(document).ready(function($){
jQuery('#my_container img').load(function($){
/* SCRIPT */
});
});
Ответ 5
Использовать возможности предварительной загрузки изображений с помощью атрибута rel= "preload"
<link rel="preload" href="images/mypic.jpg" as="image">
Атрибут as указывает тип объекта, который должен ожидать браузер. Таким образом, это добавляет самые высокие приоритеты среди всех изображений, которые вы загружаете на странице, но не меняете приоритет "JS → Изображение"
<link rel="preload" href="images/mypic.jpg">
Объявление без возможности предварительной загрузки изображений даже до загрузки js, что увеличивает приоритет загрузки изображения.
Функция предварительной загрузки