При выполнении задания стали возникать вопросы, вот несколько уточнений.
NGrok в бесплатной версии проксирует траффик только по HTTP/1.1, поэтому если вы выставите свой локальный сервер в интернет через NGrok и выполните анализ WebPageTest, то там всё будет работать через HTTP/1.1.
- Скриншот
DevToolsс работающимserver-push - Файлы кода
dev.to, которые вы изменили, чтобы сделатьserver-pushкартинок (комитьте итоговые версии файлов, затронутых изменениями) - Конфиг
NGinx - Описание со сравнением восприятия работы сайта с
inline-картинками, обычными картинками иserver-pushedкартинками (попробовать разные варианты локально) - Гипотезы о возможных оптимизациях
dev.toпо результатам анализа отчётаWebPageTestна их проде; подумайте в контексте интуиции работы сserver-push, которую вы получили - Бонус про
Falcon
В этом задании немного попрактикуемся с HTTP/2 в Rails.
Польза:
- научиться настраивать
HTTPSдля локальногоRails-приложения - научиться настраивать
HTTP/2reverse proxyс поддержкойserver-push - научиться делать
server-push, сравнить его сinlining
Работать будем на примере проекта dev.to из задания №3.
Ресурсы:
- http://railscasts.com/episodes/357-adding-ssl?view=asciicast - старый, но очень понятный
RailsCast - https://github.com/FiloSottile/mkcert - инструмент для настройки локальных сертификатов одной командой
- https://www.nginx.com/blog/nginx-1-13-9-http2-server-push/ - настройка
http2-server-pushвNGinx. - https://github.com/surma/http2-push-detect - утилита для проверки
server-push
Можно сделать с использованием mkcert
Установить или обновить NGinx.
Конфигурируем NGinx так, чтобы он принимал https-запросы https://localhost и ходил в upstream на http://localhost:3000.
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /path/to/localhost.pem;
ssl_certificate_key /path/to/localhost-key.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!EXP:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_pass http://127.0.0.1:3000;
}
}
На этом шаге браузер должен успешно открывать https://localhost
Дополняем конфиг NGinx поддержкой HTTP/2 и server-push
server {
listen 443 http2 ssl;
#...
location /{
http2_push_preload on;
#...
}
}
На главном экране в мобильном виде dev.to есть ряд картинок:
connect.svgbell.svgmenu.svgstack.svglightning.svg
Картинки из меню: connect.svg, bell.svg, menu.svg – заинлайнены.
Картинки stack.svg и lightning.svg – нет.
Попробуйте перезагружать эту страницу и посмотреть как рендерятся эти картинки при перезагрузке.
Дальше, давайте попробуем двинуться в сторону подхода HTTP/2 и не будем инлайнить svg, а подключим их как обычные картинки.
Например, image_tag("bell.svg", size: "100% * 100%")
Теперь давайте добавим server-push!
Для этого нам нужно установить специальные заголовки:
# stories_controller.rb
def index
push_headers = [
"<#{view_context.asset_path('bell.svg')}>; rel=preload; as=image",
"<#{view_context.asset_path('menu.svg')}>; rel=preload; as=image",
"<#{view_context.asset_path('connect.svg')}>; rel=preload; as=image",
"<#{view_context.asset_path('stack.svg')}>; rel=preload; as=image",
"<#{view_context.asset_path('lightning.svg')}>; rel=preload; as=image",
]
response.headers['Link'] = push_headers.join(', ')
# ...
end
На этом шаге нужно убедиться, что server-push работает.
В Chrome DevTools в панели Network вы должны увидеть, что запросы к этим картинкам делаются по протоколу h2, а Initiator = Push/Other
Ещё один способ проверить работу server-push - утилита http2-push-detect
http2-push-detect https://localhost
Receiving pushed resource: /assets/bell.svg
Receiving pushed resource: /assets/menu.svg
Receiving pushed resource: /assets/connect.svg
Receiving pushed resource: /assets/stack.svg
Receiving pushed resource: /assets/lightning.svg
Теперь поэксперементируйте, попробуйте включать и выключать server-push для тех или иных картинок и оцените, как это сказывается на их рендеринге.
Теперь, когда у вас сформировалась интуиция по работе с HTTP/2 и server-push, постройте и проанализируйте отчёт WebPageTest для сайте dev.to.
Видите ли вы какие-то возможности использовать возможности HTTP/2 для оптимизации dev.to, исходя из отчётов WPT?
Сервер Falcon https://github.com/socketry/falcon утверждает, что может сервить Rails-приложения и из коробки поддерживает HTTP/2.
Попробуйте настроить работу dev.to с server-push для Falcon.
Сделайте сравнительный бенчмарк puma и falcon на примере главной страницы dev.to.
Нужно сделать PR в этот репозиторий с вашими изменениями кода dev.to, конфигом NGinx и описанием.
В описании сравните рендеринга картинок с inlining, server-push, и без того и другого.
Напишите ваши выводы по результатам аудита dev.to через WebPageTest.
Ну и вообще, напишите о том, что интересного вы узнаете при выполнении задания.
