Хорошая или плохая идея: замена всех изображений на мобильном веб-сайте на CSS-свойство content: url () для дисплеев Retina.

В настоящее время мы создаем веб-сайт для мобильных устройств. Поддерживаемые операционные системы и браузеры должны быть:

  • Android 4.x (стандартный браузер, Google Chrome)
  • iOS6 + (Safari, Google Chrome)

Чтобы также поддерживать дисплеи с высоким разрешением, мы оценили различные методы и библиотеки для автоматической замены изображений их подвесками с высоким разрешением:

Попытка 1: retina.js http://retinajs.com/

Первая попытка заключалась в использовании обычного тега <img> типа этого: <img src="foo.png"> и использования retina.js, чтобы он автоматически заменял атрибут src именем изображения сетчатки ([email protected]). Это работает, но имеет два недостатка: во-первых, это создаст нежелательные накладные расходы, потому что будут загружены как исходное, так и изображение сетчатки глаза, а во-вторых, если изображение сетчатки недоступно, это вызовет множество ошибок 404 в журнале сервера, что мы не хотим.

Попытка 2: picturefill.js https://github.com/scottjehl/picturefill

Этот фреймворк использует странную HTML-разметку на основе <span> элементов. Мне кажется, что автор попытался имитировать предложенный элемент <picture>, который (пока что) не является стандартом, см. http://picture.responsiveimages.org - мне не нравится такой подход из-за странной разметки. Для меня не имеет смысла семантически описывать изображения с промежутками.

Попытка 3. Заменить изображения с помощью свойства CSS background-image

Иногда я вижу, как люди используют медиа-запросы CSS для обнаружения дисплеев сетчатки, а затем устанавливают фоновое изображение в div (или подобном элементе) с изображением более высокого или низкого разрешения. Мне лично не нравится этот подход, потому что он полностью препятствует созданию семантически хорошей разметки à la <img src="foo.png">. Я не могу представить, как создать веб-сайт только с помощью div, а затем установить все изображения в качестве фоновых - это очень странно.

Попытка 4. Установить изображения с помощью CSS-свойства content: url (...)

Как предлагается здесь, Is Можно ли установить эквивалент атрибута src тега img в CSS? кажется возможным перезаписать атрибут src в тегах img через CSS, используя свойство content:url(). Вот план: мы устанавливаем теги img для каждого изображения с прозрачным пустым размером 1x1 png, указанным в его атрибуте src, например: <img id="img56456" src="transp_1x1.png" alt="img description">. Теперь это семантически нормально, а также применимо к валидатору W3C. Затем мы загружаем таблицу стилей CSS, которая устанавливает все изображения на веб-сайте с помощью Media Queries.

Пример:

#img56456{content:url(foo.png)}
@media (-webkit-min-device-pixel-ratio: 2){ 
    #img56456{content:url([email protected])}
}

Теперь этот подход работает довольно хорошо:

  • Без накладных расходов
  • Сплошная разметка
  • Работает на необходимых устройствах / браузерах
  • SEO для изображений здесь не требуется

Теперь, может ли этот подход вызвать какие-либо побочные эффекты, о которых мы не думали? Я просто спрашиваю, потому что знаю, что это работает, но "кажется" странным устанавливать все изображения через CSS, и я также нашел этот комментарий к этому подходу на SO Можно ли установить эквивалент атрибута src тега img в CSS? :

«Стоит добавить, что даже в браузерах, поддерживающих назначение содержимого для img, он меняет свое поведение. Изображение начинает игнорировать атрибуты размера, а в Chrome / Safari оно теряет такие параметры контекстного меню, как« Сохранить изображение ». Это связано с тем, что присвоение content эффективно преобразует img из пустого замененного элемента во что-то вроде <span><img></span> "

Могло ли это быть проблемой? (Я не заметил никаких проблем с размером, и контекстное меню не является обязательным)


