51. 적절한 낮춤 대 점진적 향상

소개

이번 학습에서 우리는 2가지 개발접근법의 차이에 대해 얘기하겠다: 적절한 낮춤과 점진적인 향상
간단히 정리하자면 다음과 같이 정의할 수 있다:

적절한 낮춤(Graceful degradation)

원하는 기능을 갖는 또다른 버전을 제공하거나, 사용자가 제품의 결점이 사용성을 보장하기 위한 안전 조치때문이라는 것을 인지하도록 만드는 것이다.

점진적 향상(Progressive enhancement)

사용가능한 기능을 바탕으로, 향상된 기능을 적용하기 전에 테스트를 통해 풍부한 사용자 경험을 하나씩 증가시키는 것이다.

이 두 접근법이 아주 비슷한 것 같아 보이고 거의 같은 결과를 제공하게 될 것이다. 하지만 주목할 만한 차이점이 있는데 나중에 보여주겠다.

이 기법들의 필요성에 대해 먼저 설명하도록 하겠다. 그리고 나서 더 깊은 의미를 알아보도록 할 것이며 구현 예제들을 보고 비교해 봄으로써 언제 어떤 방식을 사용할지에 대한 가이드를 제공할 것이다. 자 이제 웹개발에 있어 왜 이런 특별한 개발 접근법이 필요한지 알아보자.

이 문서의 구조는 다음과 같다:

  • “Mobilis in mobile” — 끊임없이 변하는 환경 속으로 빠져들기
  • 적절한 낮춤과 점진적 향상
  • 적절한 낮춤 대 점진적 향상의 예제
    • “페이지 인쇄하기” 링크
  • 언제 무엇을 사용할 것인가
  • 요약
  • 연습 문제

“Mobilis in mobile” — 끊임없이 변하는 환경 속으로 빠져들기

“해저2만리” 의 네모선장 처럼, 웹개발자는 끊임없이 변하고 요동치는 환경 속에 있는 자신을 발견하게 되는데 이러한 환경은 우리가 이루려고 노력하는 것에 적대적일 수 있다.

웹은 어떤 화면 장치든 어떤 언어든 당신이 원하는 어느곳에서든 사용될 수 있도록 고안되고 정의되어 있다. 최종 사용자들이 기대하는 오직 한가지는 웹에 접속되어 정보를 전송하는데 사용하는 프로토콜(http, https, ftp 등등) 을 이해할 수 있는 브라우징 장치를 사용하는 것뿐이다.

이것은 우리가 장비가 어떤 것인지 최종 사용자들의 능력이 어떠한지를 기대할 수 없다는 것을 의미한다. 우리는 또한 개발자로서의 우리의 웹에 대한 경험이 다른 사람들과는 완전히 다르다는 것을 명심해야만 한다.

인터넷에서 컨텐트에 도달하기 위해서 기술을 강제로 업그레이드할 수 없다. 사람들과 회사들은 이미 정의된 환경을 고수할 것이며 단지 우리가 원한다고 해서 그 환경을 변경하거나 업그레이드하지는 않을 것이다. 수많은 사람들은 단지 웹을 소비하기를 원하며 그 내면의 기술들에 대해선 관심없다. — 그들이 원하는 전부는 우리가 그들에게 컨텐트에 도달할 수 있도록 해주는 것뿐이다. 최종 사용자들이 그들의 시스템을 최신사양으로 유지하도록 만드는 것은 운영체제와 브라우저 개발자들에게 달려있다 — 웹개발자로써 우리는 이에 대해 뭐라 할 수 없다.

이 모든 것들이 아주 형편없는 개발 환경을 만들어 버리는데, 예를 들어 기본적으로 9년 지난 브라우저에서 스크립트가 동작하고 (보안상의 이유로) 플러그인은 사용할 수 없으며, 낮은 해상도의 모니터와 꽤 일반적인 오피스 소프트웨어도 감히 돌릴 수 없는 컴퓨터들이 있는 사무실들이 있다.

