Blog

정적 웹사이트 생성기의 유혹

January 5, 2014

정적 웹사이트 생성기의 유혹

개인적으로 요새 화두인 주제가 바로 정적 웹사이트 생성기입니다. 21세기에 정적 웹사이트라니 꽤나 뜬금없는 이야기로 들리실지 모르겠지만 여기에 대해서는 약간 배경에 대해서 이해할 필요가 있습니다.

분명히 정적이라는 단어는 그 동안에 웹 어플리케이션이 발전해 온 데 있어서 정반대의 위치에 있는 단어입니다. 정적인 페이지란 말그대로 이미 완성된 HTML이고, 클라이언트의 요청을 받는 서버의 역할은 단순히 이렇게 완성되어 있는 HTML을 보내주는 역할을 할 뿐입니다. 이러한 모델은 우편부를 통해서 비유하기에 아주 적절합니다. 그렇다면 웹이 동적으로 발전해왔다는 건 어떤 걸 의미할까요? 여기서 동적이란 화려한 시각적 효과나 움직임을 지칭하는 단어가 아닙니다. 좀 더 정확히 말하자면 HTML 페이지를 클라이언트의 요청에 따라서 실시간으로 생성해서 보내준다는 의미를 가지고 있습니다. 그래서 이러한 웹 어플리케이션을 배울 때 가장 먼저 나오는 가장 간단한 예는 항상 이름을 받고서 이름을 출력해주는 예제입니다. 즉 서버는 완성된 HTML을 가지고 있지 않습니다. 거의 완성되어있거나, 심지어는 아무것도 없이도 요청에 따라 실시간으로 완성된 문서를 다시 보내줍니다. 즉, 여기서 서버란 웹서버 어플리케이션과 웹 어플리케이션을 함께 이야기합니다.

하지만 본질적인 부분을 다시 생각해볼 필요가 있습니다. 정말로 동적인 웹페이지란 필요한 걸까요? 단언컨데, 네 필요합니다. 질문을 바꿀 필요가 있습니다. 모든 경우에 정말로 동적인 웹페이지가 필요한 걸까요? 여기에 모든 경우에라는 수사를 통해서 저는 이도 저도 아닌 회색 영역을 만들었습니다. 네, 물론 아닙니다. 웹페이지 상에 동적으로 변해야하는 부분이 단 하나도 없다면, 완성된 HTML 형식으로 사이트를 공개해도 아무런 문제가 없습니다. 단지 우리는 21.1세기에 더 이상 그런 원시적인 웹 사이트는 거의 없다고 믿고 있을 뿐이죠.

사실 정적이라는 건 나쁜 것이 아닙니다. 오히려 동적 방식이야 말로 실시간으로 사이트를 생성하는 데서 오는 굉장히 큰 비용을 감당해야합니다. 바로 이런 이유 때문에 어떤 프레임워크를 사용할 것인가, 어떤 언어를 사용할 것인가 하는 게 굉장히 중요한 문제입니다. 제가 사랑해마지 않는 루비조차도 바로 이런 이유(즉 상대적으로 느리기 때문에!)로 언젠가 서비스가 커지면 갈아치워야할 프로토타입용이라고 생각되는 경우가 굉장히 많습니다. 물론 대부분의 서비스는 그 단계까지도 가지도 못 하고 프로토타입만 서비스하다 망합니다만….

뭐, 그렇습니다.

단순히 서버 수준의 스케일링까지 고려를 하지 않더라도 동적으로 웹페이지를 생성하는 일은 굉장히 느립니다. 이는 만들어져있는 즉석식품과와 주문 받으면 음식을 조리하는 방식의 차이입니다. 정적이 전자라면, 동적은 후자입니다. 당연히 느립니다. 그 차이가 비록 와닿지 않을 정도라고 하더라도 분명히 느리며, 또한 이러한 차이를 극복하기 위해 실제 웹서비스들에서는 캐시를 사용해 마치 자신이 정적 웹 페이지인 것 마냥 작동합니다. 캐시가 가능한 이유는 웹 어플리케이션의 많은 부분이 사실은 정적이기 때문입니다. 즉, 요청마다 다르게 보여주는 부분은 실제로는 그렇게 많지 않다는 이야기입니다.

