HTTP-кэширование, различия в браузерах - PullRequest
4 голосов
/ 16 сентября 2009

уважаемые переполнители стека,

Итак, я недавно пытался полностью сосредоточиться на кэшировании HTTP-ресурсов. Примечательно, что сейчас я просто смотрю на кеширование отдельного изображения со спрайтом, которое используется для рендеринга значков / небольших изображений по всей странице. Вот объяснение странного поведения, которое я вижу:

Итак, на данной странице у меня есть только одно изображение: icons.sprite.gif. Есть четыре элемента, которые используют спрайт для отображения различных значков на странице. В моей конфигурации Apache у меня установлен mod_expires и следующие директивы управления кэшем:

ExpiresActive On
ExpiresDefault "access plus 300 seconds"

ExpiresByType text/html "access plus 1 day"
ExpiresByType text/css "access plus 1 day"
ExpiresByType text/javascript "access plus 1 day"
ExpiresByType image/gif "access plus 1 week"
ExpiresByType image/jpg "access plus 1 week"
ExpiresByType image/png "access plus 1 week"
ExpiresByType application/x-shockwave-flash "access plus 1 day"

Теперь вот странность. В Safari, когда я загружаю страницу, сетевой инспектор показывает только один запрос на спрайт. Это прекрасно, работает как положено. С другой стороны, с помощью Internet Explorer и Firefox Fidder / Firebug выдает четыре успешных запроса на изображение в формате sprited = что !? Последующие запросы приводят к одному попаданию в кэш, но эта первая загрузка содержит четыре одновременных запроса. Это выглядит как довольно большой код, так как кажется, что он обходит весь смысл спрайта, который заключается в уменьшении количества запросов ресурсов в данном цикле загрузки страницы.

Что может происходить:

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

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

Я ценю ваши мысли / предложения.

Приветствия

Skone

Ответы [ 2 ]

4 голосов
/ 20 ноября 2009

Итак, после обширных поисков я понял, как решить проблему.

Допустим, например, что я создаю спрайт и использую css следующим образом:

.icon { 
   background: transparent url(/media/common/images/sprite.gif) scroll no-repeat 0 -33px;
}

.logo {
   background: transparent url(/media/common/images/sprite.gif) scroll no-repeat 0 -10px;
}

В Firefox это вызовет два запроса на это изображение, в отличие от одного запроса на изображение. Исправление, соответственно, состоит в том, чтобы консолидировать css-правила как таковые:

.sprited {
  background: transparent url(/media/common/images/sprite.gif) scroll no-repeat 0 0;
}

.icon { 
   background-position: 0 -33px;
}

.logo {
   background-position: 0 -10px;
}

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

В любом случае, надеюсь, это окажется полезным для другого спрайтера!

Редактировать : После небольшого дополнительного тестирования это фактически происходит только в Mozilla Firefox (независимо от платформы). Safari и IE интерпретируют несколько ссылок на одно и то же изображение и делают один запрос, тогда как Firefox, по-видимому, делает уникальный запрос для каждого изображения, связанного с помощью CSS.

Я понимаю, что это, вероятно, не определенно понимается как ошибка, но в эпоху, когда браузеры конкурируют за то, чтобы быть помеченными как самые быстрые - кажется потенциальным улучшением для Firefox!

Как вы думаете, ребята, я должен отправить это в Mozilla как ошибку?

1 голос
/ 17 сентября 2009

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

Во-первых, концепция максимального количества соединений. Браузеры устанавливают это по-другому. В связи с этим может быть возможно, что Firefox / другие браузеры будут пытаться загрузить один и тот же ресурс на нескольких соединениях, пока одно из них не будет успешным, тогда как Safari пробует только одно соединение для данного ресурса.

Во-вторых, Safari делает только один звонок? Или это только сообщение об одном успешном звонке? То есть Safari делает 4 запроса для данного ресурса, и первый из них завершается, поэтому остальные игнорируются и не сообщаются.

В-третьих, Safari просто быстрее? Попробуйте увеличить изображение или загрузить через медленное соединение в Safari, чтобы увидеть, будет ли у него та же «проблема», что и в других браузерах.

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

Еще одно преимущество спрайтов, не связанных с http-запросами, связано с интерактивным лагом. В прошлом браузеры IE загружали изображения только после того, как они были показаны на элементе, например, при наведении, создавая задержку в состоянии наведения. Спрайты решили эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...