Прогрессивное улучшение

Зачем:Скрипт не всегда доезжает до посетителя: слабая сеть, сбой, блокировщик, старый браузер. После урока вы строите страницу так, чтобы главное работало и без JavaScript, а скрипт делал её лучше, и проверяете это с выключенным скриптом.

20 минут

Озвучено синтезом речи (Qwen3-TTS), голос не принадлежит человеку.

Прогрессивное улучшение — способ строить страницу слоями: главное работает на HTML без JavaScript, а скрипт добавляет удобства сверху.

Скрипт может не приехать

Всю часть мы учились писать скрипты, и пора задать неприятный вопрос: а если скрипт не сработает? Не у вас: у посетителя. Причин больше, чем кажется:

  • сеть слабая, и страница уже видна, а скрипт ещё качается (на метро и в деревне это обычная ситуация);
  • в скрипте ошибка, например у посетителя старый браузер без нужной функции, и всё, что ниже ошибки, не выполнится;
  • блокировщик или корпоративный фильтр убрал скрипт целиком;
  • поисковый робот или программа чтения вообще не выполняют скрипты, или выполняют не сразу;
  • скрипт отключили сознательно.

Если страница построена так, что без скрипта она пуста, то в любом из этих случаев посетитель видит ничего. Если же она построена так, что без скрипта она проще, но полезна, то он видит главное. Эту идею называют прогрессивным улучшением (progressive enhancement), и в государственных сервисах Великобритании (GOV.UK) её сделали правилом.

Слои

Страница строится слоями, и каждый следующий слой только улучшает предыдущий:

  1. HTML: содержание, ссылки и формы. Этот слой работает везде. Список предложений лежит в разметке, форма заявки отправляется обычным способом, телефон это ссылка tel:.
  2. CSS: оформление и раскладка. Если стили не загрузились, страница некрасива, но читается.
  3. JavaScript: удобства. Меню сворачивается, поиск фильтрует, телефон проверяется на лету, форма отправляется без перезагрузки.

Всё, что вы делали в предыдущих уроках, можно разделить на «обязательное» и «улучшение», и разделение это очень практичное. Ссылка на форму заявки и сама форма: обязательное. Проверка телефона при вводе: улучшение (без неё браузер проверит поле сам при отправке, потому что в разметке есть required и type="tel").

Вот приёмы, которые из этого следуют.

  • Форма с action и method. Без скрипта браузер отправит её сам. Скрипт, который перехватывает отправку (preventDefault, как в уроке про fetch), делает то же самое лучше: без перезагрузки и с понятным сообщением. Но ломаться он не может: если он не загрузился, форма остаётся рабочей.
  • Элементы, нужные только скрипту, прячет разметка, а показывает скрипт. Кнопка меню без скрипта ничего не делает, поэтому в разметке она скрыта (hidden), а скрипт её показывает и заодно прячет список. Поле поиска без скрипта бесполезно, поэтому оно тоже скрыто в разметке и появляется со скриптом. Так не бывает «кнопок-пустышек».
  • Скрипт проверяет, что нужные ему элементы есть: if (search) { ... }. Если разметка изменилась, он молча пропустит улучшение, а не упадёт с ошибкой и не потащит за собой остальные.
  • Тег <noscript> показывает запасное содержимое, когда скрипты отключены. Пишите в нём спокойный текст («Страница работает и без JavaScript, не работает только поиск»), а не требование «включите, иначе ничего не увидите».

Посмотрите на двух похожих посетителей. В одной версии страница построена как улучшение, в другой на одном скрипте: выберите условия и посмотрите, что остаётся у посетителя.

Что остаётся посетителю
  • Список предложений обязательная работает
  • Форма заявки обязательная работает
  • Телефон и почта обязательная работает
  • Меню-кнопка улучшение не работает
  • Поиск по списку улучшение не работает
  • Проверка телефона на лету улучшение не работает

Работает функций: 3 из 6; из обязательных: 3 из 3. Страница проще, но главное доступно: посетитель увидит предложения, отправит заявку и найдёт контакты.

Проверьте себя: почему кнопка меню в разметке скрыта, а не видна всегда?

Без скрипта она ничего бы не делала. Кнопка-пустышка хуже, чем её отсутствие, поэтому скрипт сам показывает её, когда готов ей управлять.

Как проверить

Три способа, все на вашем компьютере, ни одного специального инструмента.

  1. Выключите JavaScript. В Chrome откройте инструменты разработчика (F12), нажмите Ctrl+Shift+P (на Mac Cmd+Shift+P), начните печатать «Disable JavaScript» и выберите команду. Обновите страницу. В Firefox то же делается через настройку javascript.enabled на странице about:config.
  2. Замедлите сеть. Вкладка «Сеть», список «Без ограничений», выберите «Медленный 3G» (или похожее) и обновите страницу. Вы увидите, что видно посетителю в первые секунды.
  3. Посмотрите исходный 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 и «оживляют» его скриптом позже: тот же принцип, автоматизированный.

Источники

Дальше

Теперь вы знаете: прогрессивное улучшение.