정적인 자원은 다른 처리 비용을 발생시키지 않기 때문에 동적인 자원에 비해서 훨씬 더 빠릅니다. 그저 이미 만들어져있는 것을 보내주면 그만입니다. 앞에서 이야기했듯이 서버는 그저 우편부 역할을 할 뿐입니다. 여기서 오는 또 하나의 장점은 이렇게 미리 HTML 문서를 만들 경우 배포가 매우 쉽다는 점입니다. 어느 웹서버든 HTML은 serve할 수 있습니다. 복잡하게 어떤 언어를 쓰면 이렇게 하고 어떤 프레임워크를 써면 저렇게 하고 프록시 서버 써서 도메인 돌리고 그런 걸 고민할 필요가 없습니다. 싸구려 호스팅에 올려도 되고, 남는 서버에 올려도 되고, 아마존 S3에 올려도 되고, Github Pages로 배포할 수도 있습니다. 어플리케이션이 아니니 SQL injection 같은 보안 이슈도 없고요. 오오… 은근히 좋아보이네요.

하지만!

네, 이제, 웹 프레임워크는 다 버리고 HTML 하드 코딩하시면 되겠습니다.

바로 여기입니다. 당연히 HTML을 직접 작성해야하는 정적 방식이 좋다고는 결코 말할 수 없습니다. 즉 2 * 10 + 1 * 1 + 1 * 0.1 세기에 다시 주목받는 정적 웹사이트란, 단순히 HTML을 Serve 해준다는 의미에서의 웹사이트를 말하는 것이 아니라 거기서 한 층 더 나아가 웹사이트를 동적으로 생성하되, 정적으로 Serve 한다는 의미에서 정적 웹사이트 생성기가 되는 것입니다. 이는 프로그래밍에 있어서 컴파일의 사전적인 의미에 좀 더 가까운 작업입니다. 실제로 미리 모든 것을 만들어둔다는 점에서는 프로그래밍의 컴파일 개념과도 비슷합니다.

예를 들어보죠. 이러한 방식을 적용할 수 있는 정말 좋은 플랫폼이 블로그입니다. 블로그는 시작부터 HTML 문서들을 좀 더 쉽게 배포하기 위한 동적인 플랫폼으로 출발했거나, 그런 목적으로 개발되었습니다. 하지만 문서 기반의 모든 플랫폼은 본질적으로 내가 가진 문서를 얼마나 잘 보여줄 것인가 하는 문제가 가장 중요한 문제입니다. 그런데 여기서 문서정적입니다. 그러나 문서를 지원하는 다양한 페이지들은 동적입니다. 이런 페이지에는 페이징, 카테고리, 태그, 날짜 기반 페이지, Feed가 있습니다. 그런데 여기서 동적이라는 b말의 시점을 잘 따져볼 필요가 있습니다. 웹페이지가 동적으로 생성된다는 의미는 웹페이지가 request되는 시점에서 동적으로 response를 생성한다는 의미입니다. 그런데 페이징, 카테고리, 태그, 날짜 기반 페이지, Feed와 같은 블로그의 핵심 기능들은 request를 요청하는 시점이 아니라, 블로그 운영자가 포스트를 올리는 시점에 동적입니다. 즉, 이 시점을 제외하고는 항상 아무것도 변하지 않습니다. 같은 동적이라고 말해도 실제로는 시점이 페이지가 완결되는 시점이 다르다는 점입니다. 물론 글을 쓴 시점에 response가 완성된다는 의미는 아닙니다. 대부분의 웹 어플리케이션은 lazy하기 때문에 처음 request가 들어오는 시점에 해당 페이지를 적절히 생성하고 캐시합니다. 중요한 건 실제로는 포스트를 올린 시점에 블로그의 모든 페이지가 정적으로 완결될 수 있다는 점입니다. 즉 블로그의 모든 페이지를 미리 생성할 수 있습니다. 이미 이러한 방식을 지원하는 툴들이 이미 존재합니다. Jekyll을 기반으로하는 Octopress를 사용한다면 바로 글을 쓰는 시점에 블로그에 포함되는 모든 페이지를 정적 페이지, 바꿔말해 HTML 파일로 만들어 줍니다.

단, 여기에는 약간의 함정이 있습니다. 블로그에도 정말 적은 부분이지만 사용자의 요청이 발생하는 시점에서 실시간으로 동적으로 생성하고 반응해야하는 부분이 있습니다. 바로 댓글입니다. 이 부분은 따로 고민하지 않습니다. 그냥 댓글이 들어갈 부분에 Disqus를 삽입합니다.

