Совместимость с браузерами
Что это такое
Совместимость с браузерами — это практика: решить, в каких браузерах должен работать продукт, выяснить, есть ли в них используемые вами возможности, и обработать те, которых нет. На практике это обнаружение возможностей вместо обнаружения браузера, осознанная матрица поддержки и запасной вариант, который разумно деградирует там, где возможности не хватает.
Почему это важно
Каждую страницу читает набор движков, которые никогда не выпускают одни и те же возможности одновременно. Сайт, предполагающий, что новейший API работает везде, тихо сломается для части аудитории — и обычно в самом незаметном месте: старый корпоративный браузер, заблокированное устройство, пользователь, который никогда не обновляется. Цена игнорирования — не падение, а тихая потеря пользователей, которые не могут выполнить задачу. Урок заслуживает отдельного места потому, что наивное решение — определять user agent и ветвиться по имени браузера — ненадёжно и быстро устаревает, а правильная техника почти ничего не стоит, если применять её с самого начала.
Ключевые идеи
Обнаруживайте возможности, а не браузеры
Спросите движок, что он умеет: в CSS для этого есть @supports, в JavaScript — проверка свойства или объекта, который вы собираетесь использовать. Обнаружение возможностей отвечает на важный вопрос и продолжает работать, когда имя браузера меняет смысл или пользователь его подделывает.
if ("IntersectionObserver" in window) {
observeVisibility(images);
} else {
loadAllImages(images);
}
Сначала запасной вариант, потом улучшение
Соберите версию, работающую везде, и уже поверх неё добавьте новое поведение. Это прогрессивное улучшение: отсутствующая возможность стоит отделки, а не функции, — и таблица стилей, которая начинается с простых значений и затем добавляет современное, достигает того же, так что браузер, не понимающий ни одного из них, всё равно что-то отрисует.
.card { width: 100%; }
@supports (display: grid) {
.card { width: auto; grid-column: span 2; }
}
Держите матрицу поддержки и выводите её из данных
Решите, какие браузеры вы поддерживаете, исходя из аналитики, договорных требований или публичного набора данных о совместимости, запишите это и настройте по нему инструменты. Матрица — вход для всех остальных решений: что транспилировать, какие полифилы включать, какой синтаксис допускать.
Транспиляция переписывает синтаксис, полифилы добавляют поведение
Инструмент может преобразовать новый синтаксис обратно в старый эквивалент, но он не может изобрести отсутствующий API, а полифил — скрипт, который его добавляет. Он стоит байтов каждому посетителю, поэтому включайте их по возможности, а не одним большим бандлом; современный вывод с небольшим legacy-бандлом для остальных — обычный компромисс.
Тестируйте во втором движке
Эмулятор показывает вьюпорт того движка, а не сам движок, поэтому настоящая работа по совместимости включает запуск страницы хотя бы в одном движке, отличном от того, в котором вы разрабатываете, и проверку против самой старой версии из матрицы поддержки, когда цена это оправдывает.
Практика
Оберните одну современную возможность в защиту
Выберите возможность, которой вы пользуетесь не задумываясь, и добавьте рядом запасной путь с обнаружением этой возможности. Заставьте запасной путь сработать, временно отключив проверку.
Готово, когда: запасной путь отрисовывает рабочую страницу, а снятие защиты делает разницу видимой в том же браузере.
Опубликуйте матрицу поддержки и сверьте с ней свой CSS
Запишите браузеры и версии, которые вы поддерживаете, затем просмотрите таблицу стилей на предмет любой возможности, отсутствующей в самом старом из них. Отметьте, что происходит там, где её нет.
Готово, когда: у каждой неподдерживаемой возможности есть либо запасной вариант, либо защита @supports, либо записанное решение принять этот пробел.
Частые ошибки
- Определение строки user agent — строка подделывается, замораживается вендорами и ничего не говорит о вашем вопросе; исправить: проверяйте саму возможность.
- Предположение, что современный API существует — страница падает до отрисовки, и запасной путь не срабатывает; исправить: защитите проверкой возможности и дайте старый путь.
- Полифилы всем и для всего — каждый посетитель платит байтами за случай, который есть у немногих; исправить: отдавайте современный код, а legacy-бандл — только там, где он нужен.
- Тестирование только в одном движке — различия в раскладке и событиях не видны, пока пользователь не сообщит о них; исправить: перед выпуском прогоните страницу во втором движке.
- Матрица поддержки, заданная один раз и больше не пересматриваемая — инструменты расходятся с реальностью и собирают под браузеры, которыми никто не пользуется; исправить: пересматривайте матрицу по расписанию, из аналитики, которая её оправдывает.
Что читать дальше
- Язык гипертекстовой разметки (HTML) (02-frontend/03-html) — слой с самыми старыми и надёжными запасными вариантами из всех.
- Каскадные таблицы стилей (CSS) (02-frontend/05-css) —
@supportsи снисходительная обработка ошибок каскада суть инструменты совместимости. - JavaScript (02-frontend/06-javascript) — проверки возможностей пишутся на самом языке.