Актулизировано на момент 03.12.2018 Док несколько потерял в актуальности, см презентацию https://docs.google.com/presentation/d/1bw0ypsrdyC2l35Z-h65D09ABQDSZ_Ecfp02-zE6Fmqc Если кратко то brotli 0 в 4 раза быстрее чем gzip 1, при том же сжатии И brotli 4 столь же быстр как gzip 1 на круче чем gzip 9
- gzip 1 - минимальный уровень сжатия gzip, результат .gz
- gzip 9 - максимальный уровень сжатия gzip, результат .gz
- zopfli - отдельный алгоритм совместимый с распаковщиком gzip, результат .gz
- brotli 11 - полностью новый формат, 11 это максимальный уровень сжатия, результат .br
Не рассматривается - sdch(нет поддержки в современных браузерах), попытки запустить gzip > 1, zopfli, brotli на лету без пребилда сжатых файлов (для нас не актуально, очень много данных)
- gzip 1 - быстр, мало влияет на затраты cpu, но всё-же влияет
- gzip 9 - медленнее примерно в 10 раз чем, gzip 1
- zopfli - чудовищно медленный, в 20-50 раз медленнее чем gzip 9. Для примера Json на 16 мегабайт сжимался 273 секунды
- brotli 11 - очень медленный, в 2-10 раз быстрее zopfli, но всё ещё на порядок медленне gzip 9.
- gzip 1 - выигрыш от сырых данных 50-90%
- gzip 9 - выигрыш от gzip 1 15-45%
- zopfli - выигрыш от gzip 9 4-7%
- brotli 11 - выигрыш от zopfli 8-65%
- gzip 1 -
- gzip 9 - примерно равен gzip 1
- zopfli - примерно равен gzip 1
- brotli 11 - быстрее примерно на 30% (по данным linkedin, я не тестил)
Современные браузеры и веб сервера поддерживают сжатие данных прозрачно для потребителя, передавая по сети сжатые данные. С точки зрения JS никак не видно, отдали нам запакованные данные или нет. Распаковка происходит потоково, при приёме данных, для JS это выглядит так, как будто скачивается сразу распакованный контент. Все алгоритмы таковы что распаковка не создаёт существенной нагрузки на клиента.
При скачивании файла, в графе size будет указано непосредственно передаваемое по сети значение, т.е. запакованный размер. Чтобы понять с каким сжатем скачался этот файл, нужно включить отображение заголовка Content-Encoding из ответа сервера, правой кнопке по заголовку столбца, отметить флажком Responce Headers -> Content-Encoding, см картинку http://service.crazypanda.ru/v/clip2net/k/q/mo48yPT815.png
Бразуер, умеющий работать со сжатыми данными, делая запрос указывает заголовок, например: Accept-Encoding: gzip, deflate, br
. Веб сервер, который сконфигурирован на работу со сжатыми данными, смотрит на этот заголовок, и если он умеет отдавать один из форматов которые умеет принять браузер, то он выберет какой-то(тут вопрос к серверу, по идее должен выбирать тот что лучше сжимает, т.е. в порядке увеличесния степени сжатия deflate, gzip, br) и шлёт эти данные с указанием заголовка, например Content-Encoding: gzip
по этому заголовку браузер понимает как распаковать данные. Если общего формата сжатия нет, то сервер отвечает беp Content-Encoding
заголовка и просто отправляет сырые данные.
Чтобы веб сервер отдал сжатый файл, он должен откуда-то его взять. Если просто включить gzip сжатие на Nginx то он будет каждый раз на лету сжимать его перед отправкой каждому клиенту. Он не кеширует сжатый результат по умолчанию. Если просто включить gzip on;
то он будет сжимать только MIME type text/html
и если вы хотите жать что-то ещё, то нужно отдельно настроить определение MIME type по расширению файла, а уже потом включить этот MIME type в категорию сжимаемых.
По умолчанию Nginx сжимает gzip 1, это минимальный уровень, он быстр, и эффективен, даёт выигрыш в 2-10 раз (т.е. выигрыш по сжатию 50-90%), в зависимости от контента. При больших нагрузках даже deflate минимального уровня и gzip 1 могу обрушить всё, тщательно протестируйте и вонзайте только с полным пониманием того что вы делаете. Поднимать уровень сжатия на лету категорически не советую, т.к. выигрыш относительно первого уровня 10-45% (разов уже нет) при росте времени сжатия в 10 раз.
Не нужно сжимать те форматы которые уже сжаты, например png, jpg, swf, mp3, видео и тп. Сжатие уже сжатых форматов не полезно, а вредно, их размер незначительно увеличивается и добавлается нагрузка на распаковку. Вам необходимо выяснить какие форматы используются в вашем приложении и понять что нужно сжимать о что нет, наилучший способ - проверить руками и составить табличку(см внизу мою таблицу). Js файлы жмутся очень хорошо (brotli в 30 раз примерно ), в принципе выигрыш от сжатия больше чем от минификации. Для brotli минифицированная версия jquery позволяет выиграть ещё 30% по сравнению с jquery со стрипнутыми комментами но без минификации.
Все форматы при сжатии очень маленьких файлов дают накладные расходы или очень маленький выигрыш, сжимать стоит файлы от 5-10 килобайт. Меньше особо жать нет смысла. Например файл в 32 байта только вырастает в размере.
Любое сильное сжатие стоит использовать с предсжатым файлом.
Для gzip есть static_gzip, это отдельный официальный модуль требующий перекомпиляцию nginx. Что примечательно он умеет gunzip, соответсвенно можно хранить только gzip версию и делать распаковку на лету для тех клиентов которые не умеют gzip.
Для brotli есть плагины от google и cloudflare. Они умеют отдачу предварительно сжатого файла. Т.к. анпак бротли быстрее, то было бы круто отдавать анпак распаковывая brotli, но я не знаю, есть поддержка для этого или нет, и как это работает.
универсально как я понимаю можно просто сделать в nginx перенаправление и отдать архивированный контент и добавить хедер, это не требует плагинов, хорошо ложится на кеширующие статики, но не позволяет проверить имеется ли файл в наличии, они сразу должны быть для всего. Это выглядит самым адекватным на самом деле, но лично я это не проверял.
Все совеременные десктопные браузеры (Chrome, FireFox, Edge) с некоторых версий, поддерживают brotli. Подозреваю около 80-90% с его поддержкой. Незначительно количество браузеров поддерживают только gzip, и совсем экзотика и всякие прокси не поддерживают сжатие. Формат без сжатия надо всё-таки продолжать поддерживать.
zopfli - в топку, brotli огонь, gzip 9 тоже неплох. Для продакшна только статик препакед.
Принятая схема распространения контента указана во внутренней документации компании. В все файлы dds проекта жмутся при помощи brotli в три раза
Для js файлов на фоне космического коэффициента сжатия brotli считаю ненужным минификацию.
- Про то что для gzip время распаковки существенно не зависит от уровня сжатия https://stackoverflow.com/questions/28452429/does-gzip-compression-level-have-any-impact-on-decompression
- Обзор от linkedin, разные степени сжатия brotli, zopfli и скорость распаковки https://engineering.linkedin.com/blog/2017/05/boosting-site-speed-using-brotli-compression
- Документация NginX про gzip https://docs.nginx.com/nginx/admin-guide/web-server/compression/
- Информация о том как подключить brotli к Nginx https://habr.com/post/310200/
- https://en.wikipedia.org/wiki/Zopfli
- https://en.wikipedia.org/wiki/Brotli
- Про sdch в том числе https://айри.рф/blog/sdchbrotli-или-как-пожать-ваш-html-контент-в-20-раз/
- Моя таблица с анализом типовых файлов для сковертированной версии Запорожья, + unity билд покера для интереса. https://docs.google.com/spreadsheets/d/1oSC7q4AiC1HFh3IEs7y2Ej4aEqyqczPrMG-ltSrWKAo/edit?usp=sharing