[번역/요약] Professional Frontend Engineering

원문은 YUI의 Professional Frontend Engineering 입니다. 스크립트와 함께 보시면 더 좋습니다.

오역/오탈자 신고는 메일로 해주세요.

개요

  • 야후의 Frontend Engineering 의 역사
  • 야후의 철학과 원칙
  • 현업에서의 이슈에 대한 지식과 이슈 해결의 최선의 방법
  • 왜 이런 것들이 중요한가?

야후의 Frontend Engineering 역사

  • 2001년, 야후에 3000명의 직원. 그러나 Frontend Engineer는 한명도 없었다.
  • 2001년, 최초로 Frontend engineer를 채용했고, 지금은 지사를 통틀어 700명이 정직원으로 일하고 있다.
  • 2001년, <table>, <font> 로 레이아웃을 잡았고 매우 정적인 UX을 제공했으나, 지금은 의미에 맞는 마크업을 하고 있고, 매우 동적인 UX 및 개인화를 제공하고 있다.
  • 2001년, 웹은 거의 html로 이루어졌고, 텍스트 위주였으므로, 테스트도 쉬웠고 전세계적으로 UX역시 매우 안정적/고정적이었다. 지금은 시각적인 웹, 적응적인 웹으로 발전했다. (2001 : static, lilain <-> now : visual, adalitive)
  • 2001년, 사용자들은 웹사이트가 어떻게 반응하는지, 어떻게 동작할지에 대해 크게 기대하지 않았다. 지금의 사용자들은 웹사이트가 어떻게 동작할지에 대해 매우 잘 알고 있으며, 요구사항도 까다로워졌다. 즉, UX가 매우 복잡해졌다.
  • 마지막으로 2001년, 디자인, 개발의 교차점이 명확하지 않았다. 각 팀들이 각각의 방법으로 일을 했고, 사람들은 front end와 back end를 함께 묶었고, 모호하고 결정되지 않은 프로세스로 작업했다. 그리고 (내 생각에) 오늘날 우리는 개발과 디자인을 모두 아우를 수 있는 교차점인, frontend engineering의 출현을 목도하고 있다.

그렇다면 Frontend engineering 이란 정확히 무엇인가? 이를 정의하는 몇가지 방법이 있다.

우리는 JS, CSS, HTML을 이용해 소프트웨어를 작성하는 존재이다.

여기서 나는 의도적으로 “소프트웨어를 작성”한다고 표현했는데, 왜냐하면 우리가 하는 일이 그저 페이지를 마크업하고 그래픽을 배치하는 문제가 아니라는 것이다. 오늘날의 웹사이트들은 소프트웨어 어플리케이션으로 꾸며져있다. Yahoo! 홈페이지이든, Yahoo! 메일처럼 더욱 전통적인 어플리케이션이든 관계없이 복잡하고 많은 양의 JS와 여러 소프트웨어로 만들어져있으며, 이런 페이지를 클라이언트 사이드의 가장 끝에서 작동시킨다. 따라서 우리는 소프트웨어를 작성하는 존재이다.

우리를 정의하는 또다른 방법은, frontend engineer는 브라우저에게 무엇을 할지 지시한다는 것이다.

이런 일이 쉽다면 참 좋은 일이겠지만, 브라우저의 다양성과 브라우저의 기능들의 다양성이 우리의 일을 어렵게 한다

우리는 “소스 보기” 에 책임이 있다고도 말할 수 있다.

따라서 우리의 조직이나 팀이 어떻게 구성되든, front engineer는 사용자 브라우저에 뿌려지는 모든 것에 책임이있다. 만약 여러분이 어떤 페이지에서건 “소스 보기”를 한다면, 여러분이 보는 모든 것은 곧 frontend engineer가 결정한 것의 결과물이다.

여러분이 서버사이드의 관점에서 Frontend engineering을 얕잡아볼 수도 있겠지만, Frontend engineer도 엄청나게 많은 기술들을 마스터해야한다.

Frontend engineer가 가져야할 지식 중 한가지는 HTML에 관한것이다.

이것은 그저 아는 것과는 다르며, 여러 차원에 대해 아는 것이다.

언어의 명세(specifications)에 대해 아는 것이다.

즉, 무엇이 가능하고, 무엇이 옳으며, 언어가 어떤 기능을 지원하도록 설계되었는가?에 대해 알아야 한다.

그 기술이 실제로 어떻게 구현되었는지 이해하는 것이다.

각 브라우저들은 스펙의 일부분만 구현하기도 했고, 기능을 추가해 놓기도 했다. 따라서 스펙을 이해하는 것 외에 브라우저가 스펙을 어떻게 구현해놓았는지 이해해야한다. 그리고 다른 구현물과 마찬가지로 여러 버그와 쿼크(quirk) 가 있으며, 스펙, 실제 구현, 알려진 버그를 이해하는 것 모두 중요하다.

지금까지는 단지 HTML에 관한 것일 뿐이었고, 다른 영역들도 많이 있다. 문서 객체 모델(DOM),CSS, 브라우저와 상호작용하고, 문서와 상호작용하는 API, Javascript, 또 최근 몇년간 많이 발전한 Ajax, JSON, XML, 또는 여러 다른 데이터 형식 등 도 있다.

지식의 범위가 매우 많고, 각 지식범위는 많은 차원을 가진다. 그리고 이들을 각 OS별, OS별 각 브라우저들, 각 브라우저의 각 버전에 대해서도 알아야 한다.

아 참. 브라우저마다의 렌더링 모드도 있다. 대략 계산해보면, 우리가 웹사이트를 만들 때 관리해야할 항목이 672가지에 달한다. 나는 이런 항목들이 사용성, 성능, 보안 만큼이나 중요하다고 여긴다.

672 Dimensions!

때때로 Frontend engineer들은 원하는 효과를 달성하기 위해 어떻게 해야할지 모른다. 이것이 더욱 더 우리의 일을 어렵게 하는 일이다. Douglas Crockford는 브라우저를 “상상할 수 있는 한의 최악의 소프트웨어 개발 환경”이라고 표현했다. 물론 모바일에서는 더욱 안 좋아진다.

Frontend의 작업은 backend작업과는 근본적으로 다르다, 왜냐하면 우리는 무엇도 컴파일할 기회를 갖지 못하며, 사용자들의 장비가 다양하므로 무엇이 어찌 작동할지 믿기 어렵고, 무엇도 예측할 수 없으며, JS에서 어떤 일이 일어날 지 믿을 수 없으므로, 우리는 언제나 방어적 자세를 취해야 한다. 성능상의 관점에서, 우리는 프로그램을 설치시킬 수 없고, (HTTP의 무상태라는 특성때문에)클라이언트에 저장시킬 수 없다. 그리고 재미있는 것은, 우리는 소스코드를 숨길 수 없다. 따라서 작업물을 모든 사람 볼 수 있으으로 깔끔하게 유지해야 한다.

하지만 이런 것들은 frontend가 backend와 다른 이유들과, 이 작업의 복잡성(complexity)의 일부일 뿐이다. 그리고 이 들은 엄청나게 중요하다. Yahoo!의 가치는 온라인에 존재함에서 나온다. 많은 회사들이 그들의 가치를 그들의 웹사이트로 부터 뽑아내고, 이 모든 것은 frontend engineer의 작업에 의존한다.

야후의 철학과 원칙

야후의 원칙

가용성

가용성은 웹사이트 구축의 기반이다. 사이트가 사람들에게 서비스 될 수 없다면 게임 오버다. 그리고 이런 가용성은 모두에게 적용되어야 한다. 가용성이란 즉, 접근성의 상위개념이다.

개방성

웹은 개방된 기술과 개방된 플랫폼 위에서 만들어졌다. 취미로 웹을 하는 사람이나, 웹 개발자들은 소스보기와 역공학(reverse engineering)를 통해 무엇이 어떻게 동작하는지 알아낸다. 이런 개방성은 웹의 핵심부분이고, 웹을 건강하고 생동할 수 있도록 하는 핵심부분이다. 그리고 개방성에는 앞서 언급한 철학적인 목표가 있을 뿐 아니라, 우리가 하는 일을 이해하는 생존전략이다. 우리가 배우는 것을 공유하고, 더 나은 기술, 더 나은 적용방법, 더 나은 정책을 추구하는 것은 중요하다. 왜냐하면 이들은 우리를 포함해 전세계 모든 이에게 이득을 주는 건강한 인터넷을 만들 것이기 때문이다. 개방성은 이 모든 것의 뿌리라고 생각한다.

