Работа со статикой в Badoo
Юрий Насретдинов, разработчик
Badoo• 205+ млн пользователей
• PHP-FPM: 40+ тыс запросов в сек
• 300 тыс регистраций в день
• 5 млн фото / видео в день
• 50 языков интерфейса
• 2 000+ серверов
«Статика» в Badoo• Статика — JS / CSS / картинки (фотографии пользователей хранятся отдельно)
• 100 Мб статики в репозитории
• SSI includes
• Кросс-зависимости: JS подгружает JS и CSS
• Deploy 2 раза в день
Версионирование• Не версионировать:
- полагаться на If-Modified-Since, E-Tag, …
• У всех файлов одна и та же версия: - при деплое рост трафика в 2 раза - полная инвалидация кеша клиента
• У каждого файла своя версия:- загружаются только изменения
Нет версионирования• У всех файлов нет версий и они всегда запрашиваются по одному и тому же URL
• Браузеры очень кешируют статику
• Прокси-серверы кешируют статику
• Во время деплоя часть файлов может обновиться, а часть — нет
• Пользователи обычно не жмут Ctrl+F5
Одна версия у всех файлов• Удобно: не требуется думать о версиях файлов в CSS / JS
• Надежно: не требуется анализировать зависимости, состояние всегда согласовано
• Неэффективное использование кеша клиента — при деплое весь кеш инвалидируется
Пофайловая версионность• Маркеры version(filename) — явное версионирование файлов в CSS/JS
• Цепочка зависимостей:- A -> B -> C- поменялся A, нужно дать новую версию B и C
• Сложно следить за согласованностью версий
Devel-окружение• Статика отдается через PHP и собирается «на лету»
• URL без version(…) отдают 404
• Переключатели:- включение сжатия- отключение debug-строк - (CSS only) замена #include на @import
Deploy• PHP-скрипт по обработке и загрузке файлов
• Карты:- [filename => contents_md5] - [filename => version]
• Порядок действий: - составляем зависимости [filename => […]]- находим изменившиеся файлы - перегенерируем изменившиеся файлы и их зависимости
Дополнительные возможности• Автоматическая генерация RTL-версии в
CSS
• Поддержка «include path» — можно писать include и URL до файлов с точностью до директории
• Include path — список директорий, в которых ищется файл; просматривается по порядку
Пример// something.js !
#include "funcs.js" #include "virtual:config.phtml" !
var el = document .createElement('script'); !
el.src = 'version(app.js)';
Пример
// something.css #include "head.css" !
.mydiv { background: url(version(i.png)); float: left; }
Пример (RTL-версия)
// something.css #include "head.css" !
.mydiv { background: url(version(i.png)); float: right; }
До: После:
До: После:
Спасибо за внимание! Вопросы.
Юрий Насретдинов http://habrahabr.ru/users/yourock/ [email protected]