Прогрессивное улучшение
Зачем:Скрипт не всегда доезжает до посетителя: слабая сеть, сбой, блокировщик, старый браузер. После урока вы строите страницу так, чтобы главное работало и без JavaScript, а скрипт делал её лучше, и проверяете это с выключенным скриптом.
20 минут
Озвучено синтезом речи (Qwen3-TTS), голос не принадлежит человеку.
Прогрессивное улучшение — способ строить страницу слоями: главное работает на HTML без JavaScript, а скрипт добавляет удобства сверху.
Скрипт может не приехать
Всю часть мы учились писать скрипты, и пора задать неприятный вопрос: а если скрипт не сработает? Не у вас: у посетителя. Причин больше, чем кажется:
- сеть слабая, и страница уже видна, а скрипт ещё качается (на метро и в деревне это обычная ситуация);
- в скрипте ошибка, например у посетителя старый браузер без нужной функции, и всё, что ниже ошибки, не выполнится;
- блокировщик или корпоративный фильтр убрал скрипт целиком;
- поисковый робот или программа чтения вообще не выполняют скрипты, или выполняют не сразу;
- скрипт отключили сознательно.
Если страница построена так, что без скрипта она пуста, то в любом из этих случаев посетитель видит ничего. Если же она построена так, что без скрипта она проще, но полезна, то он видит главное. Эту идею называют прогрессивным улучшением (progressive enhancement), и в государственных сервисах Великобритании (GOV.UK) её сделали правилом.
Слои
Страница строится слоями, и каждый следующий слой только улучшает предыдущий:
- HTML: содержание, ссылки и формы. Этот слой работает везде. Список предложений лежит в разметке, форма заявки отправляется обычным способом, телефон это ссылка
tel:. - CSS: оформление и раскладка. Если стили не загрузились, страница некрасива, но читается.
- JavaScript: удобства. Меню сворачивается, поиск фильтрует, телефон проверяется на лету, форма отправляется без перезагрузки.
Всё, что вы делали в предыдущих уроках, можно разделить на «обязательное» и «улучшение», и разделение это очень практичное. Ссылка на форму заявки и сама форма: обязательное. Проверка телефона при вводе: улучшение (без неё браузер проверит поле сам при отправке, потому что в разметке есть required и type="tel").
Вот приёмы, которые из этого следуют.
- Форма с
actionиmethod. Без скрипта браузер отправит её сам. Скрипт, который перехватывает отправку (preventDefault, как в уроке про fetch), делает то же самое лучше: без перезагрузки и с понятным сообщением. Но ломаться он не может: если он не загрузился, форма остаётся рабочей. - Элементы, нужные только скрипту, прячет разметка, а показывает скрипт. Кнопка меню без скрипта ничего не делает, поэтому в разметке она скрыта (
hidden), а скрипт её показывает и заодно прячет список. Поле поиска без скрипта бесполезно, поэтому оно тоже скрыто в разметке и появляется со скриптом. Так не бывает «кнопок-пустышек». - Скрипт проверяет, что нужные ему элементы есть:
if (search) { ... }. Если разметка изменилась, он молча пропустит улучшение, а не упадёт с ошибкой и не потащит за собой остальные. - Тег
<noscript>показывает запасное содержимое, когда скрипты отключены. Пишите в нём спокойный текст («Страница работает и без JavaScript, не работает только поиск»), а не требование «включите, иначе ничего не увидите».
Посмотрите на двух похожих посетителей. В одной версии страница построена как улучшение, в другой на одном скрипте: выберите условия и посмотрите, что остаётся у посетителя.
- Список предложений обязательная работает
- Форма заявки обязательная работает
- Телефон и почта обязательная работает
- Меню-кнопка улучшение не работает
- Поиск по списку улучшение не работает
- Проверка телефона на лету улучшение не работает
Работает функций: 3 из 6; из обязательных: 3 из 3. Страница проще, но главное доступно: посетитель увидит предложения, отправит заявку и найдёт контакты.
Проверьте себя: почему кнопка меню в разметке скрыта, а не видна всегда?
Без скрипта она ничего бы не делала. Кнопка-пустышка хуже, чем её отсутствие, поэтому скрипт сам показывает её, когда готов ей управлять.
Как проверить
Три способа, все на вашем компьютере, ни одного специального инструмента.
- Выключите JavaScript. В Chrome откройте инструменты разработчика (F12), нажмите Ctrl+Shift+P (на Mac Cmd+Shift+P), начните печатать «Disable JavaScript» и выберите команду. Обновите страницу. В Firefox то же делается через настройку
javascript.enabledна страницеabout:config. - Замедлите сеть. Вкладка «Сеть», список «Без ограничений», выберите «Медленный 3G» (или похожее) и обновите страницу. Вы увидите, что видно посетителю в первые секунды.
- Посмотрите исходный HTML (Ctrl+U): то, что в нём есть, видят и роботы, и посетители без скрипта. Если списка предложений в нём нет, у поисковика его тоже нет.
Фреймворки и прогрессивное улучшение
Мы уже видели, что простой проект на Svelte или React без дополнительных мер отдаёт пустую страницу, пока скрипт не загрузится. Мета-фреймворки (SvelteKit, Next.js, Astro) решают это: на сервере они подготавливают готовый HTML, и браузер получает страницу сразу, а скрипт потом «оживляет» её. Это тот же принцип, который вы применили вручную, только автоматизированный. Разговор об этом продолжится в частях про генераторы сайтов и Jamstack.
Практика
Вы на сайте эпохи 2019 года. Страница, которую вы строили, многое делает скриптом. Пройдите по ней глазами недоверчивого посетителя: что будет, если скрипты не заработают?
Составьте таблицу «обязательное и улучшение»: пять-шесть функций вашей страницы и для каждой, что видно без скрипта. Потом поправьте страницу под неё: добавьте блок контактов со ссылками tel: и mailto:, <noscript>, скройте поиск в разметке и покажите его скриптом, добавьте проверку телефона на лету. Все улучшения оберните проверкой «элемент есть».
В конце проверьте по-настоящему: выключите JavaScript в инструментах разработчика на скачанном сайте или на любой своей странице и посмотрите, что осталось. Наш предпросмотр запускает скрипты всегда, поэтому эту проверку приходится делать у себя.
Что было не так раньше
В 2010-е годы появилась мода на «одностраничные приложения», которые целиком собираются скриптом: HTML приходил пустым, а всё остальное рисовал JavaScript. Сайты-визитки открывались на слабых телефонах по десять секунд, а поисковики какое-то время видели пустой экран. До этого, в эпоху «изящной деградации» (graceful degradation), страницу строили в расчёте на самые новые браузеры и добавляли запасные варианты для старых, и почти всегда о них забывали. А ссылки с адресом javascript:void(0) и табличка «включите JavaScript» на пустой странице были нормой.
Верным осталось одно: начинайте с того, что должно дойти до каждого, и добавляйте остальное сверху. Это одновременно доступнее, быстрее и надёжнее.
Практика
Готовлю вашу страницу…
Тест
Вопрос 1 из 6
Карточки
Эти карточки попадут в повторение, когда вы завершите урок.
Что такое прогрессивное улучшение?
Ответ
Подход: сначала страница работает на чистом HTML (содержание, ссылки, формы), затем CSS делает её красивой, затем JavaScript добавляет удобства. Главное доходит до всех.
Почему нельзя рассчитывать, что скрипт будет всегда?
Ответ
Он может не успеть загрузиться (слабая сеть), упасть с ошибкой, быть заблокирован или не поддерживаться старым браузером. Страница, построенная на нём, в этих случаях пуста.
Как оформляют элемент, который нужен только со скриптом?
Ответ
В разметке его скрывают (hidden) или не пишут вовсе, а скрипт его показывает или создаёт. Так без скрипта нет «кнопок-пустышек».
Как проверить страницу без JavaScript?
Ответ
Выключить JavaScript в инструментах разработчика (в Chrome: Ctrl+Shift+P, «Disable JavaScript»), замедлить сеть во вкладке «Сеть» и посмотреть исходный HTML. Основное должно работать.
Как прогрессивное улучшение связано с серверной отрисовкой?
Ответ
Мета-фреймворки (SvelteKit, Next.js, Astro) отдают готовый HTML и «оживляют» его скриптом позже: тот же принцип, автоматизированный.
Источники
- GOV.UK Service Manual: Building a resilient frontend using progressive enhancement только ссылка, по-английски
- MDN: Progressive enhancement CC BY-SA, по-английски
- web.dev Learn HTML: Forms CC BY, по-английски
- Inclusive Components (Хайдон Пикеринг) только ссылка, по-английски
Дальше
Теперь вы знаете: прогрессивное улучшение.