풍요함(richness)

DHTML 개발과 Ajax 개발은 지난 5년간 굉장히 성장했고, 그것은 우리가 언제나 애써왔던 방향이다. 소프트웨어 디자이너, 인터페이스 디자이너, frontend engineer 로써 사용자에게 유용한 도구를 만드는 것이 우리의 일이다. 하지만 우리의 첫 원칙인 “가용성”을 잊지 말아야 한다. 따라서, 풍요로움과 가용성 사이의 균형을 이루어야 한다. 우리의 장비, 컴퓨터 사용 수준 등이 평균적인 사용자(average user)가 아니라는 것을 잊지말아야 하고, 사용자들은 굉장히 다양한 환경에서 접속하므로 사이트를 방어적으로 만들어야 한다.

안정성

우리는 안정적인 사이트를 만들기 원한다. 따라서 가용성의 관점에서 모든 것이 잘 동작하는지 언제나 확인해야한다. 하지만 안정성이라는 단어를 미래를 내다보는 관점으로도 사용할 수 있다. 웹은 아직 젊기때문에 앞으로 어떤 기술이 개발되고, 무엇이 발명될지 모른다. 따라서 안정성, 강력한 인프라스트럭쳐, 안정적인 코드에 계속적으로 투자하는 것이 중요하다. 이런 투자를 통해 우리가 차후 강력한 플랫폼을 갖게 될 것이기 때문이다.

지금까지 4가지 가이드 원칙에 대해 알아보았다. 이제 이런 원칙들을 지원할 세가지 핵심 기술을 알아보자.

점진적 개선

점진적 개선이란 우아한 성능저하의 반대말이다. (Graceful degradation & progressive enhancement) 우아한 성능저하는, 무언가 되지 않는 것을 발견했을 때 기능을 떼어내는 방법이고, 지속적인 개선이란 강력한 핵심기능에 기능을 조금씩 덧붙여 만드는 방법이다.

점진적 개선을 위한 규칙
  • 마크 업을 통해 컨텐츠를 구성
  • HTML 만을 사용해 핵심 기능을 테스트
  • CSS를 통해 레이아웃을 개선
  • JS를 통해 동작을 개선
  • 사용자 브라우저 설정을 침해하지 말 것.(CSS를 사용하지 않는 설정, JS를 사용하지 않는 설정, 글자크기 등)
  • 진입장벽을 만들지 말 것.(HTML만 사용하는 브라우저로도 접근 가능하게 할 것)

나서지않는 Javascript(Unobtrusive Javascript: 겸손한 Javascript)

  • HTML 문서에서 Javascript를 제거
  • Javscript에 의존하거나, 믿지 않도록 함.
  • (브라우저마다 객체이름, 지원하는 객체에 차이가 있으므로) 객체 사용전에 유무를 체크함
  • 전역변수를 남발하면 전역 네임스페이스를 침해할 수 있으므로, 사용시 주의할 것.
  • 마우스로만 접근하는 것이 아니라 키보드로 접근하는 경우도 있으므로 onclick, onmouseover 와 같은 이벤트 사용시 onfocus와 같이 대응되는 이벤트를 고려할 것.

브라우저 지원을 분리시킴.

  • 브라우저 지원은 지원 하느냐 하지 않느냐의 이분법적인 문제가 아니다.
  • 브라우저를 지원한다는 것이 픽셀단위까지 동일하게 보여준다는 의미가 아니다.
  • 브라우저를 세 등급으로 나누어 관리한다.
브라우저의 3등급
C 등급
  • 현대적이지 않은 브라우저 들.
  • CSS와 JS 제공안함.
  • 블랙리스트를 만들어 관리함.
  • 이런 브라우저로 접근시, 마크업이 잘 된 상태로만 보여주고, JS, CSS를 로드하지 않음.
A등급
  • CSS와 JS를 제공.
  • 엄격한 QA테스트
  • 픽셀단위까지 맞춤.
X등급(어떤지 모호하다는 의미로 X를 사용함)
  • C등급과 A등급 이외의 나머지 브라우저들
  • JS와 CSS를 지원한다고 가정하고 제공.
  • 장차 오래되어 최신의 JS와 CSS를 지원하지 않게되면 C등급으로 재 분류

현재 Yahoo!에서의 브라우저 등급 리스트 GBS

상기 등급리스트의 A등급에 해당하지 않는 브라우저 버전 및 OS버전에서는 QA테스트를 진행하지 않음.(X등급으로 처리)

현업에서의 이슈에 대한 지식과 이슈 해결의 최선의 방법

위의 핵심 테크닉에 도달하기 위한 구체적인 방법은 아래와 같다.

  • 표준이 있다면 표준에 따라라.
    • 아직 표준화 되지 않은 것이 있거나, 표준화가 진행되고 있는 것이라면 업계의 관행을 따르는 것도 괜찮다. 이런 과정이 실패하는 특수한 경우에는 기획으로 돌아가 목표를 달성하기 위한 기술들을 제안하자. 이런 과정은 더 건강한 인터넷, 프로젝트의 안정성을 위한 좋은 방법이다. 아직 익숙하지 않은 업무인 경우 개방성의 원칙을 기억하고, 문서화하며, 다른 사람들에게 공개하고 논의해 장래에 표준이 될 가능성을 주도록 하자.
  • 단순화 하고, 유연하게 하고, 개방하자.
    • 많은 경우, 단순한 것이 아름답다. 유연하게 만들면 사내의 여러 사람에게 도움을 줄 수 있고, 업계 종사자들에게도 도움을 줄 수 있다. 예를들어 별점 기능의 위젯이 사진 사이트에서 뿐 아니라 영화 사이트, 블로그 등등에서 사용될 수 있도록 하자. 마지막으로 개방하자. 우리가 배운 것을 문서화하고 API를 제안하자.
  • 우리는 여러 대상에게 만족을 주어야 한다.(사용자뿐 아니라 기기도 만족시켜야 한다)
    • 만약 어떤 Javascript 패턴이 더 압축적이고, 이것이 사용자, 협업하는 다른 개발자들에게 동일하다면, 기기에 최적화 된 패턴을 사용하도록 하자. 하지만 언제나 기억해야 할 것은, 우리가 최우선으로 고려해야 할 것은 사용자이므로, 더 좋은 사용자 경험을 제공하기 위해서 더 고민하는 것은 괜찮다. 그것이 우리의 일이므로.

조금 더 구체적인 지식 범위와 최선의 방법들을 알아보자.

HTML(Content Layer: 내용 계층)

  • doctype
    • doctype은 브라우저에게 렌더링 모드를 지정하기 때문에 중요하다. 렌더링 모드에는 표준모드와 quirks 모드가 있다. 2000년대 초반 표준을 지키는 브라우저들이 나오기 시작하면서 기존 사이트들이 의도하지 않게 보여지는 문제가 발생했다. 기존 사이트들과의 호환성을 위해 doctype을 포함하게 해서 렌더링 모드를 지정하도록 했다.
  • 마크업
    • CSS reset
      • 브라우저마다 기본으로 포함된 CSS를 통해 같은 태그들을 다르게 보여준다. 따라서 “CSS Reset”을 통해 기본적인 스타일링을 초기화해서 사용한다. YUI의 CSS reset 사이트
    • 마크업의 원칙
      • 자주 사용되지 않고, 잊혀져 가는 태그들이 많다. 각 태그의 용도대로, 최대한 사용하자.
    • 잊혀져 가는 태그 및 속성을 활용하자
    • <table>, <caption>, <thead>, <tbody>, <tfoot>, <th>, summary 속성, headers 속성, scope 속성, abbr 속성, <form>, <fieldset>, <legend>, <label for=""> ![잊혀져 가는 태그들][4

어떤 마크업이 더 나은가?(1)

1.

<dl>
    <dt>List of Stuff</dt>

    <dd>Snickers</dd>
    <dd>Mounds</dd>
</dl>

2.

<h3>List of Stuff</h3>
<ul>
  <li>Snickers</li>
  <li>Mounds</li>
</ul>

1번은 헤더(List of Stuff)와 컨텐츠 간에 관계를 만들었고, 2번은 헤더태그(h3)를 사용했다. 왜냐하면 List of Stuff가 의미하는 바가 바로 헤더이기 때문이다. 어떤 것이 최선일지 딱 정할 수 는 없다. 다만, 마크업을 할 때 지금 하고 있는 일이 어떤 것에 해당하는지를 이해하고, 당신의 시나리오에서 최선의 선택을 하라.

어떤 마크업이 더 나은가?(2)

1.

<div id="footer">© 2009 Yahoo! Inc. | 이 내용은 변경 가능함.</div>

2.

<div id="footer"><p>© 2009 Yahoo! Inc. | 이 내용은 변경 가능함.</p></div>

변경이 가능한 상황에서 1번과 2번 중 어떤 것이 더 나은가? 1번은 곧바로 내용으로 들어가므로 가볍다는 장점이 있다. 하지만 나는 2번이 더 좋다고 생각한다. 왜냐하면 div 는 영역을 나타내고 있고, 그 아래 p 가 내용을 나타내고 있기 때문이다. 만약 정보 제공자가 Yahoo! 이외에 더 추가된다면, 영역을 나타내는 요소가 중복해서 들어가야 한다는 위험성이 있다.

div 중독 & class 중독 (divitis & classitis)

마크업을 할 때 div와 class를 남용, 오용하지 않도록 해야 한다. 이를 위해서는 가장 의미있는 엘리먼트를 찾고, 쓸모있는 DOM 구조를 만들어야 한다.

div 중독의 징후 – div가 너무 많고, 각각은 class 속성들과 과도하게 관련되어 있다.

<div id="news">
    <div class="headline">News Headline</div>

    <div class="source">NY Times</div>
    <div class="date">Oct 17th, 2008</div>
    <div class="paragraph">Lorem ipsum...</div>

    <div class="headline">News Headline</div>

    <div class="source">LA Times</div>
    <div class="date">Oct 17th, 2008</div>
    <div class="paragraph">Lorem ipsum...</div>
</div>

더 나은 방법

<div class="mod" id="news">
    <h3>News Headline</h3>
    <cite class="publisher">NY Times</cite>

    <cite class="date">Oct 17th, 2008</cite>
    <p>Lorem ipsum...</p>

    <h3>News Headline</h3>
    <cite class="publisher">LA Times</cite>

    <cite class="date">Oct 17th, 2008</cite>
    <p>Lorem ipsum...</p>
</div>

DIV가 우선 모든 것을 감쌌다. 그 이유는, 보이기로는 라운드코너를 사용하든, 그림자를 넣든, 말풍선을 사용하든, 사실 그 뼈대는 네모이기 때문이다.

우리는 이런 레벨의 DIV를 표준 모듈 형식(Standard Module Format)이라 부른다. 페이지의 모든 컨텐츠 조각, 페이지의 모든 컨텐츠 덩어리가 바로 모듈이고, 따라서 우리는 이들을 DIV로 묶고 MOD라는 클래스이름을 준다. 각 모듈들은 그 구조에 따라 header, body, footer 영역을 가질 수 있다. 표준 모듈 형식을 통해 우리는 모든 컨텐츠들을 감싸는 새로운 구조를 갖게 되었고, 따라서 예측가능하고 어디에나 적용할 수 있는 믿을만한 구조를 갖게 되었다. 이 구조는 플랫폼의 일부가 될 수 있고, 우리가 구축하려고 하는 것들의 단단한 기초가 되었다.

Standard Module Format

<div class="mod">
    <div class="hd"></div>
    <div class="bd"></div>

    <div class="ft"></div>
</div>

아래 그림은 표준 모듈 형식으로 만들어진 야후 탑페이지의 News 부분이다.

Yahoo News Module

위 그림과 같은 것을 구현해 낼 때, 우리는

  1. 가장 안쪽에 위치한 컨텐츠에서부터 시작해 의미상으로 어떻게 마크업을 하는 것이 가장 좋을지를 도출한다. 가장 안쪽에 위치한 컨텐츠에서부터 시작해 의미상으로 어떻게 마크업을 하는 것이 가장 좋을지를 도출한다.
  2. 의미에 맞게 마크업 후, 이것이 모듈이므로, 모듈을 나타내는 DIV로 감싸고 유일한 id를 준다. 의미에 맞게 마크업 후, 이것이 모듈이므로, 모듈을 나타내는 DIV로 감싸고 유일한 id를 준다.
  3. 이 표준모듈에 header영역, body영역, footer영역을 준다. 이 표준모듈에 header영역, body영역, footer영역을 준다.

이 표준모듈형식은 여러 컨텐츠 영역에 적용될 수 있을 만큼 충분히 유연하고 단단하고 예측가능한 토대를 제공하게 되었다.

CSS(Presentation Layer: 표현계층)

CSS를 페이지에 어떻게 넣어야 할까?

최선의 방법은 <link>를 사용하는 방법이다. 물론 인라인으로 넣을 수도 있고, <style>을 쓸 수도 있고, <style>@import를 사용할 수도 있다. 하지만, 가장 성능이 좋고 깔끔한(cleanest) 방법은 문서의 <head> 내 에 <link>를 사용하는 것이다.

class와 ID의 사용

우리가 class나 id를 CSS의 관점에서 생각하고 있지만, 사실 이들은 HTML 계층이다. 이들은 HTML 그 자체내의 값(value)이거나 값을 갖는 속성이라고 말할 수 있다. 이들이 HTML 소속이므로, 이들은 HTML을 작성할 때 우리가 지키는 원칙에 따라 작성되어야 한다. 즉, 최대한 의미에 맞게 짜여져야 하고, HTML 문서를 더 풍성하게하고, 문서에 의미를 더해주는 방식으로 사용되어야 한다. 이전에 나는 class들이 “엘리먼트의 하위분류(element subclass)”로 생각될 수 있음을 이야기 한 적이있는데, 같은 태그를 용도에 따라 구분하고자 할 때가 바로 class를 사용해야할 시점이다.

ID의 세가지 역할 (Matt Sweeney)

  1. HTML 계층에서 각 ID는 페이지의 특정 위치에 접근할 수 있도록 하는 URL의 fragment identifier 이다. 따라서 1. 적절한 의미의, 2. 사용자에게 친숙한, 읽을 수 있는 값을 지정해야 한다. (foo.html#weather)
  2. ID는 CSS에서 편리하게 사용할 수 있는 선택자(selector)로 사용된다. (#weather {})
  3. Javascript에서도 쉽게 요소를 선택할 수 있도록 한다. (document.getElementById('weather'))

단단한 문서 구조

단단한 문서구조를 만드는 것은 frontend engineer들이 더 나은 삶을 살 수 있도록 한다.

<style>
        h3 {font-size : 107%;}
         a {color: red;}
    cite a {color:blue;}
</style>

<div class="mod" id="news">
    <h3>In The News</h3>
        <ul>
            <li>
                <a href="">Something happened</a> -
                <cite><a href="">NY Times</a></cite>

            </li>
        </ul>
</div>

Something happened에는 빨간색으로, NY Times에는 파란색을 주고 싶다면, 위와 같이 ID와 class의 추가 없이 구조적 DOM의 장점을 활용해 cite유무에 따라 구분이 가능하다. 여기에 #mod h3{}, #mod a{}, #mod cite a{} 와 같이 상위에 ID를 지정하게 되면 모듈에 따라서 스타일을 입힐 수 있게 된다.

배경 이미지, 큰 단일 이미지를 position을 변경하면서 보여주는 방법(CSS Sprite)

CSS Sprite

CSS 필터/핵 문법

#selector {
  width : 100px;      //for everybody
  *width : 120px;     //for IE 6,7
  _width : 110px;     // for IE6
}

어떤 사람은 이런 것들이 문법적으로 올바르지 않은 CSS파일을 만든다고 불평하기는 하지만, 우리는 이것이 현명한 거래라고 생각한다. 왜냐하면 특정 페이지를 나타내는 속성들을 한 곳에 모을 수 있기 때문이다. 위의 필터는 꽤 알려진 것이기 때문에 소스를 보거나, 유효성 검사기에서 오류로 나타나더라도 헷갈리지는 않는다.

hasLayout문제

hasLayout이 IE 6와 7에서만 가지고 있는 속성이기 때문에 문제도 이 두 버전에서만 나타난다. 개념을 잡기 위해서는 이 문서를 읽어보기 권한다. hasLayout이슈는 IE 에서의 많은 문제들의 원인이다. 해결방법은 zoom:1;이 있다.

Javascript(Behavior Layer: 행동계층)

나서지 않는 Javascript (Unobtrusive Javascript: 겸손한 Javascript)

위의 나서지 않는 Javascript에 대해 설명한 것을 더 자세히 설명하자면, HTML에는 Javascript 코드를 전혀 넣지 않아야 한다. 예를 들어, 아래와 같은 코드가 있다면,

<a href="help.html" onclick="helpPopup()">help</a>

아래 코드가 더 낫다.

<a href="help.html" id="myID">help</a>

<script>
    addListener("myID", "click", helpPopup);
</script>

즉, onmouseover, onmouseout 과 같은 이벤트 핸들러들이 HTML 문서에 포함되지 않도록 하고, 나중에 Javascript를 통해 적용시키자.

Javascript는 기능 강화용으로 사용하자

예를 들어, Drag and Drop으로 순서를 정렬하고, 정렬될 때 Ajax로 순서를 정하는 페이지의 경우, Javascript를 지원하지 않는다면 셀렉트박스를 사용해 순서를 지정하고, 폼을 제출했을 때 적용되는 방법을 사용할 수 있다. 즉, Javascript를 통해 사용자 경험을 강화하고, 지원하지 않는 경우에도 중요한 기능은 유지되도록 해야한다.

객체가 존재하는지 검사하자

엘리먼트의 색상을 변경하는 아래와 같은 코드를 생각해보자.

function color(o, col) {
  o.style.background = col;
}

만약, o 라는 엘리먼트가 없다면 이 코드는 에러를 낼 것이다.

이 코드를 아래와 같이 바꿔보자.

function color(o, col) {
  if(o) {
    o.style.background = col;
  }
}

객체가 존재하는지 미리 체크하므로, 존재한다면 원하는 효과를 낼 것이고, 존재하지 않으면 사용자 경험을 해치지 않고 별 다른 메시지를 내지 않으면서 작동하지 않을 것이다.

유효성 검사(Validation)

Javascript에서 가장 좋은 유효성 검사기는 JSLint 이다. 여기서 나는 “유효성 검사”의 뜻을 조금 더 확장시켜 사용했다. 왜냐하면 유효성 검사라는 말을 스펙에 엄격하게 맞는 지 검사한다는 뜻 뿐아니라, 건강한 Javascript에 반하는 코딩 습관들까지도 검사한다는 뜻으로 사용했기 때문이다. JSLint는 Douglas Crockford가 만든 것이고, Javascript로 짜여진 Javascript 프로그램이다. 이 프로그램은 세미콜론이 빠진 것, Array 마지막 요소 후의 콜론, 굳이 전역변수일 필요가 없는 전역변수 등을 찾는다. 즉, 코드에서 보푸라기(lint)를 찾아주어 코드를 더 건강하게 하는 것이다.아마 이 도구를 도입하면 처음에는 기분이 좀 상할 수도 있겠다. 왜냐하면 더 좋다고 생각되는 코드를 엄격하게 강요하기 때문이다. 우리의 코드품질은 이 도구를 사용하기 시작하면서 부터 정말 엄청나게 높아지고있다. 하지만 Javascript 코드 작성의 개인적인 스타일을 고치는 데에는 학습곡선이 필요할 것이다. 디버깅을 할 때, 동료에게 코드 디버깅을 요청할 때, 예절바르게 JSLint님께 먼저 물어보고 사람들이 일반적으로 아하!(gotcha) 하는 부분을 챙겨보자. 디버깅을 할 때의 모든 일반적인 버그상황을 피할 수 있으므로 당신의 시간을 아껴줄 것이다.

최적화

최적화 관점에서, 두가지 방법을 추천한다. 첫번째는 YUI compressor 를 사용해 코드를 줄이는 것이다. 이 프로그램은 긴 단어를 짧게 하고, 공백과 주석을 제거한다. JSLint가 모든 세미콜론을 정확한 위치에 사용하도록 하기 때문에 JSLint이후에 이 프로그램을 사용하면 공백을 줄였을 때 따르는 문제가 전혀 없으므로 완전히 안전하다고 할 수 있다. 따라서 JSLint와 YUI compressor를 사용하면 사람이 읽기는 어렵지만, 사용하기 쉽고, 압축된 코드 묶음을 얻을 수 있다. YUI compressor는 Javascript 뿐 아니라 CSS에도 적용할 수 있다. CSS에도 마찬가지로 주석과 공백을 없앤다. 많은 경우, 코드를 소스 저장소(SVN 등)에 체크인할 때 자동 실행되도록 빌드 프로세스에 넣는 것이 매우 유용하다.

더 많은 Javascript 소프트웨어를 만들 수록 전통적인 컴퓨터 과학의 관습을 더 많이 받아들이게 된다. 그 중 하나는 바로 단위 테스트이다. YUI Test는 Javascript 단위테스트를 작성하기 위한 테스트 프레임워크이다. 간단한 문법으로 구성되어, 정말 빠르고 쉽게 단위테스트를 빌드할 수 있고, 좋은 기능들도 많이 있다. 예를 들어 DOM event를 시뮬레이션할 수 있어서 여러브라우저에서 테스트가 가능하고, 어떤 인터랙션을 할지 스크립트로 짜두고 결과를 살펴볼 수 있다. 테스트 코드의 크기가 너무 크다면 그룹으로 만들고, 이 여러 그룹을 한 묶음으로 만들 수도 있다. 또, 어떤 코드들의 속도측정도 가능하다.

마지막으로, 데이터 전송이다.

Yahoo! 에서는 Ajax 기반의 통신을 다룰 때 YUI의 Connection Manager를 사용한다. 이 프로그램도 많은 기능이 있다. 모든 폼을 묶어 직렬화(serialize)할 필요 없이 한번에 전송하는 기능도 그 중 하나다. 우리는 데이터를 전송할 때 XML보다는 군살없는 JSON형식을 많이 사용한다. 이는 JavaScript가 스스로 지원하는 방법이고, 매우 가볍고, 플랫폼에 의존하지 않기 때문이다.

데이터 전송에 대해 한가지 더 말하자면, 데이터 전송시에는 꼭 보안을 신경써야 한다. frontend engineer들은 주 업무가 보안이 아니다. 하지만 우리의 코드는 노출되어있고, 따라서 이 코드 때문에 보안문제가 생길 여지도 있다. 보안에 대해 잘 모르겠다면 Yahoo!에는 보안 컨설팅 그룹이 있으므로 문의해야만 한다. 서버와 통신할 때는 언제나 주의하고 그리고 이따금씩, 지속적으로 보안문제가 우리가 신경쓰는 모든 것이 되어야 한다.

왜 이 모든 것이 중요한가

우리의 디자이너에게 영감을 불어넣고 교육을 하는 것은 대개 우리의 일이다. 오랜 시간 동안 우리는 디자이너에게 이런저런 일들을 할 수 없다고 말해왔다. 우리의 대답이 바뀌기 시작하면, 디자이너들도 진의를 바르게 파악할 것이다. 그리고 그렇게 되면 그들도 할 수 있는 한 최선을 다할 것이다. 따라서 나는 이것이 우리의 일이고, 어떤 것이 가능한지를 그들에게 보여주어야 한다고 생각한다. 새로운 인터렉션에 대해 프로토타입을 제작하고, 그들을 위해 한계를 넓혀보자. 이것은 우리가 디자인을 잘 해서가 아니라, 브라우저에서 무엇이 가능하고 무엇이 불가능한지 잘 알기 때문이다. 우리가 이런 새로운 역할을 하게 되면, 디자이너와 이런 것들을 공유하고, 디자인 속에 어떻게 녹여낼지 그들에게 고민해보도록 할 수 있다. 따라서 그들의 도구 상자안에 도구를 하나 더 넣어주는 것이 우리의 일이고, 그들의 일은 그 도구를 어떻게 사용할지 알아내는 것이다.

디자이너와 협업하는 다른 방법은, 프로젝트에 일찍 관여하는 것이다. 오랫동안 생각해본 결과, 만약 그렇지 않으면 우리가 옳은 것을 위해 싸울 수 없기 때문이다, 오늘의 제안이 내일은 불만이 된다. 우리는 정말로 우리가 할 수 있는 최대와 구현할 수 있는 가장 좋은 방법에 대해 그들에게 확실히 말해 줘야 한다. 그럼으로써 우리의 기반을 확고히 할 수 있고, 장래에 더 재미있는 일과 더 많은 일을 할 수 있다.

왜 이 모든 것이 중요한가

우리는 해야할 일이 많다.

우리는 더 많은 frontend engineer들이 필요하다.

우리 회사는 건강한 인터넷에 의존한다.

만약 우리가 웹을 사람들에게 더 좋게 만든다면, 웹은 계속해서 번성할 것이다. 우리회사는 웹이 그 기반이 되므로, 웹의 번영은 곧 우리 회사의 번영과 직결된다.

경계를 늦추지 않아야 한다.

새로운 기술들이 나오고, 새로운 브라우저들이 나오고 있다. 우리는 언제나 이런 것에 대해 잘 알고 있어야 한다.

Frontend engineer들이 사용자 경험에 큰 책임을 가지고 있기 때문이다.

스크린리더로 접근하든, 특정 브라우저로 접근하든, 모바일로 접근하든 그들에게 좋은 경험을 주는 것이 우리의 책임이다.

마지막으로 우리가 방어선의 마지막에 서있다.

이 것은 사용자에게도 마찬가지지만, 더 중요하게는 프로젝트의 라이프 사이클 관점에서이다. 우리는 디자이너의 작업물, 백엔드의 작업물 등을 통합하는 역할을 한다. 프로젝트가 서비스 되기 전의 마지막을 우리가 담당하고 있다. 그러므로 무언가 잘못되고 있다면 손을 들어 지적해야 한다.

사용자를 대변하고, 다음 세대의 인터넷, 최선을 다해 최고의 인터넷을 만드는 것이 우리의 일이다.

JS프로그램의 압축(Compression of JavaScript Program)

원문은 http://j.mp/gl4jDq 에서 보실 수 있습니다. 오역의 가능성이 있으니 원문과 비교하며 보세요~

왜 자바스크립트를 압축해야 할까?

JS파일을 압축해야하는데에는 여러 이유가 있을 수 있을 수 있습니다. 네트워크 대역폭을 줄이고자 하는 것이 가장 명백한 이유가 될 수 있는데, 이는 HTTP 압축을 통해 달성할 수 있습니다. 그러나 HTTP 압축에 의존할 수 없거나 허용되지 않는 예외적인 경우가 있을 수 있습니다. 제 흥미를 끈 것은 JS파일 크기에 강제적인 제한을 둔 몇몇 데모 공모전이었습니다. 예를 들어, WebGL 64k Contest 에는 다음과 같은 규칙이 있습니다.

  • 제출되는 파일의 사이즈는 64k 이하일 것(65536바이트)
  • 외부요청이 없을 것, 모든 것은 JS내에 인라인으로 포함시킬 것.

두번째 포인트를 보면, 모든 이미지나 음악 등의 자원들이 JS 소스코드로 인라인되어야 하고, 첫번째 포인트에 따르면 소스코드는 65536바이트를 넘지 않아야 합니다. 꽤 도전적이네요! 재미있는 프로그램을 만들기 위해 여러분은 주어진 용량을 효율적으로 사용해야 합니다. 따라서 압축이 필요합니다.

The Google Closure Compiler

가장 중요한 것을 먼저 봅시다. Google에서 공개한 Google Closure Compiler라는 도구가 있습니다. 이 도구는 기본적으로 아래와 같은 방법을 통해 JS코드의 용량을 최소한으로 줄입니다.

  • 모든 주석과 불필요한 공백 제거
  • 변수명과 프로퍼티명을 더 짧게 변경
  • 표현문과 구조를 더 압축된 형태로 리팩토링

말할 것도 없이 JS소스코드를 압축하려는 모든 시도는 closure compiler를 사용하는 것으로부터 시작됩니다. 아울러 이 글에서는 이미 closure compiler로 압축되어있는 코드에서 더 나아가 바이너리 압축을 적용시키는 것에 초점을 맞출 것입니다.

압축방법 결정하기

우리가 당면한 주요문제 중 하나는 JS 프로그램이 스스로 압축해제가 가능해야 한다는 것입니다. 따라서 압축해제 루틴이 너무 많은 공간을 차지하면 압축의 이득을 잃게 됩니다. 또다른 문제는 바이너리로 압축된 데이터 스트림이 JS소스로 저장이 가능한 형태여야 한다는 것입니다.

기존의 라이브러리들

압축해제 루틴이 작아야 하므로, 기존의 (효율적이지만 크기가 큰) JXGraph, js-deflate와 같은 압축해제 라이브러리들은 실격입니다.

liblzg 사용하기

저의 첫번째 해결책은 liblzg 압축 라이브러리를 사용하는 것입니다. 이 라이브러리는 경량화된 압축해제 루틴을 가질 수 있도록 특별히 디자인되었습니다. 압축해제루틴은 불과 450바이트 정도에 불과하며(조금 손을 보면 더 작아질 수 도 있습니다) 우리의 필요에 잘 맞습니다.

바이너리 데이터 다루기

이제 다른 문제가 있습니다. 어떻게 바이너리 데이터를 js 소스 파일로 담을 수 있을까요?

Base64

바이너리 데이터를 텍스트 파일로 저장할 수 있는 검증된 방법은 물론 base64 를 통한 방법입니다. 그러나, 이 방법은 텍스트 한글자마다 6비트밖에 사용할 수 없기 때문에 33%의 용량(8비트 문자 인코딩인 경우)을 더 써야 합니다. 이런 용량증가는 압축률에 심각한 영향을 미칠 것 이므로 더 좋은 방법을 찾아봐야 합니다.

Latin 1

첫번째로 시도해봤던 방법은 Latin 1 인코딩을 사용하는 방법이었습니다. 즉, 압축된 바이트 데이터를 Latin 1으로 인코딩해 JS 문자열로 저장한 것입니다. 물론, 인코딩의 한계로 몇몇 바이트 값이 금지(더 정확하게 말하면, 0~31, 39, 92, 127~159번)되어 있기 때문에 조금 손보지 않으면 작동하지 않습니다. 사용할 수 없는 바이트코드를 2바이트 문자로 대체시키고, (liblzg로 압축된 데이터의 통계에 기반해) 자주 쓰이지 않는 바이트코드를 사용할 수 없는 코드와 교환하게 되면 용량을 증가시킬 요소는 5~10% 정도로 줄어들 수 있습니다. 자, 이것보다 더 줄일 방법은 없을까요?

UTF-16

할 수 있습니다! Latin 1 인코딩을 사용했을 때 0~255번 코드 사이의 26%는 사용할 수 없다는 것에 주목하면, UTF-16 인코딩의 사용할 수 없는 코드는 3%에 불과 합니다(0~65535번 코드 사이에 2151개의 코드). 그럼 UTF-16를 사용해 JS 프로그램을 줄여봅시다. 브라우저가 UTF-16을 이용하는 것을 인지할 수 있도록 파일 시작 부분에 2바이트의 BOM이 추가됩니다(사실 클라이언트 프로그램이나 텍스트에디터에서 Latin 1 인코딩을 UTF-8로 혼돈하는 경우가 있기 때문에 UTF-16이 Latin 1을 사용하는 것보다 더 안전합니다). 이제 압축된 데이터 스트림 2바이트를 1개의 UTF-16 글자로 줄일 수 있게 되었고, 다시 한번 사용할 수 없는 코드에 대한 처리를 하고 나면, (사용할 수 없는 코드를 사용할 수 있는 UTF-16 코드 2글자로 대체), 4%미만의 용량이 증가합니다 (liblzg 압축된 데이터의 경우에는 거의 1%미만 입니다).

UTF-16 인코딩의 단점

UTF-16인코딩을 사용하는 데에 심각한 문제가 하나 있습니다. 압축해제 루틴도 UTF-16으로 저장되어야 한다는 것입니다. 즉, 압축해제 로직이 2배의 용량을 차지하게 된다는 뜻입니다.(900바이트 이상). 작은 파일에서는 최종 파일의 크기가 Latin 1 인코딩을 사용하는 것보다 더 크게 될 겁니다. 하지만 걱정할 것은 없습니다. 해결책은 가까이 있으니까요. 압축해제 루틴도 줄일 수 있습니다. 어떻게 가능할까요? 바이너리 데이터에 했던 것과 같이 2개의 글자를 UTF-16 글자 한개로 만들어봅시다. 압축해제 루틴은 순수한 ASCII코드(36~126번 사이의 글자들)이라는 좋은 특징을 가지고 있습니다. 이것은 두개의 연속된 바이트를 한개의 유니코드로 합치면 “언제나” 유효한 글자가 된다는 뜻입니다(2020-7e7e 사이의 UTF-16코드는 전부 유효합니다). UTF-16 문자열로 표현된 압축해제 루틴이 사용할 수 없는 코드를 만들지 않기 때문에 공간을 전혀 낭비하지 않게 되고, 이 루틴을 다시 되돌리는 작업도 매우 간단합니다. 네, 되돌리기 위해 또다른 루틴이 필요하고, 이 루틴은 순수한 UTF-16 형식이어야 합니다. 하지만 새로 만들 루틴은 그렇게 많은 코드가 필요치 않고 아주 간단합니다. 이 루틴은 아래와 비슷할 겁니다(closure compiler를 통하지 않은 모습입니다).

liblzg를 통한 접근의 결론

지금까지 우리는 스스로 압축을 해제할 수 있는 JS 프로그램을 만들기 위해 최대한으로 liblzg 압축을 활용했습니다. 요약하면 :

  • 스스로 압축해제가 가능한 JS 모듈(약 600바이트)
  • (원래의 바이너리 크기보다 3%정도 더 큰) 아주 잘 압축된 바이너리 데이터
  • (크로스 브라우징이 아주 잘 되는) 순수 ECMAScript 구현
  • (DEFLATE, Bzip2, LZMA 등 보다는 떨어지지만) 적절한 압축률

좋은 결과에 도달하긴 했지만, 더 잘할 수도 있습니다.

더 잘 해보기 – PNG

JS로 브라우저 API에 접근해 DEFLATE로 인코딩 된 데이터를 풀어낼 수 있으면 얼마나 좋을까요? 대부분의 브라우저는 여러가지 작업을 위해 내부적으로 zlib을 사용하지만, zlib을 JS로 직접접근하는 방법은 아직 없습니다. 하지만 우리가 IE 6,7, 8과 같은 기존 브라우저에 대한 호환성을 희생시키면 엘리먼트를 사용한 다른 멋진 트릭을 사용할 수 있습니다. JS프로그램을 PNG 이미지 파일 내에 저장시키는 것입니다. 이 방법은 어떤 장점이 있고, 어떻게 사용할 수 있을까요?

PNG 아이디어

자, PNG 이미지 파일 포맷에 대해 약간의 배경지식을 가져볼까요.

  • PNG는 압축하는데에 DEFLATE알고리즘을 사용합니다(이것은 이를테면 ZIP과 gzip에 사용되는 것과 비슷합니다).
  • 무손실 파일 포맷입니다(어떤 픽셀도 왜곡시키지 않습니다).
  • 모든 최근의 브라우저들은 Image 객체로 로딩 될 때 PNG 이미지를 해석할 수 있습니다.
  • PNG 이미지를 canvas 엘리먼트로 그릴 수 있고, getImageData() 메서드를 통해 픽셀들을 다시 읽어들일 수 있습니다.

다시 말하면, canvas 엘리먼트의 도움으로 PNG 이미지를 압축해제할 수 있고 그 내용을 (eval을 사용해)실행 가능한 JS의 String 객체로 풀어낼 수 있다는 것입니다. 우리는 다시한번 원래의 PNG 이미지 데이터를 JS 문자열로 바꾸는데 너무 많은 용량 증가 없이 UTF-16트릭을 사용할 수 있습니다.

압축해제 로직

liblzg 해결책을 사용했을 때는 압축해제 코드가 별도로 필요했습니다. 이번에는 실제 압축해제 알고리즘은 필요가 없고, 다만 대략 아래와 같은 순서를 따르는 작은 프로그램이 필요합니다.

  1. UTF-16 문자열을 바이너리 문자열로 디코드
  2. btoa()메서드를 사용해 바이너리 문자열을 Base64로 인코드
  3. “data:image/png;base64,”라는 작은 헤더를 앞에 붙인 data URI를 생성
  4. data URI를 Image 객체로 로드
  5. 이미지의 onload 핸들러에서
    1. 이미지를 canvas 엘리먼트로 그리기
    2. pixel 값을 읽어들여 새로운 문자열로 할당
    3. 문자열의 내용을 실행

이 압축해제 프로그램의 크기는대략 liblzg 디코더와 비슷하지만, 다른 측면에서 DEFLATE 압축 방법은 더 좋은 압축률을 보입니다(주요 원인은 liblzg는 오직 LZ77 압축만을 사용하는데 반해, DEFLATE는 LZ77과 Huffman 압축을 조합해 사용하기 때문입니다).

PNG를 통한 접근법의 결론

지금까지 위에 설명된 PNG를 통한 방법은 압축률과 관한한(압축해제 루틴을 압축된 컨텐츠의 일부로 포함했을 때), 주어진 목표 내에서 현재의 브라우저 기술을 최대한으로 이용했습니다. 이 방법의 장점들은

  • DEFLATE 압축해제 루틴을 브라우저 내에서 재 사용
    • 일반적으로 사용 가능함(PNG를 지원하는 모든 브라우저)
    • 매우 좋은 압축률(JS 코드가 잘 압축됨)
  • 순수한 PNG 데이터를 유효한 UTF-16 문자열로 인코드
    • 바이너리 데이터를 문자열로 인코딩할 때 매우 낮은 오버헤드(Base64의 33%에 비교했을 때 3~4%에 불과)
    • 브라우저가 잘못 해석할 가능성이 매우 낮음

끝내기 – CrunchMe

여기 설명된 압축방법들이 여러분께 유용하고 흥미로웠으면 합니다. 여러분이 자신의 JS 프로그램을 압축하고자 한다면, CrunchMe 라는 오픈소스 커맨드 라인툴이 있습니다. 참고 : 이 글을 쓰고 있는 현재 CrunchMe는 아직 개발중입니다. 하지만 일반적인 사용에는 충분히 안정적일 겁니다. (그렇긴하지만, 스스로 컴파일 해야할 겁니다).

위지윅(WYSIWYG) 에디터를 만들고자 할 때 고려할 사항

원문은 http://bit.ly/ksonHb 에서 보실 수 있습니다.

1. iframe docs vs. contenteditable divs

위지윅에디터를 제작하고자 할 때 iframe을 사용할 지, 어느 엘리먼트에나 존재하는 contenteditable 속성을 이용할 지 고민될 수 있습니다. 답변자는 iframe을 추천합니다. 그 이유로:

iframe내에서는 문서 타입, CSS, script 등을 이용해 완전한 제어를 할 수 있습니다. 여러 다른 페이지내에서 통일된 액션과 모습을 보여주는 데에 꼭 필요합니다. 특히 Firefox에서 contenteditable 속성을 가진 엘리먼트가 매우 버그가 많은데, 이것은 몇 년 전부터 있어왔고 아주 잘 동작하는 document의 designMode속성에 비해(pre-1.0 부터인가? 확실하지 않습니다) 이 속성이 비교적 최근에(3.0버전부터) 도입되었기 때문입니다.

2. Cross browser styling

execCommand는 볼드, 이탤릭 등 엘리먼트에 스타일을 입히도록 하는 역할을 합니다. 문제는 각 브라우저 마다 이 메서드를 실행했을 때 어떤 브라우저는 볼드를 <b>로, 어떤 브라우저는 <strong>으로 표시하는 것과 같은 문제가 발생할 수 있습니다. 이것을 통일 시키는 방안에 대해 답변자는 이렇게 이야기 합니다.

만약 여러 다른 브라우저에서 통일된 결과물을 얻는 것이 중요하다면, 아마 자기만의 스타일링 코드를 작성해야 할 겁니다. 그렇지만, 이렇게 하면 브라우저에 내장된 되돌리기(undo) 작업을 불가능하게 할 것이므로 자기만의 되돌리기(undo)/다시실행하기(redo) 코드를 만들어야 할 겁니다.

3. adding items to the undo chain

Q:브라우저에 내장된 되돌리기/다시실행하기 작업이 저장된 배열이 있을까요? 그리고 그것을 수정할 수 있을까요?

A: 브라우저 내장의 되돌리기 스택에 접근할 수 있는 방법은 없습니다. 스스로 작성하셔야 합니다.

4. keeping the text selection

Q: 글자체를 선택하는 것과 같이 포커스가 이동하면서 블럭지정이 풀려버리는데, 블럭지정한 텍스트를 어떻게 유지할 수 있을까요? Rangy나 Google closure 외에 다른 라이브러리가 있습니까?

A: 이 질문이 가장 흥미롭습니다. 바로 제가 Rangy를 작성했거든요. 이와 같은 일을 하는데에 더 좋은 라이브러리는 없다고 생각합니다. Google Closure는 범위/선택과 관련한 API를 가지고 있지 않지만 DOM Range와 일반적인 브라우저의 Selection 객체보다 더 우선한 자신만의 인터페이스를 사용한다고 생각합니다. IERange는 Rangy와 비슷한 아이디어를 가진 라이브러리이지만 구현된 범위가 적으므로 지금당장은 고려대상이 아니라고 생각합니다.

p.s. 재미있는 것은, 그 아래의 답변입니다. “진심으로 말하는데 그냥 나와있는 것을 쓰세요” 라는데, 무려 3명이나 추천했군요 🙂

더 나은 SEO를 위해 알기쉬운 사이트 구조 작성하기

원문: Intelligent site structure for better SEO!

검색엔진은 오늘날 사이트에 방문자를 이끌어주는 가장 중요한 방법 중 하나이다. 따라서 검색엔진 최적화(Search Engine Optimization)은 매우 중요하다. 하지만 SEO는 종종 기술적 꼼수 모음으로 오해받곤 한다. – SEO전문가로서 고객들과 기술적인 이슈를 고치는 데에 많은 시간을 들였음을 고백한다. – 사이트의 구조는 검색엔진이 사이트의 주제가 무엇인지, 그리고 얼마나 쉽게 사이트의 목적과 의도에 맞는 컨텐츠를 찾고 색인화 할 수 있는지를 결정한다.

좋은 구조를 만듦으로써 다른 사람들로부터 링크를 받은 여러분의 컨텐츠를 활용할 수 있고, 사이트의 구조를 이른바 “링크주스(linkjuice)”와 같이 여러분 사이트의 다른 페이지에 배치해 놓을 수도 있다.

상업적인 사이트라면 질 좋은 컨텐츠를 여러분의 판매 페이지의 랭킹을 높이는데 사용할 수도 있다. 왜 필요한지 이제 관심이 좀 생겼을까? 지금까지 무엇을 왜 할지 알았으니 이제는 어떻게 하는지 알아볼 차례다. 

좋은 사이트 구조 만들기

새로운 사이트를 개발하거나 개편할 때, Visio나 하다못해 엑셀에 집어넣더라도 사이트의 구조를 그려보는 것이 도움이 된다. 여러분이 할 것은 그림 1과 같이 모든 페이지와 섹션을 트리로 만들어내는 것이다. (저자의 옛 사이트 구조에 기초함):

그림 1: 전형적인 사이트 구조

그림 1: 전형적인 사이트 구조

Code섹션이 전체 사이트의 반이상으로, 현재 균형이 맞지 않음을 볼 수 있다. 사이트 구조를 합리적이고 균형잡힌 피라미드 모양으로 만들어내야 한다. 사이트 내의 컨텐츠 양에 따라 2개에서 7개 사이의 메인섹션으로 구성하고 다른 섹션 대비 2배 이상 큰 섹션이 있으면 안된다.

또 다른 몇몇 포인트들이 있다. 먼저, “About Me”, “Projects”, “Websites”와 같은 기본적인 자기 소개 페이지가 3개나 있다. 또한, 내 사이트의 통계를 검토해보니 3레벨과 4레벨에 있는 Word Press 페이지가 사이트 트래픽의 30% 가량을 차지하고 있음을 알았다.

Visio나 OmniGraffle 과 같은 툴의 이점은 재정렬을 매우 쉽게 해주고, 새로운 구조가 잘 작동할 것인지 좋은 느낌을 받을 수 있게한다는 것이다. 나는 가끔 책상이나 벽에 포스트 잇을 붙여놓고 사용하기도 하는데, 둘다 나에게는 잘 맞는다.

그림 2는 재정렬한 결과이다.

그림 2: 개선된 섹션 구조

그림 2: 개선된 섹션 구조

그림에서 보듯 몇몇 페이지는 트리의 상단으로 이동시켰고, 또 몇몇 페이지는 제거했다. 사이트 구조를 다시 생각하다보면 어떤 페이지들은 사용자들에게 별로 이롭지 않은 것을 자주 발견하게 될 것이다. 그런 경우에는 없애는 것이 최선이다.

또 블로그를 홈으로 옮기기로 결정했다. 내 홈페이지에는 터무니없는 이야기도 많고, 그리고 또 본질적으로는 또 다른 “About Me” 페이지의 하나이다. 나 자신에 대해 부끄러운건 아니지만 블로그가 내 사이트의 방문목적이 되는 것을 원치는 않는다. 내 블로그는 내 사이트의 토대이므로 블로그도 이 구조의 중요한 위치에 배치했다.

섹션에 이름 짓기

사이트 구조에 만족했다면 섹션의 이름들에 대해 생각해 볼 차례다. 만약 섹션을 구성할 수 있을만큼 각 주제의 컨텐츠의 양이 충분하다면, 그만큼 많은 사람들도 검색을 통해 찾아올 것이라고 확신할 것이다. 이것이 바로 섹션의 이름을 사람들이 검색어로 활용하는 키워드로 만들어야 하는 이유가 되는 것이다!

예를 들어, 여러분이 나처럼 워드프레스 플러그인을 만들고 다른 사람들을 위해 섹션을 만들었다고 해보자. 이 섹션의 이름이 “워드프레스” 여서는 안된다. 여러분은 어떻게 검색할 것인가? “워드프레스 플러그인”으로 검색하지 않을까? 그러므로 “워드프레스 플러그인”과 같은 이름을 지어야 한다(이것은 “워드프레스”라고 부르지 말라는 의미가 아니고, 페이지 타이틀과 네비게이션 링크를 “워드프레스 플러그인”으로 만들라는 의미이다). 사람들이 어떤 검색어로 검색하는지를 알고자 한다면 아래 도구 들이 도움이 될 것이다.

섹션과 하위 섹션에 알맞은 이름을 결정한다. 이제 반 정도왔다. 이제 같은 방법으로 각 페이지들의 이름을 짧고 간결하게 결정한다. 내 섹션들은 이제 그림 3과 같은 이름을 가지게 되었다.

그림 3: 알아보기 쉬운 섹션이름을 가진 사이트 구조

그림 3: 알아보기 쉬운 섹션이름을 가진 사이트 구조

지금까지 우리는 사이트 구조 정의에 가장 중요한 두가지를 해왔다. 앞으로는 또 다른 몇몇 중요한 포인트에 대해 생각해보고자 한다.

숙지해야 할 몇가지 사항들

다음은 사이트 구조를 결정할 때 숙지해야 할 몇가지 사항들이다.

포럼과 같이 사용자가 조정하는 컨텐츠

만약 사이트의 한 부분이 다른 부분보다 훨씬 더 많은 컨텐츠가 있고, 더 많이 생산 되는 곳의 질은 상대적으로 떨어진다면, 아마도 두 곳을 섞는 것이 꺼려질 것이다. 예를 들어, “A List Apart”의 같은 초기화면을 생각해보면, 몇 주마다 아주 양질의 글들이 업데이트되고 이 글들은 다른 사이트들에 많이 링크된다. 또 다른 섹션은 포럼이다. 포럼은 그 질이 보장되지 않는 글들이 매일 몇개씩 올라오는 곳이다.

여러분의 포럼은 아마도 사이트 첫페이지의 검색 순위를 떨어뜨릴 것이다. 왜냐하면 사이트의 ranking strength 가 양질의 컨텐츠에서 포럼으로 흘러가기 때문이다. 따라서 이 둘을 함께 유지하기 위해서는 포럼을 사이트의 서브도메인으로 옮기도록 하라.

여러분이 운영하는 블로그는 상대적으로 문제가 되지 않는다. 블로그의 글들은 상대적으로 질이 보장되어 있고 여러분은 블로그 글 또한 검색 순위에 오르는 것을 바랄 것이기 때문이다.

중복된 카테고리와 태그

여러 카테고리를 갖는 사이트나 블로그가 빠지기 쉬운 함정은 특정 글들에 대해 지속적으로 비슷한 두 개의 카테고리를 배정하는 것이다. 예를 들어 사이트에 “브라우저”와 “오페라”라는 카테고리가 있다고 하고, 여러분은 오페라에 대해서만 글을 작성한다고 하자. 이제 브라우저 카테고리의 리스트를 보게되면 아마도 오페라 카테고리의 페이지들과 완전히 같은 컨텐츠가 존재하게 된다. 이 두가지는 기본적으로 중복이다.

태그를 사용하면 이 문제는 더 자주 일어나게 된다. 아마도 “이것이 왜 문제가 되나요?” 하고 놀라게 될텐데, 몇몇 사용자가 컨텐츠가 너무 마음에 들어 모든 포스트를 링크하려고 한다고 해보자. 이제 여러분은 그들이 어떤 카테고리의 것들을 링크하게 되는지 통제할 수 없게 된다. 어떤 사람은 “브라우저” 카테고리를 링크하고, 또 어떤 사람은 “오페라” 카테고리를 링크한다. 이런 일이 여러 번 일어나게 되면, 여러분은 good link를 던져버리는 꼴이 된다.

만약 2개의 링크가 “브라우저”카테고리로 연결되고, 2개의 링크는 “오페라” 카테고리 페이지로 연결된다고 해보자. 인기가 덜한 경쟁자의 사이트에는 “오페라”카테고리가 없고 한 개의 “브라우저”카테고리에 3개의 링크를 가지고 있다. 모든 상황이 같다고 단순가정하면 경쟁자가 당신보다 상위에 랭크되게 된다.

내부 링크 구조

구조를 잘 만들었다면, 피라미드처럼 보여야 한다. 이제 이 피라미드 사이에서 어떻게 연결할 것인지를 결정해야한다. 섹션들을 큰 미라미드 내의 작은 피라미드처럼 생각해보자. 각 미라미드의 꼭대기는 그 서브페이지들과 모두 연결되어야 하고, 서브페이지들도 꼭대기와 연결되어야 한다.

컨텐츠 관점에서 각 페이지들이 긴밀히 연결되어 있으므로, 사이트가 검색에 걸리게 될 확률이 높아진다. 여러분은 검색엔진에게 어떤 것이 관련되어 있고 어떤것이 연관되지 않는지를 알려주게 된다.

그림 4를 보자.

그림 4: 각 섹션 내에서 페이지들을 서로 어떻게 연결해야할지 고려해야 한다.

그림 4: 각 섹션 내에서 페이지들을 서로 어떻게 연결해야할지 고려해야 한다.

각 페이지가 잘 연관되어 링크되도록 해야한다. 예를 들어, 서브페이지 3이 플러그인 2를 항상 링크하고 있다면, 사실은 플러그인 4와 연관됨에도 불구하고 검색엔진은 서브페이지 3이 플러그인 2와 연관되어있다고 여길 것이다.

새로운 사이트구조에서의 URL

새로운 사이트 구조를 만들어냈으면, 이제 다음단계로 이 구조에 맞는 URL을 만들어야 한다. 각 페이지의 URL은 그 페이지의 컨텐츠를 나타내야 한다. 어떤 키워드로 노출 될지를 결정했다면, 가장 중요한 한 개의 키워드를 URL에 포함시켜야 한다.

새 URL을 결정할 때 기억해야할 것들은

  • 여러 단어는 하이픈(-)으로 분리하라.
  • Unix나 Lunux서버는 대소문자를 구분하기 때문에 대소문자를 섞으면 절대 안된다. 대소문자가 섞인 URL은 오타의 가능성을 엄청나게 높인다 – /LoOks/LiKe/ThiS/ 와 같은 URL을 잘 기억할 수 있을까?
  • 숫자는 여러분의 CMS에게나 쉽지 사용자에게는 어렵다. 숫자가 섞인 URL은 사람에게는 어렵기 때문에 기억하거나 링크될 확률을 줄인다. – 숫자를 사용하지 마라.
  • 될 수 있으면 URL은 추정하기 쉽게 만들어라. 사람들에게 기억되기 좋은 URL은 그들이 친구들과 이것에 관해 이야기하기도 쉽게 만든다.
  • 301 Redirect를 통해 이전 페이지에서 새 페이지로 리디렉트 시켜라. 301 Redirect는 완전한 이동을 뜻하고, 검색엔진은 이전 링크 값을 새로운 페이지로 대치시킬 것이다.
  • 컨텐츠가 한 URL에만 있도록 하라. 예를 들어 프린트 스타일시트를 사용한다고 하면 인쇄를 위해 또 다른 페이지를 가져야 할 아무런 이유가 없다.

주소와 관련한 정보나 일어날 수 있는 문제에 대해 더 알고 싶으면 저자의 중복된 컨텐츠라는 글을 참고 한다.

결론 : 여러분의 사이트 구조에 적용하기

좋은 사이트 구조는 검색엔진 최적화에 꼭 필요하다. 이는 사용자와 서치엔진 모두에게 사이트 내의 컨텐츠를 찾기 쉽게 한다. 좋은 구조는 카테고리가 잘 나뉘어 있고, 카테고리 내의 페이지들이 같은 주제끼리만 연결되는 것을 의미한다.

올바른 URL을 사용하는 것은 사용자들이 기억하고 링크하는 기회를 늘리고, 서치엔진에서 상위에 랭크될 가능성도 매우 높인다.

참고 : 나는 이 글을 2007년 10월 dev.opera.com에 기고했다. 이 주제에 대한 글이 필요하다는 결론을 내렸을 때, 오래 전 작성했던 이 글을 발견했다. 몇몇 참고링크를 더했을 뿐 중요하게 변경된 것은 없다.

회원가입 프로세스를 심플하게 만드는 17가지 방법

xguru님의 이번 주 기술뉴스에 포함된 “회원가입 프로세스를 심플하게 만드는 17가지 방법” 에 대한 간단한 번역입니다. 원문에는 이해가 쉽도록 이미지 등도 있으니 참고하세요~ 오역의 가능성은 다분합니다 -_-

  1. 이메일을 아이디로 만들어라
  2. 사용자가 항상 쓰는 비밀번호를 쓸 수 있게 하라. (복잡한 규칙을 설정하지 마라. 은행, 개인정보 등 민감한 사항을 다루는 웹사이트들은 예외.)
  3. 추가 정보는 우선 계정을 만든 다음에 받도록 해라.
  4. 만약 내 아이디(이메일)가 사용되고 있다면 (Ajax등을 사용해서) 바로바로 알려줘라. 만약 아이디(이메일)가 사용되고 있다면 바로 비밀번호를 타이핑하고 로그인할 수 있도록 비밀번호 필드를 보여주고, “이 이메일 주소로 비밀번호 찾기 메일 보내기” 와 같은 링크를 달아주자.(이미 가입한 사람이 가입했는지 잊어먹은 경우의 편의를 고려함.)
  5. CAPTCHA가 꼭 필요할까?
    • A/B 테스트를 통해 CAPTCHA가 제거 되었을 때 스팸 가입자가 증가하는지 살펴보라.
  6. 회원 가입 후에는 자동으로 로그인 되게 하라.
    • 뭔가를 필요로 해서 회원가입을 하는 것이므로 바로 접근가능하게 할 것.
  7. 환영 이메일을 찾기 쉽게 만들라
    • 예를 들어 Your [app name] account details 와 같은 제목을 사용하고 암호와 같은 보낸 사람 이메일 대신 보낸사람이름을 활용하라.
  8. 회원가입폼을 홈페이지에 드러나게 하라
    • 회원 유치가 주 목적이라면 facebook과 같이 회원가입폼을 드러나게..
  9. 회원 가입을 했을 때의 이점을 알려줘라

— 이 아래부터는 의견들.

  1. 회원 가입과 로그인을 한번에..
    • 이메일만 입력하게 하고 가입되어있으면 로그인 폼을 보여주고, 되어있지 않으면 회원가입폼을 보여줌
  2. 이메일만 받자
    • 이메일만 회원 가입시 받게 하고, 자신의 정보를 수정할 수 있는 링크가 포함된 메일을 보낸다. 언제나 이 메일의 링크는 자기 정보를 수정할 수 있도록 만듦으로, 패스워드 찾기 시에도 활용될 수 있다.
  3. 그냥 오픈아이디를 사용하자.
  4. 뉴스레터는 opt-out이 아닌, opt-in 방식으로 보내라 여기서 opt-in은 받겠다고 요청한 사람 opt-out은 거부하지 않은 사람.
  5. 내 브라우저가 자동으로 폼을 채워넣도록 해주세요. 브라우저의 자동완성 기능을 활용하는 사용자들을 위해 자바스크립트 등으로 초기값을 조정할 때는 신중하게.
  6. 사용가능한 비밀번호 형식을 미리 보여줘라.
  7. 어디서 가입이 가능한지를 알려줘라.
    • 로그인보다 회원가입을 강조하라
  8. 패스워드를 두번 넣게 하지마라.
    • 그냥 인풋 텍스트로 한번 받고 말지, 비밀번호 형식으로 2번 받을지 가입자에게 고를 수 있게 하라. (이것은 좀.. 그래도 트위터는 비밀번호 한 번 입력으로 가입이 가능하죠!)