Опубликован: 01.07.2011 | Доступ: свободный | Студентов: 6428 / 1052 | Оценка: 4.07 / 3.64 | Длительность: 10:34:00
Лекция 13:

Постепенное ухудшение или прогрессивное улучшение

< Лекция 12 || Лекция 13
Аннотация: Различия между двумя подходами к разработке: постепенное ухудшение, прогрессивное улучшение. Движение в постоянно изменяющейся среде. Основы постепенного ухудшения и прогрессивного улучшения. Пример для сравнения постепенного ухудшения и прогрессивного улучшения (Ссылки "Печать страницы").

Введение

В данном руководстве мы обсудим различия между двумя подходами к разработке: постепенное ухудшение и прогрессивное улучшение. Для упрощения изложения дадим рабочие определения:

Постепенное ухудшение

Предоставление альтернативной версии функциональности или уведомление пользователя о недостатках продукта, как мера предосторожности для указания применимости продукта.

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

Начиная с некоторой базовой допустимой функциональности постепенное улучшение возможностей пользователя, тестируя поддержку усовершенствований перед их применением.

Может показаться, что эти два подхода очень похожи, и что они должны предоставить почти одинаковые результаты, но необходимо отметить, что существуют различия, которые мы рассмотрим ниже.

Мы начнем с объяснения необходимости этих методов. Затем мы рассматриваем более содержательное определение, показывая примеры реализации, после чего проводим сравнение и указываем, когда и что использовать. Давайте начнем с объяснения, почему требуются такие специальные подходы к web-разработке.

Лекция имеет следующую структуру:

  • Движение в постоянно изменяющейся среде
  • Основы постепенного ухудшения и прогрессивного улучшения
  • Пример для сравнения постепенного ухудшения и прогрессивного улучшения
    • Ссылки "Печать страницы"
  • Что когда применять
  • Заключение
  • Контрольные вопросы

Движение в постоянно изменяющейся среде

Почти как капитан Немо из "20,000 лье под водой" разработчики web ощущают себя в постоянно изменяющейся и неустойчивой среде, которая может быть достаточно враждебна по отношению к тому, что мы пытаемся получить.

Инфраструктура Web была создана и определена для использования с любым устройством отображения, на любом языке, везде, где может понадобиться. От конечного пользователя ожидается только, что он использует устройство просмотра, которое может соединиться с Web и понимает протоколы, используемые для передачи информации - http, https, ftp и т.д.

Это означает, что мы не можем ожидать никакой настройки или возможностей от конечных пользователей. Мы можем быть также совершенно уверены, что наш опыт работы с Web в качестве разработчиков совершенно отличен от опыта тех людей, которых мы хотим охватить.

Не требуется обязательного обновления технологий, чтобы получить доступ к содержимому Интернет. Люди и компании будут придерживаться определенной среды, и не будут изменять или обновлять ее просто потому, что мы этого захотим. Множество людей хотят только потреблять Web и не обращают внимания на технологии, которые лежат в основе - они ожидают только возможность получить доступ к содержимому, которое мы им обещаем. Это разработчики операционных систем и браузеров должны поддерживать их системы на современном уровне - разработчики Web ничего не могут сделать в этом отношении.

Все это приводит к очень хрупкой среде разработки, например, офисы, где по умолчанию используются 9-летние старые браузеры с отключенными сценариями и плагинами (по причинам безопасности), низкое разрешение и компьютеры, которые едва справляются с нагрузкой при выполнении офисного программного обеспечения, являются достаточно распространенными.

Мы могли бы теперь заявить, что такие компании "опоздали на поезд" и нет никакого смысла пытаться поддерживать устаревшие технологии. Но такое отношение может заставить нас забыть, что эти люди могут быть очень важны для успеха наших продуктов. Во многих случаях они не имеют необходимых прав для изменения своего технического окружения. Когда речь идет о доступности, то все еще более очевидно: конечный пользователь с дислексией не сможет понять сложные инструкции, а слепой пользователь не сможет "щелкнуть на зеленой кнопке, чтобы продолжить", даже если мы и указали, что это требуется для использования наших систем.

