Как стать автором
Обновить

Комментарии 19

А как давно была сделана эта работа?

Как я слышал и сталкивался, поисковый движок того же яндекса или гугла, даже несмотря на большие изменения или оптимизацию сайта, далеко не сразу реагирует

Быть может, через 2-3 недели эффект немного «аукнется»?

Guetzli внедрили в 2017 году. Тогда оно никак не сказалось на посещаемости.

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

Мы это делаем в формате "не увеличивать долг". Добавили вещь, которая утяжеляет сайт на X, запомнили, что надо это X чем-нибудь скомпенсировать. Потом устроили субботник и скомпенсировали.

У меня в электронной библиотеке тоже есть задача динамического сжатия PDF-страниц и обложек ресурсов.
Обложки выводятся React, вначале подставляется URL на кешированное значение обложки, если его нет, срабатывает fallback на динамическую генерацию нужной ширины. Сгенерированные обложки кладутся в кеш и в следующий раз обращение попадет в кеш и отдастся напрямую nginx.

Из форматов если исходный SVG, то отдается SVG. Если исходник не в SVG, то если браузер поддерживает, отдается webp, а если не поддерживает, то PNG или JPG в зависимости от того, в каком формате исходник (PNG на случай если в исходном PNG есть прозрачность). Про AVIF думал, но пока долго динамически генерировать, не хочется, чтобы на сервер слишком большая нагрузка пришлась.

По поводу сжатия, у меня WebP дает те самые 20-25% что гугл и обещал по сравнению с JPEG при, как правило, лучшем качестве.

Про devicePixelRatio не понял в чем проблема прочитать его из JS и выставить правильный URL. srcset я не использую именно из-за fallback при промахе мимо кеша: при промахе надо динамически подставить другой URL и в это время и devicePixelRatio известен.

Также есть забавный момент, что реализован собственный аналог loading="lazy" так как он лениво загружает когда изображение выходит за пределы экрана по вертикали, а когда по горизонтали (горизонтальный скролл), то все равно грузит. Ну и не очень устраивало в какой момент браузер решает подгрузить изображение.

AVIF пока не использую так как слишком большая нагрузка и у меня обложки в кеш не на все время попадают, а чистятся если место под кеш закончится (первым удаляются обложки к ресурсам, которые давно не открывались). Думаю как-нибудь стоит потыкать в видюхи Intel ARC, может они смогут аппаратно генерить AVIF через аппаратный кодировщик?

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

У нас используется server side rendering. Поэтому разрешение дисплея надо знать до того, как содержимое уедет на клиента. Ради этого раньше была вся возня с cookie, в которой сохраняли pixel ratio. И вдвое больше вариантов кэшируемой страницы.

"Навар" от webp при обычных jpeg (сформированных libjpeg-turbo), конечно, выше. Guetzli динамически подбирает параметры cжатия jpeg так, чтобы потери были в тех местах, где они незаметны. Поэтому у Вас 25%, а у нас 15% – мы 10 процентных пунктов получили на guetzli.

А про расход CPU да, непреятно. Это у нас CPU условно бесплатное, т.к. сервера наши собственные, ядер и памяти много, счёт за электричество – константа. А вот если на ходу генерировать, да ещё и места нет для AVIF под все 100% изображений, то проблема.

А какую-то часть кода из SSR исключить нельзя, чтоб она так и передалась как <script>..?

Вообще с бесплатностью CPU история более сложная: если на сервере рендеринг утилизирует все ядра, значит отвечать сервер на другие (конкурентные) запросы будет медленнее и начнут падать показатели по скорости загрузки страниц.

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

Можно, но браузер сейчас может грузить картинки параллельно с загрузкой javascript, причём это окончательные картинки (js их ни на что не поменяет). А так получаются строго две стадии: грузим страницу, потом грузим js и только потом грузим картинки. Или, что ещё хуже – грузим страницу со ссылками на одни картинки, браузер пошёл уже какие-то из них качать, а тут мы решили, что умнее, и подменили ему картинки на другие.

Кроме того, с SSR столько проблем, что лучше не усложнять.

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

Ну собственно, это одна из причин реализации собственного loading="lazy".

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

Был когда-то инцидент – разваливалась вёрстка в android browser 4.4 (возможно, до сих пор так и разваливается, не проверял, т.к. это уже музейный экспонат). Можно было узнать, что вёрстка развалилась, по вычисленной ширине страницы. Она была сильно больше, чем надо. При обнаружении можно было послать соотв. сигнал на сервер и посчитать, сколько таких в сутки имеем. Если меньше 10, то ничего не делаем :)