이렇듯 의외로 블로그는 정적인 웹 플랫폼입니다. 근데 더 큰 함정이 있군요. 이렇게 만들면 블로그에 글은 어떻게 쓸까요? 다르게 말하면 블로그에서 가장 동적인 부분은 글을 작성하는 부분입니다. 이런 부분은 정적 블로그 생성기에서는 존재하지 않습니다. 여기서 모든 포스트는 그저 마크다운 파일일 뿐입니다. 또한 글이 작성된 시점이나 사이트에 기능이나 페이지가 더해진 시점을 일반적으로 Git 저장소에 push가 일어난 시점으로 판단합니다. 이런 부분은 일반인들이 이런 툴을 사용하기에 매우 프로그래머스럽습니다. 하지만 프로그래머들에게 이런 점은 다른 방향에서 자유를 선사합니다. 바로 블로그 글을 자신이 원하는 에디터로 작성 할 수 있다는 점입니다. 저는 지금 이 글을 제가 애용하는 에디터인 Emacs 위에서 작성하고 있습니다. 예전부터 블로그나 위키를 운영하면서 에디터 통합을 꿈꾸던 입장에서는 지금은 너무 쉽게 이런 접근이 가능합니다. 물론 또다른 방향에서 웹 편집기들은 발전하고 있습니다. Summernote와 같은 부트스트랩 기반의 에디터도 있고 Ghost와 같은 마크다운 프리뷰를 바로 보여주는 훌륭한 플랫폼도 있습니다. Mediawiki에는 웹문서에서 바로 편집을 하는 것 같은 경험을 제공하는 Visual Editor 같은 확장도 있습니다.[^1] 많은 훌륭한 시도들이 있습니다만 여전히 웹에서 글을 작성한다는 것은 전용 에디터에 비해서 매우 불만족스러운 일입니다. 반면에 마크다운 파일을 기반으로 하고 있다면 그저 텍스트 문서를 원하는 에디터에서 작성하면 그만입니다.

[^1]: http://www.mediawiki.org/wiki/VisualEditor 에서 직접 edit를 해보시기 바랍니다.

아시는 분은 아시겠지만! 이미 Github을 적극 활용하는 많은 분들은 Github Pages와 Github에서 지원하는 루비 기반의 정적 웹페이지 생성기(이자 Github CEO가 만든)인 Jekyll을 적극 활용해서 블로그나 사이트를 운영하고 있습니다. 단순히 블로그에서만 사용할 수 있는 건 아닙니다. 이미 괜찮은 블로그 솔루션들이 마련되어 있기에 편하게 사용할 수 있는 것 뿐이지, 결과적으로 정적인 사이트라면 얼마든지 생성할 수 있습니다. 루비 커뮤니티에서 두 번째로 유명한 Middleman으로 생성한 사례들도 매우 많습니다. 이 사이트도 Middleman으로 만들어졌고, 글을 작성하면 Travis를 통해 빌드하고, 다시 변경된 내용을 Github Repository에 반영해 Github Pages로 배포되고 있습니다. 이러한 활용 방법에 대해서는 다른 포스트에서 좀 더 자세히 다루겠습니다. 이 외에도 Static Site GeneratorModern Static에서는 다양한 정적 웹페이지 생성기들을 소개하고 있습니다.

당연하게도 이런 정적 페이지 생성기들은 정적 페이지를 통한 배포의 이점을 전부 그대로 누립니다. 그냥 HTML 문서니까요. 동시에 빌드 시점에서는 프로그래밍 언어의 강력함도 누릴 수 있습니다.

결국에 중요한 문제는 어느 시점에서 동적이면 되는가의 문제로 귀결됩니다. 블로그가 정적 웹페이지로도 만들어질 수도 있는 건 모든 시점에 동적일 필요가 없었기 때문입니다. 반면에 소셜 사이트를 정적 웹페이지로 만드는 건 거의 불가능하다고 봐도 되겠죠. 네, 케바케입니다. 하지만 분명한 건 정적 웹페이지로 만들 수 있는 페이지를 동적 어플리케이션으로 서버에 물려놓는 건 사이트 구축은 그렇다고 쳐도, 운영 면에서 불리합니다. 정적 웹페이지 생성기는 중간쯤 어딘가에서 어떤 공백을 메워줍니다.

네, 모든 종류의 웹사이트가 정적일 수는 없습니다. 거꾸로 모든 종류의 웹사이트가 동적일 필요도 없는 거고, 적절한 타협점이 필요한 거죠.