Мы работаем в неизвестности, и нам требуется найти способ заставить все работать. Здесь на помощь и приходят как постепенное ухудшение, так и прогрессивное улучшение.

Основы постепенного ухудшения и прогрессивного улучшения

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

Итак, постепенное ухудшение является практикой создания функциональности web таким образом, что она предоставляет определенный уровень взаимодействия с пользователями в более современных браузерах, но будет также постепенно ухудшаться до более низкого уровня взаимодействия с пользователями в более старых браузерах. Этот более низкий уровень не слишком удобен для использования посетителям сайта, но, тем не менее, предоставляет базовую функциональность, за которой они пришли на сайт, для них она остается доступна.

Прогрессивное улучшение похоже, но действует в другом направлении. Все начинается с создания базового уровня взаимодействия с пользователями, который смогут предоставить все браузеры при отображении web-сайта, но также создается более развитая функциональность, которая будет автоматически доступна для браузеров, способных ее использовать. Другими словами, постепенное ухудшение начинается с существующего уровня сложности и пытается исправить ситуацию для менее развитого уровня взаимодействия, в то время как прогрессивное улучшение начинается с самого базового, работающего примера и предназначено для постоянного расширения для будущих сред. Постепенное ухудшение означает смотреть назад, в то время как прогрессивное улучшение означает смотреть вперед, сохраняя ноги на твердой почве.

Пример для сравнения постепенного ухудшения и прогрессивного улучшения

Давайте посмотрим на пример, показывающий подход, который использует прогрессивное улучшение, и другой подход, использующий постепенное ухудшение.

Ссылки "Печать страницы"

Возможно, что ссылки, которые позволяют пользователям печатать текущий документ, бесполезны - нажатие на иконке принтера в панели инструментов браузера делает то же самое. Однако тестирование пользователей показывает, что в качестве последнего шага процесса резервирования (например, на web-сайте авиакомпании) они являются хорошим приглашающим сигналом к действию. Пользователи чувствуют, что контролируют ситуацию, и получают чувство завершения того, что они начали.

Проблема со ссылками "Печать страницы" в том, что в HTML не существует способа соединиться с кнопкой принтера браузера - для этого требуется JavaScript. В JavaScript это делается просто - объект window браузера имеет метод print(), который можно вызвать для запуска печати. Возможно, наиболее распространенный способ состоит в использовании псевдопротокола javascript:

<p id="printthis">
  <a href="javascript:window.print()">Print this page</a>
</p>

Это работает, когда поддержка JavaScript имеется и включена, и браузер поддерживает команду print. Однако, если JavaScript недоступен (например, на некоторых мобильных устройствах), то эта ссылка работать не будет - щелчок на ней вообще ничего не сделает. Это создает проблему, так как, будучи разработчиком сайта, вы пообещали посетителям эту функциональность. Когда они щелкают на ссылке, и она не работает, они испытывают неуверенность и подозревают мошенничество, и будут совершенно справедливо упрекать вас за предоставление плохого взаимодействия с пользователями.

Чтобы ослабить эту проблему разработчики сайтов обычно используют подход постепенного ухудшения: сообщают пользователю, что ссылка может не работать, и в чем может быть причина, и может быть даже предлагают альтернативное решение, чтобы получить то, что они хотят сделать. Обычный прием состоит в использовании элемента noscript. Все внутри этого элемента будет показано конечному пользователю, когда JavaScript будет недоступен. В данном случае это может быть следующий код:

<p id="printthis">
  <a href="javascript:window.print()">Печать страницы </a>
</p>
<noscript>
  <p class="scriptwarning">
    Печать страницы требует использования JavaScript. 
    Пожалуйста, включите поддержку JavaScript в браузере.
  </p>
</noscript>