우리는 이제 가서 이러한 회사들에게 “기회를 놓치셨습니다” 우리는 더 이상 구식의 기술을 지원할 수 없습니다 라고 주장할 수도 있을 것이다. 하지만 이러한 태도는 우리가 이 사람들이 우리 제품의 성공을 위해 아주 중요하다는 것을 잊어버리게 만들 수 있다. 대부분의 경우, 그들은 그들의 기술 장비를 변경할 필요성을 갖지 않고 있다. 접근성 측면에서 볼 때 이것들은 더욱 분명하다: 독서 장애 사용자들은 우리의 복잡한 명령어들을 이해할 수 없으며 시각 장애 사용자들은 “계속 진행하기 위해 녹색 버튼을 클릭하세요”를 할 수 없다, 그것이 우리의 시스템을 사용하기 위해서 필요하다고 우리가 정해놓았다고 하더라도 말이다.

우리는 미지의 상태에서 작업하고 그것이 동작하도록 할 수 있는 방법을 찾을 필요가 있다. 이것이 적절한 낮춤과 점진적 향상 둘 다 활동하기 시작하는 곳이다.

적절한 낮춤과 점진적 향상

당신은 이미 위에서 간단한 정의를 보았다; 이번 장에서 좀 더 기술적인 정의를 제공할 것이며 이러한 방법론들을 구현하는 것이 정말로 의미하는 것이 무엇인지 알아볼 것이다.

적절한 낮춤은 당신의 웹 기능을 만들어내는 습관인데 좀 더 최신 브라우저에서 특정 수준의 사용자 경험을 제공하지만 구식 브라우저에서 낮은 수준의 사용자 경험에 맞게 기능을 적절히 낮추어 줄 수 있다. 이 낮은 수준은 당신의 사이트 방문자가 사용하는데 편리하지는 않지만 여전히 기본적인 기능을 제공해주어 사이트를 사용할 수는 있도록 한다; 이것들이 그들을 도망가게 만들지는 않는다.

점진적인 향상도 비슷하지만 모든 것이 반대로 이루어진다. 당신은 모든 브라우저에서 웹사이트가 렌더링될 때 제공할 수 있는 기본적인 수준의 사용자 경험을 확립하는 것부터 시작하지만 좀 더 향상된 기능을 만들어서 브라우저에서 사용할 수 있는 경우 자동으로 그 기능이 가능하도록 할 수 있다.

다르게 말해서, 적절한 낮춤은 복잡한 상태에서 시작하여 낮은 경험에 대해 수정하는 반면 점진적 향상은 아주 기본부터 시작해서 샘플이 동작시켜 미래의 환경을 위한 즉각적인 확장이 가능하도록 하는 것이다. 적절하게 낮추는 것은 과거를 되돌아 보는 것을 의미하는 반면 점진적으로 향상하는 것은 단단한 땅에 발을 딛고 있는 것을 유지하면서 앞으로를 기다리는 것을 의미한다.

적절한 낮춤 대 점진적 향상의 예제

점진적 향상을 사용하는 접근 방식과 적절한 낮춤을 사용하는 또다른 접근 방식을 보여주는 예제를 살펴보도록 하자.

“페이지 인쇄하기”링크

사용자가 현재 문서를 인쇄하도록 하는 링크는 거의 쓸모없다 — 브라우저에서 프린터 아이콘을 누르는 것과 같은 것이다. 그러나 사용자 실험에서는 예약 프로세스(예를 들어 항공사 웹사이트)의 마지막에 페이지 인쇄하기 기능은 좋은 재확인 호출이 된다는 것을 보여주고 있다. 사용자들은 자신에 차 있어서 시작한 것을 끝내려고 한다.

“페이지 인쇄하기”링크가 갖는 문제는 HTML 에 브라우저의 인쇄 버튼을 링크할 수 있는 방법이 없다는 것이다 — 이를 위해 자바스크립트가 필요하다. 자바스크립트에서 이것은 간단하다 — 브라우저의 window 객체는 프린트출력을 시작하도록 호출할 수 있는 print() 메소드를 가지고 있다. 아마도 대부분 일반적인 방식은 다음과 같이 자바스크립트를 이용한다: pseudo protocol:

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

이것은 자바스크립트가 가능하고 활성화되어 있어서 브라우저가 인쇄 명령어를 지원하는 경우에 동작한다. 그러나 만약 자바스크립트가 가능하지 않은 경우(예를 들어 어떤 모바일 기기)에 이 링크는 동작하지 않을 것이다 — 클릭해도 아무일도 일어나지 않는다. 이는 문제점을 야기시키는데 사이트 개발자로써 당신은 방문자들에게 이 기능을 보증해야 하기 때문이다. 링크를 클릭했는데 동작하지 않는다면 그들은 혼란스러워 하며 속았다고 느낄 것이며 당연히 나쁜 사용자 경험을 제공하는 것에 대해 당신을 비난할 것이다.

이러한 문제를 줄이기 위해 사이트 개발자들은 보통 적절한 낮춤 접근방식을 취하게 된다: 사용자에게 링크가 동작하지 않을 수 있으며 그 이유가 무엇인지를 알리고 원하는 것을 얻을 수 있는 대안책을 제시할 수 있다. 일반적인 편법은 noscript 요소를 사용하는 것이다. 이 요소내에 있는 것은 자바스크립트가 가능하지 않는 경우 최종사용자에게 보여진다. 앞의 경우 다음과 같이 할 수 있다:

<p id="printthis">
  <a href="javascript:windowprint()">Print this page</a>
</p>
<noscript>
  <p class="scriptwarning">
    Printing the page requires JavaScript to be enabled.
    Please turn it on in your browser.
  </p>
</noscript>

이것은 적절하게 기능을 낮추도록 고려되었다 — 우리는 사용자에게 무언가 잘못되었다는 것을 설명하고 이 문제를 어떻게 풀어야 하는지 설명한다. 그러나 이것은 당신의 사이트의 방문자들에 대해 다음과 같이 가정하고 있다:

  • 자바스크립트가 무엇인지 알고 있다
  • 자바스크립트를 어떻게 활성화하는지 알고 있다
  • 자바스크립트를 활성화할 수 있는 권한과 옵션이 있다
  • 단지 문서를 인쇄하기 위해 자바스크립트를 켜는 것에 대해 만족한다

약간 더 나은 접근방식은 아마도 이렇게 될 수 있다:

<p id="printthis">
  <a href="javascript:windowprint()">Print this page</a>
</p>
<noscript>
  <p class="scriptwarning">
    Print a copy of your confirmation.
    Select the "Print" icon in your browser,
    or select "Print" from the "File" menu.
  </p>
</noscript>

이는 위의 상세한 문제들을 해결하고 있지만 모든 브라우저에서 프린트 기능이 동일하다는 것을 가정하고 있다. 추가적인 사실이 남아있다 — 이러한 접근방식에서의 문제는 우리가 어떤 기능을 제공하면서 그것이 동작하지 않을 수 있다는 것을 완전히 알고 있어야 하며 스스로 설명할 수 있어야만 한다. 기술적으로 “인쇄하기” 버튼은 필요가 없는데 이것은 같은 문제에 대해 점진적인 향상 접근방식이 그것이 동작할 것이라고 가정하지 않는 이유이다.

만일 우리가 점진적인 향상을 이용해 이 문제를 해결하려 한다면, 첫번째 단계로 스크립트를 사용하지 않고 페이지를 인쇄하는 방법이 있는지를 찾을 것이다. 방법이 없다면 실제로 링크를 사용하는 것은 HTML 요소를 잘못 선택한 것을 의미하는 것이다. 만일 자바스크립트로만 가능한 기능을 제공하길 원한다면 버튼을 사용해야만 할 것이다: 버튼은 스크립트 기능을 지원하기 위한 것이다 라고 정의되어있다. W3C 스펙을 보면 다음과 같다:

푸쉬 버튼: 푸쉬 버튼은 디폴트 행위를 갖지 않는다. 각 푸쉬 버튼은 요소의 이벤트 속성들과 연관된 클라이언트측 스크립트를 가질 수 있다. 이벤트가 발생할 때(예를 들어, 사용자가 버튼을 누르거나 땔 때 등), 연관된 스크립트가 동작한다.

두번째 단계는 사용자가 활성화된 자바스크립트를 갖는지 브라우저가 인쇄할 수 있는지를 가정하지 않는 것이다. 대신 우리는 단지 사용자에게 문서를 인쇄할 필요가 있으며 “어떻게” 할 것인지는 그들에게 달려있다고 단호하게 얘기하는 것이다:

<p id="printthis">Thank you for your order.
Please print this page for your records.</p>

이것은 어떤 경우든 동작한다. 기능의 나머지를 위해 우리는 겸손한 자바스크립트를 사용해서 브라우저가 지원하는 경우에만 인쇄 버튼을 추가한다:

<p id="printthis">Thank you for your order.
Please print this page for your records.</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 메소드가 있는지 확인한다.
  • 둘다 참이면 새로운 클릭 버튼을 생성하고 클릭 이벤트 핸들러로 window.print()를 적용한다.
  • 마지막으로 문단에 버튼을 추가한다.

이것은 모든 사용자가 기술적인 환경과 관계없이 동작할 것이다. 우리는 절대로 동작하지 않는 사용자 인터페이스 요소를 약속하지 않는다 — 대신 그것이 동작하는 경우만 보여준다.

언제 무엇을 사용할 것인가

내가 이상주의자일지도 모르나 나는 정말로 적절한 낮춤을 싫어한다. 무언가를 만들었는데 그것이 다른 환경에서는 거의 동작하지 않으면 (혹은 사용자가 업그레이드를 해야한다면) 나는 환경과 사용자의 업그레이드하는 능력에 대해 많은 가정을 만들어야 한다.

