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

Наша команда очень рада, что после долгой вынашивания нам удалось запустить новую мобильную версию нашего новостного сайта https://i.stuff.co.nz. При этом нам пришлось решить ряд проблем, многие из которых мы знали, что столкнемся, в том числе переход на HTTPS (наша домашняя страница обслуживается через HTTPS, хотя наши страницы статей еще нет), интеграция сторонних содержания и удовлетворения требований различных заинтересованных сторон (нашей редакционной группы, наших пользователей и наших рекламодателей).

Тем не менее, было несколько проблем, которые появились позже в Safari на устройствах iOS, которых мы не ожидали, и которые вызвали у нас значительное беспокойство и разочарование.

В этом посте мы рассмотрим ошибку конвейерной обработки iOS и оставим наш опыт применения Apple директивы upgrade-insecure-requests в Content Security Policy для более позднего поста.

Ошибка конвейерной обработки Apple iOS

Оказывается, в iOS существует ошибка конвейерной обработки по крайней мере, начиная с iOS 5, которая проявляется в том, что изображения время от времени и (случайно меняются местами) на странице, и которая была источником разочарования для других разработчиков.

Ошибка

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

Наша команда слышала об этой проблеме ранее, но предполагала, что, поскольку она была изначально замечена в iOS 5 (т.е. пять поколений iOS назад), к настоящему времени она решена — однако это оказалось не так.

Во время внутреннего тестирования, которое мы провели перед запуском нашего нового сайта в контролируемой бета-версии для 10% наших пользователей, мы не видели (или, возможно, не замечали) этой проблемы, и мы запустили наш новый сайт в бета-версии в блаженном неведении, что мы ' д скоро столкнуться с этой проблемой.

Запуск

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

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

Чтобы усугубить ситуацию, Apple выпустила iOS 10 примерно в то же время, когда мы запустили нашу бета-версию, и мы не были уверены, была ли проблема, которую мы видели, существующей проблемой в предыдущих версиях iOS, или она только что появилась / всплыла в iOS 10.

Самый неприятный вид бага

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

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

Наша домашняя страница больше, чем мы хотели бы в идеале с точки зрения доставляемого размера, включая более 200 запросов, из которых около 100 — изображения (включая URI данных). Из них около 45 представляют собой фактический редакционный контент, а остальные состоят из рекламных изображений, пикселей отслеживания, значков и тому подобного.

Таким образом, учитывая относительно большую загрузку страницы (с точки зрения количества запросов и количества изображений), мы подозреваем, что создаем условия для проявления ошибки конвейерной обработки iOS. Возможно, Apple не исправила эту ошибку ранее, потому что с ней столкнулось недостаточное количество сайтов; однако наш сайт, хотя и довольно большой по количеству и общему размеру запросов, не так уж нетипичен по сравнению с другими крупными новостными сайтами:

https://www.theguardian.com/international
всего запросов: 164
запросов изображений: 76

https://m.washingtonpost.com/
всего запросов: 130
запросов изображений: 40

http://mobile.nytimes.com/international/
всего запросов: 151
запросов изображений: 69

Поиск решения

Учитывая, что наш новый мобильный сайт включает в себя ряд различных методов, которые не использовались в предыдущей версии, существует довольно много переменных, которые могут иметь некоторое отношение к проявлению ошибки конвейерной обработки / замены изображений, и поэтому мы несколько вещей, чтобы попытаться смягчить/устранить ошибку:

Политика безопасности контента

Политика безопасности контента — это механизм, который позволяет сайту указывать браузеру через HTTP-заголовок, какой тип политики безопасности следует применять к различным частям страницы.

Есть много директив, которые можно использовать для создания заголовка CSP, как подробно здесь, и мы подозревали, что некоторые из директив, которые мы использовали в нашем заголовке CSP, могли создавать проблемы для Apple.

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

Разделение домена

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

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

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

Отключение проверки активности

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

HTTP 2

Одна из теорий, которую мы сформировали, заключалась в том, что, учитывая, что ошибка конвейерной обработки iOS существует уже довольно давно и, вероятно, связана с операциями, выполняемыми на относительно низком уровне сетевого стека, вполне вероятно, что это проблема, связанная с использованием Apple HTTP 1.1. .

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

Решение

К счастью, наша догадка (и выбор времени, учитывая, что HTTP 2 теперь готов к внедрению) оказалась верной, и, отдавая наши изображения из одного поддомена с использованием HTTP 2, мы обнаружили, что больше не видим проблемы в последних версиях iOS.

HTTP 2 означает, что страница должна обслуживаться через HTTPS, но, к счастью, это то, что мы уже решили сделать для нашей домашней страницы и страниц разделов; наши страницы статей по-прежнему обслуживаются через HTTP, но поскольку на странице статьи обслуживается гораздо меньше изображений, мы вряд ли столкнемся с ошибкой конвейерной обработки изображений.

Переход на HTTPS имеет смысл, поскольку он обеспечивает лучшую безопасность и позволяет использовать HTTP 2. Однако для таких новостных организаций, как наша, это также может быть проблематично, поскольку мы полагаемся на сторонних поставщиков для определенного содержимого страниц, такого как реклама и аналитика, и эти третьи стороны могут еще не иметь возможности надлежащим образом обслуживать свой контент через HTTPS — если наша страница обслуживается через HTTPS, а сторонний поставщик загружает контент на нашу страницу с помощью HTTP, мы можем получить предупреждения о смешанном содержании, что означает что браузер показывает, что наша страница не защищена.

Wired.com недавно написал хороший пост о своем долгом пути к использованию HTTPS на своем сайте и рассказал о некоторых проблемах, с которыми они столкнулись при получении контента от сторонних поставщиков для правильной работы на HTTPS.

Интересно, что после более глубокого изучения практики других новостных сайтов мы замечаем, что некоторые из них — такие как Нью-Йорк таймс и Вашингтон пост — также размещают свои изображения (а в некоторых случаях такие как New York Times). York Times только свои изображения) через HTTP 2, поэтому вполне возможно, что их команды также столкнулись с этим решением той же проблемы.

Подведение итогов

Как вы поняли из вышеизложенного, мы рады, что смогли использовать HTTP 2 для устранения ошибки конвейерной обработки iOS.

В будущем мы постараемся больше использовать HTTP 2, хотя потребуется некоторое время, чтобы убедиться, что весь наш сайт может обслуживаться через HTTPS.

Хотя мы по праву гордимся выпуском нашего нового мобильного сайта, настоящая мотивация для написания этого поста — помочь всем, кто в будущем будет бороться с проблемой подкачки изображений. Как упоминалось выше, сейчас мы находим сайты, которые передают свои изображения через HTTP2, предположительно для решения этой проблемы. Когда мы столкнулись с этой проблемой, мы были бы очень рады найти кого-то, у кого был подобный опыт, и найти решение, которое сработало.