А тут просто не было, например, атрибута src, браузер и не знал, что надо что-то качать. Но размеры обложки фиксированные, поэтому ничего не поползло. Как узнать, что посетитель увидел дырку?

Ну отслеживать не сложно. Координаты изображения можно узнать от верха экрана. Высота и ширина экрана известны. Математика уровня 5 класса.

Тут надо пояснить проблему и почему именно такое решение. Вот пользователь схватил скролл и проскролил одним рывком 100 обложек. При классическом подходе или с loading="lazy" попав в вьюпорт они начнут все отображаться. Но встанут в очередь и будет единовременно в процессе загрузки не более 6 (так как столько потоков по умолчанию в браузерах). И все, пока все эти 100 не загрузятся по 6 штук, 101 обложка, до которой домотал пользователь, грузиться не будет. А сколько это времени займет? Ну если одна обложка по 50к, то 5 Мб пока не скачается...

То есть если пользователь резко крутанул скролл, он и должен увидеть заглушку (если она предполагается на время загрузки) и лишь когда перестанет быстро мотать заглушки постепенно (по 6 шт) сменятся обложками.

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

То есть, если всё хорошо, то да, ленивый скролл хорошо оптимизирует трафик. А вот если не все 100% сценариев учтены, то как узнать, что у кого-то так и остались заглушки?

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

А на фронте особо нечему ломаться, главное оттестировать непосредственно сам алгоритм ленивой загрузки с fallback при ошибке.

Мы то же оптимизируем.

https://habr.com/ru/company/ru_mts/blog/645305/

Только механизм чуть более хитрый. В дом ничего лишнего не генерирует. Но картинку запрашиваем в зависимости от размера экрана. В итоге выигрыш до 10 раз доходит по размеру картинок на странице.

Да, это здорово. Мы не стали в этом направлении идти из-за SSR. А заранее знать, что браузер умеет, а чего нет, невозможно. Точнее, можно вести коллекцию user agent и (почти) не ошибаться, но это не наш метод.

А 10 раз, это, наверное, от исходного изображения. А мы за точку отсчёта брали уже масштабированные картинки при помощи libjpeg-turbo.

Раз пошла речь за avif, то у кого CentOS8, вот репозитарий с libavif-tools (avifenc), чтоб руками не собирать: https://elibsystem.ru/node/641

Скачал патч, наложил и перекомпилил библиотеку. Буду теперь экспериментировать с webp на своём сайте. Спасибо)

Отрадно видеть, что не мы одни бьёмся с "проклятием python 2.7" :)

есть хорошая статья, про web, avif, jpeg. мораль проста: webp не так хорош, как о нём нарассказывал google, при условии что вы сжимаете jpeg специальным оптимизированным кодеком (и это не обязательно guetzli, я тестил MozJPEG из статьи и он работает мгновенно) ну и вам не нужна прозрачность, на шакальном качестве на сколько помню webp немного лучше. по этому мозилла так долго не включала у себя его поддержку. кстати есть ещё момент: а как быстро отрисовываются картинки на клиенте с разных кодеков, jpeg тут наверняка самый оптимизированный, возможно для телефона это будет иметь какой-то смысл

https://medium.com/@inna_netum/действительно-ли-webp-лучше-jpeg-91639d852035

Да, очень быстро, буквально, на третьей-четвёртой картинке мы напоролись на то, что webp даёт больший по размеру файл, чем guetzli. Не стали бы заморачиваться вообще, но понадобилась прозрачность вот для этой страницы.

А про скорость отрисовки даже думать не хочется... Помимо времени работы кодека имеет ведь значение и количество задействованных кодеков. Одно отдать в jpeg, другое – в webp, а третье – в avif, и у телефона уже есть много разнообразной работы.

Есть ещё один момент. Webp разные участки картинки сжимает по-разному. Я когда тестировал на вот этом изображении, считал, сколько прожилок у листочков видно. Получалось, что при том же размере файла листочки были чуть-чуть "прожилистей". А avif в режиме 4:4:4, когда оно по размеру немного больше, чем jpeg, – совсем хороши. То есть, внутренний маньяк-перфекционист может быть доволен при переходе на новые форматы даже без экономии места.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории