Stay Hungry. Stay Foolish. Don't Be Satisfied.

기술 뉴스 #14 : 14-09-01

프로젝트 일정이 바빠서 8월 한달동안 뉴스레터를 쉬었다가 오랜만에 발행합니다.

웹개발 관련

  • Chrome Enchanted: 2014년 주목할만한 HTML5 규격 4종 : 도창욱님이 정리한 글로 Web Components, Web Animations, WebRTC, Service Worker 기술의 개념을 잡기에 잘 정리된 글이다. 개인적으로는 Web Components와 Service Worker에 관심이 있는 편이다.(한글)
  • JavaScript Memory Management Masterclass : JavaScript의 메모리 관련 성능개선과 관련해서 아주 깊은 내용까지 잘 정리된 발표자료(영문)
  • 온라인 장애 체험관 : 네이버 NULI에서 접근성 확대를 위해 온라인 장애 체험관 사이트를 열었다(한글)
  • 반응형 웹 디자인의 현재 : Smashing Magazine의 The State Of Responsive Web Design를 번역한 글로 반응형 웹과 관련된 기술들을 잘 설명한 글이다. 현재 반응형 웹을 구현하는 방법이라기보다는 현재의 문제점과 새로운 기술들이 어떻게 해결하려고 하고 있는지를 설명하고 있어서 반응형 웹 디자인에 관심이 있다면 알아둘 필요가 있는 내용이다.(한글)

그 밖의 프로그래밍 관련

  • Beautiful Open : 오픈 소스 프로젝트 사이트 중에서 디자인이 좋은 사이트만 모아놓은 곳(영문)
  • Common App Rejections : 애플이 앱스토어에서 앱 리뷰를 거절하는 이유를 정리해 놓은 페이지를 공개했다.(영문)
  • Java 9 Features Announced : 오라클에서 Java 9의 기능을 처음으로 공개했다. Java 8도 먼 얘기로 들리는 상황에 벌써 자바 9을 얘기하는 게 맞는지 모르겠지만, 경량 JSON API, HTTP 2 클라이언트 등이 포함되었다.(영문)
  • VisuAlgo : 정렬, 큐, 트리 등의 데이터 구조나 알고리즘을 동작 방식을 애니메이션으로 코드와 함께 보여주는 사이트. 알고리즘을 애니메이션으로 보여주는 사이트가 다수 있지만 깔끔한 디자인과 코드와 함께 보여주고 있어서 알고리즘을 이해하기에 좋다.(영문)
  • Open Sourcing the f8 Conference Apps : 페이스북이 인수한 DBaaS 업체인 Parse에서 페이스북 콘퍼런스인 f8용으로 만든 앱을 오픈 소스로 공개했다. 이 앱은 Parse를 기반으로 만들어졌다.(영문)
  • PYCON Korea 2014 : 국내 첫 파이썬 콘퍼런스가 지난 8월 30일에 숙명여대에서 열렸다. 나는 안타깝게도 참석을 못 했지만 콘퍼런스 사이트에 가면 발표자료를 볼 수 있다.(한글)

IT 업계 뉴스

볼만한 링크

  • 뉴욕타임스 혁신보고서(번역본) : 170페이지 정도의 PDF로 뉴욕타임스의 혁신보고서의 번역본이다. 내용이 길어서 다 읽어보진 못했고 IT 기술 내용이 위주는 아닌 것 같지만 관심 가는 주제라서 링크를...(한글)
  • GitHub – Cracking the Code to GitHub’s Growth : Github의 성장과 관련해서 분석한 글이다. 긴 글이지만 Github이 어떠한 전략을 사용하면서 성장했고 어떤 부분을 중요시하는지 잘 정리되어 있다.(영문)

프로젝트

  • Ment.io : Github이나 Facebook에서 하듯이 사람을 멘션하는 툴팁을 구현해 주는 Angular.js 용 라이브러리
  • C3.js : D3.js 기반 차트 라이브러리
  • howdoi : 쉘에서 코드 스니펫을 검색할 수 있는 파이썬 스크립트. howdoi format date bash와 같이 작성하면 bash에서 날짜 포매팅 코드를 바로 볼 수 있다.
  • fzf : 쉘에서 파일을 fuzzy 검색으로 찾을 수 있는 스크립트

버전 업데이트

2014/09/01 20:56 2014/09/01 20:56

관련 글

WanderWorld의 Parallax Scroll 랜딩페이지 개발 후기

이미 보신 분들도 있겠지만, 최근에 작업한 프로젝트 WanderWorld의 랜딩페이지를 만들었다. 이 랜딩페이지에서 소위 Parallax Scroll이라고 부르는 기법을 적용했고 SNS 등에서 어느 정도 이슈와 관심이 쏠렸다. 공개하고 나서 랜딩페이지 개발에 대한 공유 요청을 꽤 많이 받았는데 바빠서 미루고 있다가 이제야 정리를 한다.

슈퍼마리오의 Parallax

Parallax Scroll은 보통 전경과 배경이 다른 속도로 움직이는 것을 의미한다. 게임 같은 곳에서 많이 사용하는데 키랙터를 움직일 때 배경으로 있는 구름과 산이 다른 속도로 움직이고 뭐 이런 걸 Parallax Scroll이라고 부른다. 웹에서도 이 기법을 사용해서 상당히 인터렉티브하게 보이는 사이트가 유행처럼 지나갔고(내 체감으로는 작년 정도?) WanderWorld의 랜딩페이지도 이 기법을 이용했다. 요즘은 Parallax가 아니더라도 그냥 스크롤에 따른 애니메이션 효과는 모두 Parallax Scroll이라는 이름으로 부르는 분위기다.

Parallax Scroll은 랜딩페이지에 적합한가?

랜딩페이지를 오픈하고 나서 가장 많이 들은 얘기가 과도하다. 혹은 불필요하다 같은 얘기다.(버그 리포팅은 제외하고...) WanderWorld의 랜딩페이지는 상당히 긴 스크롤을 가지고 있고 이는 서비스를 소개하는 스토리텔링 기법을 사용하고 있지만, 사용자는 계속 스크롤을 해서 끝까지 가야 하고 그래야 서비스가 어떤 서비스인지 인식할 수 있다. 이 부분에 대한 지적인데 의도한 부분이지만 지적 자체는 합당하다고 생각한다. 실제로 랜딩페이지를 오픈하고 Reddit에 랜딩페이지에 관한 글을 올렸을 때 대부분 비슷한 반응을 보였다.(개발자로서 이때 약간은 의기소침 ㅠ)

WanderWorld의 랜딩페이지

먼저 랜딩페이지의 목적을 생각해 보자. 랜딩페이지는 그 이름대로 사람들이 서비스를 사용하기 위해(혹은 서비스를 알기 위해) 사람들이 들어오는 페이지이다. 어떤 방법이든지(이벤트나 마케팅 등) 사람들을 랜딩페이지로 이끌면 랜딩페이지는 사람들이 서비스를 이용(회원에 가입하거나 다운로드를 하거나 메일링에 가입하거나)하도록 만드는 것이다. 크게 보면 랜딩페이지는 사람들을 꾀는 페이지라고 할 수 있다. 앞에 과도하다는 지적은 간결하고 매력적으로 서비스의 핵심을 전달하는 대신에 사용자에게 너무 큰 노력을 요구한다는 지적이라는 점에서는 합당하다.

하지만 우리가 의도한 것은 다르다. 랜딩페이지는 사람을 꾀는 페이지라고 했지만 일단 사람들이 사이트에 오게 하여야 하고 오면 집중하게 하여야 한다. 핵심 기능을 잘 설명해 놓거나 아주 매력적인 30초짜리 소개 동영상을 띄워놓을 수도 있다. 이는 이론상으로 랜딩페이지의 기본을 잘 따르고 있지만, 서비스 대부분이 다 이렇게 하고 있고 나온 지 얼마 되지도 않은 서비스에 사람들이 일정 수준 이상의 관심을 가진다고 기대하기도 어려웠다.(일단 그전에 별로 방문도 하지 않을 것이다.) 랜딩페이지에 적용한 약간은 과도한 Parallax Scroll 효과는 다분히 의도한 것이었다. 서비스의 초기 버전이라 설명할 서비스의 엣지도 그렇게 많지 않은 상황에서 랜딩페이지 자체로 관심을 끌고 이를 통해 사람들이 WanderWorld를 더 기억하고 다른 사이트보다 관심을 가지고 랜딩페이지를 돌아보게 하는 게 목적이었다. 결과적으로는 이슈도 기대 이상으로 모았고 이를 통해 방문자와 다운로드 유도도 했기 때문에 단기로 봤을 때는 성공적이었다고 생각하고 피드백도 서비스를 이해하기 매우 좋았다는 얘기와 스크롤이 너무 많아서 핵심을 이해하기 어렵다는 얘기가 둘 다 있는 걸로 보아 취향 차이라고 본다.

랜딩페이지의 기획

결과적으로는 앱보다 랜딩페이지가 먼저 릴리즈 했지만, 원래는 동시에 릴리즈할 생각이었고 우리는 그때도 이미 많은 업무부하가 걸려있는 상태였다. 현재 상황에서는 서비스가 앱을 중심으로 하고 있으므로 랜딩페이지에 큰 비중을 두지 않으려고 했고 디자이너도 앱 디자인으로 많은 업무부하가 있었으므로 처음에 내 방향은 랜딩페이지는 평이해도 좋으니까 "간단하게 가자!"였다.(사실 좀더 괜찮은 랜딩페이지를 만들고는 싶었지만, 그때 상황에서 좀 무리가 있다는 판단이었다.) 하지만 디자이너와 그로스 해커와 셋이서 랜딩페이지에 대한 구체적인 얘기를 하다가 랜딩페이지를 좀 더 매력적으로 만들어야 한다는 얘기가 나왔고 이는 Parallax Scroll까지 이어졌다.

처음에 난 약간 반대입장이었다. 평소에 난 절제된 애니메이션을 더 좋아하기도 했고 랜딩페이지로 어떤 이슈화를 만들 필요는 있다고 봤지만, 작년도 아니고 올해에 Parallax Scroll로 이슈화하기에는 좀 늦었다고 생각했다. 이에 대해 논의를 하다가 아직은 Parallax Scroll에 사람들이 흥미를 느낄 거라는 설득에 넘어갔고 생각해 보면 국내에서는 괜찮은 Parallax Scroll 사이트를 본 기억이 별로 없기도 했기에 Parallax Scroll로 랜딩페이지를 만들기로 했다.

개발 과정


1차 목업

Parallax Scroll 사이트는 한 번도 만들어 본 적이 없었다. 대충 스크롤을 기반으로 애니메이션을 한다는 것 정도만 알고 있었지 구체적으로 어떻게 만드는지를 파악해 본 적이 없었다. 그래서 기획과 디자인이 나오기 전에 어떻게 만들지를 파악하는 것이 첫 과제였다.

꽤 잘 만든 Parallax Scroll 사이트를 보면 위 3개 사이트 정도가 있다. EveryLastDrop과 Nasa Prospect는 상당히 잘 만든 사이트이고 Carousel은 적당한 애니메이션을 잘 섞어서 만들었다. 검색해보면 Parallax Scroll을 쓴 추천 사이트들이 많이 나오지만 (자세히 보면)뜻밖에 제대로 구현한 게 많지 않고 모바일에서는 그냥 정적인 화면으로 대체해버리거나 동작 안 하는 경우도 많다. Parallax Scroll 용 라이브러리로는 대표적으로 Stellar.js, Jarallax, skrollr가 있는데 EveryLastDrop은 skrollr를 썼고 Nasa Prospect는 Stellar를 쓴 것으로 보이고 Carosel은 자체 구현한 것으로 보인다.

처음에는 Parallax용 라이브러리를 쓸까 했는데(잘 쓰면 개발 시간을 많이 줄일 수 있으므로) 어느 라이브러리가 좋은지 판단하기가 어려웠고 시간이나 상황을 봤을 때 특정 라이브러리를 테스트해보고 교체까지 할 시간이 없어 보였다. Parallax Scroll 사이트를 만드는 것이므로 라이브러리를 바꾸면 거의 다시 만들어야 할텐데 어떤 라이브러리에 버그나 한계가 존재하는지 알 수 없었기 때문에 라이브러리를 사용하기가 망설여졌다.(그렇게 좋아 보이지도 않았다.) 대신 Dave Gamache이 쓴 Parallax Done Right의 예제소스를 분석해서 Parallax Scroll을 어떻게 구현하는지 파악해 보기로 했다. Dave가 Parallax 구현에 대한 설명도 잘해놓고 예제도 라이브러리 수준으로 잘 구현해 놨기 때문에 원래는 동작원리를 이해하려고 소스를 보기 시작했는데 소스 파악이 약간 되자 이 예제를 개선해서 직접 개발하기로 했다. 라이브러리를 사용하는 것보다 문제를 생겼을 때 수정해서 구현하기도 쉬울 것 같았다.