person Timo Ernst    schedule 29.01.2014    source источник
comment
Два других варианта включают всегда обслуживая сетчатку, затем позволяя браузеру перейти на более раннюю версию и используя спрайты с медиа-запросами со смещением позиции. Я предпочитаю большие и маленькие изображения соответственно.   -  person bishop    schedule 29.01.2014
comment
@bishop Я тоже думал о том, чтобы всегда обслуживать изображение сетчатки, но накладные расходы для устройств без сетчатки слишком высоки, имхо, особенно на мобильных устройствах.   -  person Timo Ernst    schedule 29.01.2014
comment
Да, но вы получаете кеширование, что для меня важнее. Кроме того, если вы оптимизируете двукратные изображения, штраф будет не таким существенным. Я бы также добавил, что это нужно обрабатывать индивидуально: SVG, файлы шрифтов, формы CSS и спрайты должны быть предпочтительнее перед serve-retina-and-downsample.   -  person bishop    schedule 29.01.2014
comment
@bishop Насколько я могу судить, кеширование работает должным образом ..   -  person Timo Ernst    schedule 29.01.2014
comment
Я вообще не считаю накладные расходы на понижение качества изображения с ретина-первым запретом, имо. Сохранение для сетчатки обычно позволяет сохранять изображения в формате JPEG с качеством 0–10% и при этом хорошо выглядеть как на устройствах с сетчаткой, так и без нее. Размер при качестве 0-10% сопоставим с качеством 70-80% на изображении вдвое меньшего размера. Сказав это, если вы не можете этого сделать (например, PNG) и SVG не подходят, то единственная реальная проблема здесь заключается в том, что вы загружаете оба изображения для устройств Retina, что само по себе является проблемой накладных расходов.   -  person niaccurshi    schedule 30.01.2014
comment
@niaccurshi Я пытался сказать: если вы всегда показываете свое изображение сетчатки на всех устройствах (даже на тех, у которых нет дисплея сетчатки), вы получите накладные расходы на устройствах без сетчатки, потому что вы обслуживаете на 50% больше данных. чем способен показать их дисплей.   -  person Timo Ernst    schedule 31.01.2014
comment
Я понимаю, что @Timo, но я не верю, что возникнет проблема с накладными расходами, если вы предоставите одно изображение, оптимизированное для сетчатки глаза, на все устройства. Применив этот метод раньше, я обнаружил, что хорошо оптимизированное размерное изображение сетчатки лишь незначительно (не на 50%) тяжелее, чем такое же хорошо оптимизированное размерное изображение без сетчатки. Очевидно, это должно быть оговорено тем фактом, что это зависит от изображения и формата файла, который вы используете!   -  person niaccurshi    schedule 02.02.2014
comment
@niaccurshi Я понимаю вашу точку зрения! Однако, например, когда я просматриваю веб-страницы, сидя в туалете (где качество сигнала действительно очень плохое), я часто ценю это, когда веб-сайт предоставляет изображения с минимально возможным кб. Я называю это инициативой «туалет прежде всего» :-) - Я лично считаю, что сетевые данные для мобильных устройств должны быть сведены к абсолютному минимуму, потому что каждый байт имеет значение, если качество сигнала плохое.   -  person Timo Ernst    schedule 03.02.2014
comment
@ Тимо, я согласен. Но более старые или менее совместимые со стандартами телефонные браузеры будут загружать ОБЕ изображения, а не только одно. Я хочу сказать, что правильная оптимизация jpg-изображения на сетчатке сделает ваше изображение, особенно если это более сложный jpg-файл, того же размера, что и изображение без сетчатки. Вы ничего не сохраняете, и вам нужно поддерживать два файла. Не существует единого решения, подходящего для всех, но иногда вам просто не нужны два файла для сохранения размера файла :) Если у меня будет время, я скоро приведу пример, показывающий это.   -  person niaccurshi    schedule 04.02.2014
comment
@niaccurshi Зачем браузеру загружать оба файла? Это именно то, чего я пытаюсь избежать :-)   -  person Timo Ernst    schedule 06.02.2014
comment
Думаю, это ответит на некоторые вопросы: timkadlec.com/2012/04 / media-query-asset-download-results   -  person niaccurshi    schedule 09.02.2014
comment
@niaccurshi Очень классная ссылка! Особенно тест номер 3, когда изображение не загружается, когда родительский элемент настроен на отображение: ни один не выглядит интересным.   -  person Timo Ernst    schedule 11.02.2014
comment
Я не понял, почему вы думаете, что у рисунка странная разметка. Мы используем его в нашем проекте, и он очень хорошо выполняет свою работу без каких-либо недостатков. Если вы хотите использовать его только для изображений сетчатки, вам на самом деле не нужны никакие элементы span или picture. Все, что вам нужно, это тег img с атрибутом srcset. например: <img srcset="normal.jpg, retina.jpg 2x" height="50" width="50">. Напомним, что в Chrome теперь есть встроенная поддержка элемента изображения и атрибута srcset.   -  person Deniz    schedule 29.10.2014
comment
@DenizToprak Да, новая картина потрясающая, и я полностью ее рекомендую. Старая версия опиралась на странную структуру разметки, основанную на ‹span›.   -  person Timo Ernst    schedule 30.10.2014