Это считается постепенным ухудшением - мы объясняем пользователю, что возникла проблема и как ее решить. Однако это предполагает, что посетители сайта:

  • Знают, что такое JavaScript
  • Знают, как включить его
  • Имеют права и возможность включить его
  • Счастливы включить JavaScript, просто чтобы напечатать документ

Возможно, немного лучше будет следующий подход:

<p id="printthis">
  <a href="javascript:window.print()">Печать страницы </a>
</p>
<noscript>
  <p class="scriptwarning">
    Распечатайте копию своего подтверждения. 
    Выберите иконку "Print" в браузере,
    Или выберите "Print" в меню "File".
  </p>
</noscript>

Это исключает некоторые из перечисленных выше проблем, но предполагает, что функция печати одинакова во всех браузерах. Кроме того, остается факт - проблема с подходом такого типа состоит в том, что мы предлагаем некоторую функциональность, полностью осознавая, что она может не работать, и затем должны объяснять это. Технически нет необходимости для наличия кнопки "напечатать это", именно поэтому подход с прогрессивным улучшением к той же проблеме не предполагает, что это будет работать.

Если мы должны решить эту проблему с помощью прогрессивного улучшения, то на первом шаге нужно выяснить, существует ли способ печати страницы без использования сценария. Такого способа нет, что в действительности означает, что ссылка является неправильным выбором элемента HTML для использования. Если вы хотите предоставить функциональность, которая доступна только с помощью JavaScript, необходимо использовать кнопки: по определению кнопки предназначены для поддержки сценариев (http://www.w3.org/TR/html401/interact/forms.html#push-button). Как говорит спецификация W3C:

кнопки: Кнопки не имеют поведения по умолчанию. Каждая кнопка может иметь клиентские сценарии, связанные с атрибутами событий элемента. Когда происходит событие (например, пользователь нажимает кнопку, отпускает ее, и т.д.), включается связанный сценарий.

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

<p id="printthis">Спасибо за Ваш заказ. Пожалуйста, распечатайте эту страницу для собственного учета.</p>

Это работает в любом случае. Для остальной функциональности мы используем ненавязчивый JavaScript (http://onlinetools.org/articles/unobtrusivejavascript/), чтобы добавить кнопку печати, только когда браузер его поддерживает:

<p id="printthis">Спасибо за Ваш заказ. Пожалуйста, распечатайте эту страницу для собственного учета.</p>
<script type="text/javascript">
(function(){
  if(document.getElementById){
    var pt = document.getElementById('printthis');
    if(pt && typeof window.print === 'function'){
      var but = document.createElement('input');
      but.setAttribute('type','button');
      but.setAttribute('value','Print this now');
      but.onclick = function(){
        window.print();
      };
      pt.appendChild(but);
    }
  }
})();
</script>

Обратите внимание, насколько ненавязчив сценарий - мы не предполагаем ничего.

  • Помещая всю функциональность в анонимную функцию и немедленно ее выполняя - это делает следующий код (function(){})() - мы не оставляем за собой никаких глобальных переменных.
  • Мы проверяем поддержку DOM и пытаемся получить элемент, к которому хотим добавить кнопку.
  • Затем мы проверяем, что элемент существует, и что браузер имеет объект window и метод print (проверяя, что type этого свойства будет function ).
  • Если проверки прошли успешно, мы создаем новую кнопку щелчка и задаем window.print() в качестве обработчика события щелчка.
  • Последний шаг состоит в добавлении кнопки в параграф.

Это будет работать для каждого пользователя, независимо от технической среды. Мы никогда не обещаем пользователю элемент интерфейса, который не работает - наоборот, мы показываем кнопку, только когда она работает.

Что когда применять

Я могу быть идеалистом, но я действительно не люблю идею постепенного ухудшения. Создавая что-то, а затем, делая едва работающим в других средах (или предлагая пользователям модернизироваться), я делаю слишком много предположений, как о среде, так и о возможности пользователей модернизироваться.

Я помню себя, использующим Blackberry, когда это устройство не могло найти беспроводную сеть, и я был крайне разочарован, когда web-продукты сообщили, что им требуется JavaScript, который я должен включить. Я не могу, и я являюсь законным пользователем ваших продуктов - особенно когда я плачу большие деньги за GPS и EDGE доступ к вашим службам.

Однако, постепенное ухудшение становится жизнеспособным в нескольких ситуациях:

  • Вы модифицируете старый продукт, и у вас нет времени, доступа или понимания для его изменения или замены.
  • У вас просто нет времени, чтобы закончить продукт с полным прогрессивным улучшением (часто признак плохого планирования или исчерпания бюджета).
  • Имеющийся продукт является пограничным случаем, например, сайты с очень большим трафиком, где каждая миллисекунда производительности означает разницу в миллионы долларов.
  • Продукт по определению настолько зависим от сценариев, что больше смысла имеет поддержание "базовой" версии, а не усовершенствованной (карты, клиенты email, агрегаторы новостей).

Во всех остальных случаях, прогрессивное улучшение сделает и конечных пользователей и вас более счастливыми:

  • Независимо от среды и возможностей вы поставляете продукт, который работает.
  • Когда появляется новый браузер или расширение браузера становится широко используемым, можно добавить еще один уровень усовершенствования, не трогая исходное решение - постепенное ухудшение будет требовать изменения исходного решения.
  • Вы позволяете технологии быть тем, чем она должна быть - помощью для достижения цели быстрее, чем без нее, а не "необходимостью", чтобы быть в состоянии достичь цели, прежде всего.
  • Если необходимо добавить новые свойства, можно сделать это после проверки, поддерживаются ли они на определенном этапе, или вы можете добавить их на самом базовом уровне функциональности и улучшить их в более развитых средах. В любом случае обслуживание происходит в одном месте, а не в двух различных местах.

Поддержание прогрессивно улучшенного продукта современным требует значительно меньше работы, чем обслуживание двух версий.

Заключение

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

Контрольные вопросы

  • Лекция показывает ссылки печати в качестве примера, который может использовать любой подход. Какие другие примеры вы можете придумать?
  • Предположим, что вы хотите использовать JavaScript для проверки перед отправкой формы, что поле формы содержит адрес email. Какие могут быть другие подходы, и какие другие проблемы должны быть рассмотрены?
  • Предположим, что вы хотите вывести карту, и хотите использовать прогрессивное улучшение. С какой базовой функциональности необходимо начинать?
  • Предположим, что вы имеете интерфейс, который состоит из двух раскрывающихся форм элементов управления. Выбор варианта в первой форме будет изменять доступные варианты во второй форме. Какое может быть альтернативное решение для такого типа элемента управления? Какие проблемы могут встретиться с ним?

Об авторе

Крис Хайлман работает Web-разработчиком уже десять лет, с тех пор как бросил радио-журналистику. Он работает для Yahoo! в Великобритании в качестве инструктора и ведущего разработчика, и осуществляет надзор за качеством кода внешнего представления для Европы и Азии.

Крис поддерживает блог на сайте Wait till I come (http://wait-till-i.com/) и доступен во многих социальных сетях под ником "codepo8".

Фото с разрешения: Bluesmoon (http://www.flickr.com/photos/bluesmoon/1545636474/)

< Лекция 12 || Лекция 13
Александр Мельников
Александр Мельников

В лекции №7 результат работы ни одного скрипта кроме первого не выводит результат на странице браузера, ни одного. Почему. Автор, разъясните пожалуйста. Сокурсники, можете помочь понять?

Юлия Максимова
Юлия Максимова

Я пишу в блокноте, сохраняю с разрешением html и открываю через браузер. Пустой лист

Это задание после первой лекции,  в чем его выполнить, чтобы увидеть результат или как?

Руслан Халитов
Руслан Халитов
Россия, Саратов, ЧУ "Международная академия экспертизы и оценки"
Андрей Маштак
Андрей Маштак
Россия, Тамбов, ТВВАИУ, 1981