이렇게 테스트 삼아 최초로 예제 사이트를 만들었다. 일단 하기로 했고 기획과 디자인에서 모두 의욕을 보여주었기 때문에 제대로 구현하는 게 내 책임이었고 처음 예제를 만들 때는 내가 Parallax Scroll을 구현할 수 있는지 구현하면 어떻게 해야 하는지 파악하는 데 주력하고 있었다. 그래서 기획안을 이미지로 잘라내서 요소를 배치한 뒤에 Parallax Scroll을 구현해 봤다. 이렇게 구현하면서 Parallax Done Right의 예제소스의 동작원리를 대충 파악하고 씬(Scene)을 전환하거나 할 때 어떤 부분이 가능하고 어떤 부분이 잘 안되는지를 파악했다. 그래야 가능한 방법을 다시 찾아보거나 디자이너한테 가능한 부분과 안되는 부분에 대해서 피드백을 할 수 있어서... 일단 예시를 하나 만들어 보니까 해볼 만 하겠다는 생각이 들었다.

이때가 오픈 시점에서 3주 정도 전이었다.(이때는 3주 뒤에 공개할 일정으로 움직이고 있지는 않았지만...)

2차 목업

1주일 정도 지나자 디자인이 나오기 시작했다. 전체 씬 중에 2/3정도가 나왔고 이를 바탕으로 실제 구현에 들어갔다.

확실히 디자인이 나오니까 앞의 작업보다는 난이도가 훨씬 높았고 고려할 부분도 많았다.

Dave의 예제는 기본적으로 아래의 원리로 동작한다.

  1. 각 씬을 하나의 div로 만들고 해당 요소는 모두 div 안에 둔다.
  2. JavaScript에서 keyframes라는 배열을 만들어서 여기서 사용하는 div와 스크롤의 크기, 애니메이션 할 요소와 효과를 지정한다.
  3. 스크롤이 일어날 때 해당 스크롤 영역에 들어가면 사용하는 div를 display:block으로 바꾸고 각 요소를 스크롤에 따라서 애니메이션 한다.
var keyframes = [
  {
    'wrapper': '#scene1',
    'duration': '100%',
    'animations':  [
      {
        'selector': '#logo',
        'translateY': ['0%', '-30%']
      }, {
        'selector': '#headline',
        'translateY': ['0%', '-80%']
      }, {
        'selector': '#intro-bird2',
        'opcity': [0, 1]
      }
    ]
  },
  { 
    'wrapper': '#scene2',
    'duration': '130%',
    'animations':  []
  }
];

keyframes는 위와 같은 객체의 배열이 된다. wrapper가 위에서 말한 div의 셀렉터이고 duration이 스크롤의 높이이다. 퍼센티지로 지정하면 뷰포트의 높이를 기반으로 스크롤 위치를 계산해서 스크롤 사이즈로 변환한다. animations도 배열인데 한번에 여러 요소를 움직일 수 있으므로 배열로 준다. 셀렉터로 찾아서 css 트랜지션을 반영하므로 다른 div에 있는 요소라도 셀렉터로 조회된다면 애니메이션 효과는 같이 적용된다.(그래서 난 편의상 id를 사용했다.) 애니메이션은 repaint를 최대한 줄이기 위해서 translateX, translateY, scale, opacity만을 사용하는데 만들어 본 결과 이 4가지만 있으면 사실 모든 걸 다 할 수 있다.

Dave가 작성한 예제가 그런 것이긴 하지만 값은 퍼센티지로 주거나 pixel 값으로 줄 수 있는데 특별한 이유가 아니라면 같은 타입을 써야 한다. 퍼센티지를 쓰더라도 결국 값을 뷰포트에 기반을 둬서 픽셀값으로 변환을 하므로 30% 우측으로 이동한 다음에 100px 우측으로 이동 같은 식으로 주기는 어렵다.(물론 라이브러리를 수정하면 불가능하지는 않을 것이다.) 그리고 같은 요소를 사용할 때는 이전 값을 계속 유지해야 한다. CSS로 위치를 잡은 기본위치를 바탕으로 움직이므로 두 번에 나누어서 움직인다고 하면 'translateY': ['0%', '-30%'], 'translateY': ['-30%', '-60%'] 이런 식으로 이전의 할당한 값을 다음의 초깃값으로 지정해야 한다. 그렇지 않으면 다시 0부터 시작하게 된다. 아주 고급 기능을 사용하는 것은 아니라서 모던 브라우저 대부분에서는 큰 문제 없이 동작했다.

뷰포트에 각 요소를 배치한 화면

각 씬마다 화면에서 요소는 위처럼 배치되어 있다. 거의 모든 요소는 position: fixed;로 고정된 위치에 배치하는데 애니메이션이나 원하는 전환 효과에 따라 일부 요소는 뷰포트 내에 두고 opacity0으로 두고 화면 바깥에서 등장하는 요소들은 top, bottom, left, right0으로 두고 margin으로 위치를 이동시켜서 뷰포트에 경계선에 둔 뒤에 위의 자바스크립트로 이동을 시킨다.

작업하다가 느낀 몇 가지 소소한 팁은

  1. 완성된 하나의 화면은 CSS로 배치해서 각 위치를 맞춘 다음에 디폴트 위치를 바꾸고 자바스크립트로 해당 위치만큼 이동하게 하면 좀 편한 것 같다.
  2. 그룹화해서 함께 움직이는 부분은 하나로 묶어서 그 내부에서 위치를 잡으면 이동시킬 때 일일이 조정해야 할 필요가 적어진다.
  3. Parallax Scroll을 구현하면 사람들이 스크롤을 거꾸로도 진행하므로 스크롤을 반대로 했을 때도 제대로 동작하는지 확인해야 한다.
  4. 가능하다면(현실적으로는 좀 힘들어 보인다.) 마지막 씬부터 하는 게 편하지 않을까 하는 생각한다. 뒤로 갈수록 작은 수정에도 스크롤을 계속 해봐야 해서 생산성이 무척 떨어진다.

실제 디자인을 가지고 작업을 5-6씬 정도를 만들어보니까 어떻게 만들면 작업이 편하고 어떻게 하면 불편한지 감이 오기 시작했다.

성능 개선

당시 걱정되던 것은 성능문제였다.(이때 크로스 브라우징 테스트도 전혀 못 했지만...) 주말 후에 최종 디자인이 나올 예정이었으므로 그 외 다른 이슈는 모두 처리해 놓고 싶었다. 보통 웹에서 이런 애니메이션을 작업하면 나오는 것이 60fps 얘기다. 애니메이션 작업을 60fps에 맞추면 성능을 최대한 발휘할 수 있는데 막상 작업하려니 좀 어려웠다. 실제 이런 작업을 해본 적이 없어서 프로파일링을 해봐도 어디부터 수정해야 하는지 잘 모르기도 했지만, 애니메이션이 스크롤에 따라 발생하기 때문에 스크롤을 어느 속도로 하냐에 따라 애니메이션의 성능도 달라져서 튜닝을 하기가 어려웠다. 정해진 속도가 있는 게 아니다 보니 스크롤을 살살하면 60fps 근처가 나오기도 하지만 스크롤을 빨리하면 10fps도 안 나오는 경우도 허다했다.

고민하다가 간단한 스크립트로 지연을 주면서 일정 위치까지 스크롤을 이동하는 코드를 작성했다. 이 코드가 성능에 영향을 줄 수도 있겠지만 같은 조건을 만들어서 개선을 하면 어느 정도는 성능개선을 할 수 있을 거라고 생각했다. 기본적으로 translateX, translateY, scale, opacity가 repaint를 발생시키지는 않지만, 최초 등장 시에는 repaint가 발생하긴 한다. 예를 들어 opcity: 0;에서 처음 보이기 시작할 때는 한 번씩 repaint가 발생한다. 그래서 스크롤을 내리면서 프로파일링을 돌려보니 가장 큰 병목이 씬을 전환하는 순간에 발생했다.

선능개선 전/후의 프로파일링

앞에서 설명한 대로 각 씬이 <div>로 묶이고 자바스크립트에서 차례대로 감추거나 보이게 하거나 하므로 씬이 바뀌는 순간 그 안에 있는 모든 요소들도(보이지 않는 요소더라도) 한꺼번에 paint를 하므로 여기서 이 처리에 대한 비용이 크게 든다. 각 요소를 움직일 때는 한꺼번에 다 움직이는 것이 아니라서 큰 비용이 들지 않지만 씬 전환 시에 paint 처리 비용이 많이 들어서 씬을 없애 버렸다. 어차피 코드는 각 DOM을 잡아서 움직여 주는 것이기 때문에 굳이 <div>로 분리하지 않아도 큰 문제는 없을 거라고 생각했다. 대신 초기 로딩 시에 비용이 더 많이 들겠지만, 특성상 리소스도 많고 로딩 시간도 많이 걸려서 로딩 페이지를 따로 만들 예정이었으므로 paint 부하를 앞에 모으는 것이 더 낫겠다는 판단이었다.

성능 개선을 하면서 Parallax Done Rihgt가 아무래도 예제라서 성능 최적화 되지 않은 부분이 많고 버그 같은 것도 꽤 있어서 이러한 부분을 많이 수정했다.

최종 작업

최종 디자인을 받으면서 다시 작업에 들어갔다. 원래는 랜딩페이지를 앱 오픈과 동시에 공개할 계획이었다가 마케팅 전략과 맞물려서 앱보다 랜딩페이지를 먼저 내보내기로 하면서 일정이 급해졌다. 그동안은 다른 작업을 하면서 랜딩페이지를 작업하고 있었는데 최종작업 때는 아무래도 손도 많이 가고 일정이 급해져서 일주일 정도는 온종일 랜딩페이지 개발만 했던 것 같다. 그나마 2차 목업에서 약간의 노하우가 쌓여서 작업 자체는 어렵지 않았다. 이런 작업을 해본 개발자들은 대부분 알겠지만(공개했을 때 위로의 말이.. ㅋㅋ) 뭔가 하이테크인것 처럼 보이지만 실제로는 엄청난 노가다 작업이다. 각 픽셀 위치 잡고 거기서 이동해서 위치 잡고 이러한 작업이 계속된다. ㅎㅎ 실제로 공개 이후 우리 사이트를 소개한 smooth-web에서 "매우 정교한 페이지에서 얼마나 공정이 걸려 있는지 궁금하다."라고 말하기도 했다.

반응형 웹

뷰포트내에서 요소를 배치할 기준선

애니메이션을 어떻게 하냐에 따라 다르긴 하겠지만 주로 움직이는 요소들은 위에서 빨간 점선을 기준으로 위치를 잡아서 움직이는 게 좋다. 웹은 다양한 해상도에 대응해야 하므로 반응형으로 만들었는데 이 기준으로 움직이지 않으면 위치를 맞추기가 어렵다. 각 요소의 위치는 CSS로 잡고 이동은 자바스크립트로 하므로 CSS는 미디어 쿼리를 이용해서 해상도 별로 위치를 다르게 지정하더라도 자바스크립트에서는 그렇게 할 수 없다.(불가능한 것은 아니지만, 해상도 별로 움직이는 효과를 일일이 다르게 줄다는 것은 수습 불가능한 일로 보였다.) 예를 들어 우측에서 1000px이동했다가 다시 좌로 1000px를 이동한다면 작은 모니터에서는 잘 보이겠지만 해상도가 큰 모니터에서는 움직이기 전에 자리 잡고 있는 게 미리 보일 것이다.

그래서 정확한 위치에 있지 않다고 되는 배경 같은 요소는 %로 이동을 하거나 위치를 잡게 하고 충분한 값을 줘서 화면에서 사라지게 했고 핵심 요소들은 중앙선을 기준으로 좌우로 배치해서 정확한 위치를 잡을 수 있도록 했다. 특히 WanderWorld의 랜딩페이지는 여러 가지 애니메이션을 통해 한 곳에 배치되는 게 많았기 때문에(폰이 등장하고 폰 안에 사진이 등장하거나 Johnny가 움직여서 카페 앞에 서있다거나 하는 등) 다른 위치에서 이동해 와서 정확한 지점에 위치해야 하므로 중심선을 기준으로 위치를 잡지 않으면 방법이 없었다.

처음에는 만들기만 하는 데 집중하고 있었기 때문에 반응형까지 고려할 여유는 없었다. 이후 다양한 해상도에서도 잘 보이게 하려고 미디어 쿼리를 넣기 시작했는데 시간적 여유가 있거나 다음에 다시 하게 된다면 이런 부분도 좀 더 효율적으로 작업할 수 있을 것 같다. 이번에는 미디어 쿼리가 거의 땜질식으로 바로잡는 것으로 작업했다.


모바일

원래 주말까지 작업하고 월요일에 오픈이 목표였지만 밤을 새우고도 작업을 다 하지 못했다. 페이지 작업은 거의 끝났지만 자잘하게 수정하고 하는 작업이 계속 끝나지 않아서 마무리되지 않았다. 결국, 하루 미루고 화요일에 열었지만 당시에도 결과물이 아주 만족스럽지 않았고 모바일 최적화는 많이 부족했다. 주말에 계속 모바일 쪽도 같이 보고 있었지만, 처리가 쉽지 않았다.

안드로이드 쪽 브라우저는 제대로 디버깅을 하지 못했지만,(모바일 사파리에 맞추니까 그럭저럭 돌아갔다) 모바일 사파리로 처음 확인할 때는 스크롤이 제일 문제였다. 모바일 사파리는 (이유는 모르겠지만) 스크롤을 할 때 다른 상태 값을 갱신하지 않는다. 즉, Scroll을 하는 중에는 ScrollTop등을 전혀 갱신하지 않다가 스크롤 이벤트가 완료되는 순간에 한 번에 갱신한다. Parallax Scroll에서는 스크롤에 따라 변화를 줘야 하기에 이게 큰 문제가 됐다. scroll 이벤트에 requestAnimationFrame을 연결해 놨는데 이 문제 때문에 requestAnimationFrame이 호출조차 되지 않는다.

결국은 네이티브 스크롤로는 해결방법이 없다고 생각하고 iScroll을 도입해서 소프트웨어 스크롤을 구현했다. 이 연결작업도 시간이 꽤 걸리긴 했지만, 기존보다는 훨씬 자연스럽게 스크롤을 할 수 있었다.(여전히 아주 깔끔하진 않지만) iScroll이 어설프게 붙은 상태에서 일단 열고 당시에 정신이 없었는지 <viewport>설정도 제대로 주지 않아서 모바일에서 이상하게 최적화되어 있었다. 그래서 오픈 뒤에 이러한 부분을 맞춰서 미디어 쿼리랑 모바일 최적화에 집중해서 일주일 정도 더 작업했다.

물론 데스크톱은 보통 가로가 길지만, 모바일은 세로가 더 길어서 초기부터 이런 부분을 어느 정도 고려해서 디자이너와 협의하기는 했다. 모바일에서는 이미지 사이즈나 요소 등을 다르게 가져갈 수도 있지만 그런 작업을 할 시간은 없었기에 그대로 진행했다.

스크롤

구현을 다 해보고 나니 다루기 가장 어려운 게 스크롤이고 Parallax Scroll에서는 Scroll을 기반으로 모든 게 이뤄지므로 가장 중요한 부분이기도 하다. 스크롤이 어려운 이유가 사용자마다 다른 마우스를 사용하고(트랙패드, 마우스 휠, 빨콩 등) 설정한 스크롤 감도도 다 다르다. 누구는 1000px를 스크롤 하려면 여러 번 스크롤 해야 하지만 누구는 한번에 1000px정도는 이동해 버릴 수 있다. 이 부분은 사실 완전한 해결책은 못 찾았고 다양한 환경에서 테스트도 하지 못했다. 초반에 스크롤 높이를 너무 낮게 잡아서 이 부분을 좀 충분히 준 것이 전부이다.

테스트 가능한 선에서 적절한 높이를 주고 버튼으로 단계별로 자동 스크롤 해서 이동할 수 있는 UI를 제공하는 것이 적당한 절충안으로 보인다. 특히 모바일에서는 스크롤 높이가 너무 높으면 엄청나게 불편할 수 있기 때문에 적절히 잘 맞추어야 한다. 모바일 스크롤은 특히 더 어려운데 모멘텀 스크롤까지 되면서 손가락으로 터치할 때 적절히 맞추어야 하는데 이걸 조절하는 게 좀처럼 쉽지 않았다. 사실 마지막에 모바일과 스크롤 최적화를 하면서 라이브러리를 가져다 쓰는 게 나았으려나 하는 생각을 많이 했다.(처음에는 Parallax 구현에만 정신이 팔려 있어서 모바일이나 이런 부분은 고려도 못 하고 있었다.) EveryLastDrop을 보면 모바일에서도 스크롤이 아주 자연스럽게 잘 되는데 이 부분까지는 비슷하게 구현해 내지 못하고 포기해야만 했다. 아주 불편하고 딱딱하지 않은 스크롤 정도로 만족해야 했다.

에필로그

고생은 했지만 모르는 영역을 해보는 재미도 있었고 결과도 만족스러워서 Parallax Scroll로 안 했으면 큰일 났겠다 하는 생각마저 든다. ㅎㅎ 특히 기획, 디자인 부분까지 처음부터 의논하면서 개선해 나가는 건 무척 소중하고 재미난 경험이었다. 처음 공개하고 사람들의 반응을 보면서 국내에서는 아직 Parallax Scroll로 이슈화가 가능하다는 생각도 새삼 하게 됐다.(물론 반 이상은 스토리텔링도 잘 되고 디자인도 잘 나와서이기도 하다.) 초기 목표였던 이슈화도 어느 정도 성공해서 국내뿐만 아니라 해외에서도 괜찮은 반응을 얻었다.

Awwwards에 등록된 WanderWorld

만들면서 랜딩페이지가 괜찮게 나와서 어워드 사이트에도 등록하자는 얘기가 오가서 Awwwards에 등록도 했는데 7.28이라는 꽤 괜찮은 점수를 받았고 Site of the day에는 선정되지 못했지만, Honorable Mentions에 선정되기도 했다. 어워드 사이트 등을 통해서 퍼져 나갔다고 추측하긴 하는데 포루투칼 사이트인 tek.sapo.net에도 소개되고 smooth-web, CSS Author, Web Design Inspiration등에도 소개가 돼서 목표였던 트래픽도 꽤 모으고 기분도 좋아서 만족스러운 결과였다.(좀 더 완성도를 높였다면 하는 아쉬움도 동시에 있지만...)

다 만들고 몇 가지 느낀 점은...

  • Parallax Scroll은 마케팅적은 이슈화 혹은 디자인적 요소 외에는 달리 쓸데는 없다는 생각이 들었다.
  • 생각보다 많은 사람이 웹페이지에서 스크롤을 하는 게 기본 행위가 아니다. 그래서 스크롤을 하면 뭔가 나온다는 것을 명시적으로 알려줘야 한다.(보통 스크롤을 내려보지 않나???) 디자인적으로 좀 내려볼 수 있게 했다고 생각했음에도 충분하지 않아서 누군가에게는 완료된 페이지처럼 보였던 것 같다. 대부분의 Parallax 페이지에 매번 Scroll Down이라는 안내가 나오는 이유가 있다.
  • 화살표 버튼 등으로 클릭하면 다음 씬까지 이동하는 버튼 혹은 단계별로 이동해 볼 수 있는 네비게이션은 Parallax가 해칠 수도 있는 사용성을 개선해 주는 좋은 요소라고 생각한다. 사실 이는 원래 추가할 계획이었지만 일정상 추가하지 못했다.
  • 아무래도 이미지가 많다 보니 CSS sprite를 이용하면 사이트 성능을 많이 높일 수 있을 것 같다.(시간이 없어서 이건 못 했다. CSS도 상당히 조절해야 했기에 ㅠㅠ) 사이트 로딩 시 이미지는 미리 로딩하는 건 필수적으로 필요하다고 본다.
2014/08/29 22:19 2014/08/29 22:19

관련 글