Ответы (2)


Есть много преимуществ и недостатков, но одним из недостатков является то, что изображение не будет кэшироваться. Это больше проблема на мобильных устройствах, где Интернет обычно медленнее и дороже для пользователя (если используется соединение для передачи данных, а не Wi-Fi).

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

person S..    schedule 29.01.2014
comment
Вау, спасибо за подсказку по поводу кеширования. Если это правда, то методика определенно не годится :-( - person Timo Ernst; 29.01.2014
comment
Я только что протестировал это в Google Chrome (версия для ПК) и, насколько я могу судить, изображение, которое предоставляется через css content:url(), правильно кэшируется, когда я обновляю страницу. По крайней мере, в Chrome. - person Timo Ernst; 29.01.2014
comment
Просто также протестирован на iPhone (iOS7), и кеширование, похоже, работает правильно. - person Timo Ernst; 29.01.2014
comment
Можете ли вы предоставить ссылку на эту претензию? Нет причин, по которым применение ресурса с использованием разных методов DOM должно иметь какое-либо влияние на кеширование - это нечто среднее между запрошенным ресурсом и браузером. - person Barney; 30.01.2014
comment
Я думаю, что лучше, чтобы сервер доставлял совпадающие изображения. - person Mirko Brunner; 02.02.2014
comment
@MirkoBrunner Хороший вопрос! Это звучит как хороший метод, но требует некоторой дополнительной работы, поскольку для серверной части потребуется дополнительная логика, которая анализирует пользовательский агент клиента, а затем проверяет его по базе данных устройства, чтобы решить, является ли это устройством Retina или нет. - person Timo Ernst; 03.02.2014
comment
@Timo Да, нужно еще немного поработать. Но лучшее решение для клиентов / пользователей. Я быстро обнаружил, что класс PHP на GitHub (github.com/serbanghita/Mobile-Detect) . - person Mirko Brunner; 03.02.2014

Новая версия picturefill http://scottjehl.github.io/picturefill/ не полагается на <span> больше нет. Вместо этого он просто использует официальный атрибут srcset HTML5 и имитирует его поведение, если браузер его не поддерживает, так что для меня это идеальное решение спустя некоторое время.

Использование свойства CSS content:url(...) было отличной идеей, но это также сделало вещи немного сложными и хакерскими.

Итак, отвечу на свой вопрос: Нет, это плохая идея. Использование новой версии Picturefill - лучшее решение. Вы даже можете удалить его через некоторое время, когда новые версии всех основных браузеров поддерживают атрибут srcset, и вы по-прежнему будете соответствовать стандарту. http://caniuse.com/#search=srcset

Пример:

<img srcset="examples/images/small.jpg, examples/images/medium.jpg 2x" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<script src="picturefill.js"></script>
person Timo Ernst    schedule 30.10.2014