나는 노트북이 무선랜을 찾을 수 없을 때 블랙베리1를 사용하는 자신을 발견하며 웹저작물이 자바스크립트가 활성화되어야 한다고 해서 내가 그 기능을 켜야만 할 때 아주 불만을 느낀다. 나는 능력이 없어서 확실히 당신 제품들에 적절한 사용자이다 — 특히 나는 당신의 서비스에 GPS나 EDGE[2. EDGE: Enhanced Data rates for GSM Evolution의 약어, 핸드폰의 데이터전송기술의 하나로 미국시장에서 3세대 표준 기술로 채택된듯하다 우리나라의 3G가 WCDMA방식을 사용하는 것과 같은 의미임접속을 해야하는 경우 많은 돈을 지불한다.

그러나 약간의 상황에서 적절한 낮춤은 실용적이 될 수 있다:

  • 오래된 제품을 갱신하려는데 시간이 없고 그것을 변경하고 교체하기 위한 방법이나 통찰력이 없다.
  • 단지 완전히 점진적인 향상으로 제품을 마무리할 시간이 없다(종종 나쁜 기획의 징후이거나 예산이 바닥나는 경우이다).
  • 당신의 제품이 edge케이스이다. 예를 들어 수행 속도 차이가 매 밀리세컨드 마다 수백만 달러의 차이를 의미하는 트래픽이 아주 많은 사이트.
  • 정의된 제품 자체가 스크립팅에 의존적이라서 향상된 버전이 아닌 “기본” 버전을 유지하는데 스크립팅이 적절하다. (지도서비스, 이메일 클라이언트, 피드 리더기등)

그렇지 않은 다른 모든 경우, 점진적인 향상이 최종 사용자와 당신에게 더 행복할 것이다:

  • 환경과 능력에 관계없이 동작하는 제품을 제공한다.
  • 새로운 브라우저가 출현하거나 브라우저 확장이 널리 채택되고 있을 때 당신은 원래의 해결책을 건드리지 않고 앞으로 또다른 수준으로 향상시킬 수 있다 — 적절한 낮춤은 원래의 해결책을 변경할 필요가 있을 것이다.
  • 당신은 기술이 허락하는 한 생각될 수 있는 기술을 만들 수 있다 — 처음부터 목적을 달성할 수 “있어야만 하는” 것은 아닌 기술이 없이 더 빨리 목적을 달성할 수 있도록 도움을 준다.
  • 새로운 기능들을 추가할 필요가 있다면, 특정 단계에서 지원되는지 체크 한 후에나 할 수 있거나 가장 기본 수준의 기능만 추가하고 좀 더 복잡한 환경에서 더 좋게 만들 수 있다. 어떤 경우든 유지보수가 동시에 발생하고 다른 곳에서 발생하지 않는다. 점진적으로 향상된 제품을 최신으로 유지하는 것은 두가지 버전을 유지보수 하는 것보다 훨씬 덜 수고스럽다.

요약

점진적인 향상과 적절한 낮춤 둘 다 같은 것을 하기 위함이라고 말할 수 있다: 우리 제품을 모든 사용자에게 유용하도록 하는 것이다. 점진적 향상은 좀 더 정교하고 동시에 안정된 방법을 보증하지만 시간과 노력이 더 필요하다. 적절한 낮춤은 이미 존재하는 제품을 위한 패치로 더 용이하게 사용될 수 있다; 나중에 유지보수하기가 더 힘들어지지만 처음 들이는 수고는 줄어든다.

연습 문제

  • 이 문서에서 각 접근방식을 이용한 인쇄 링크 예제를 보여주었다. 다른 예로 무엇이 있을지 생각해 볼 수 있는가?
  • 당신은 폼이 전송되기 전에 이메일이 포함된 폼필드에 대해 확인하기 위해 자바스크립트를 사용하고 싶다고 말할 수 있다. 다른 접근방식으로 무엇이 있을 수 있는지 그리고 고려해야 할 다른 문제점이 어떤 것이 있을 수 있는가?
  • 당신은 지도를 표시하고 싶은데 점진적인 향상을 사용하고 싶다고 할 수 있다. 당신이 시작할 기본적인 기능은 무엇인가?
  • 당신은 2개의 드랍다운 폼 컨트롤로 구성된 인터페이스를 갖는다고 하자. 첫번째 드랍박스에서 옵션을 선택하면 2번째 드랍박스에서 가능한 옵션이 변경될 것이다. 이러한 컨트롤에 대한 대체물이 무엇이 있을 수 있는가? 이 컨트롤에 어떤 문제점들이 있을 수 있는가?

저자에 관하여

Chris Heilmann은 지난 10년간 웹 개발자로서 활동해 왔으며 취미삼아 라디오 저널리즘에 관한 일도 한다. 그는 영국에 있는 야후에서 트레이너와 리더 개발자로 근무하고 있으며 유럽과 아시아의 front end 코드의 품질을 관리한다.

그의 블로그는 Wait till I come 에 있으며 많은 소셜 네트워크에서 “codepo8”로 알려져 있다.

  1. Blackberry: 블랙베리는 캐나다 RIM사의 스마트폰 브랜드로 미국 비즈니스 용어 사전에 ‘blackberry’를 ‘타동사, 휴대전화로 이메일을 전송하다’라는 설명이 붙을 정도로 영어권 직장인의 필수품으로 통한다고 한다. (‘googling’이 ‘검색하다’란 의미로 쓰이는 것과 같음). 출처:http://article.joins.com/article/article.asp?Total_ID=3477143
이 글을 다 읽어주셨다면, 댓글을 남겨주세요. 좋았다라는 격려도 좋고, 잘못된 부분을 지적해 주시는 것도 좋습니다. 마음에 드셨다면 아래 Like 버튼을 눌러서 페이스북과 트위터로 소개해 주시면 더욱 좋겠습니다.