1990년 월드와이드웹이 발표된 이래로 웹은 현재까지 많은 발전을 거듭해 왔다. 정보를 제공하는 사람은 더 많은 정보를 효율적으로 전달하고 싶어 했고 이용자의 요구사항도 높아져만 갔다. 이에 부응하기 위해 수많은 라이브러리, 프레임워크, 개발 패턴들이 탄생하였고 현재의 거대하고 다양한 웹 개발 문화가 만들어졌다. 그중 이번 포스팅에서는 AJAX 등장 이후의 개발 패턴의 변화라는 주제에 대해 기록하려고 한다.
웹의 역사에 큰 획을 그을만한 중요한 사건이 몇 가지가 있는데 그중 하나가 AJAX의 등장이다. AJAX(Asynchronous Javascript And XML)은 브라우저의 JS엔진과 웹서버가 XML(또는 JSON)을 매개로 하여 비동기적으로 통신할 수 있는 기술이다.
요즘의 웹서비스는 많은 기능을 포함하고 있기 때문에 단순하게 정보를 표현해 주는 “웹 페이지” 보다 하나의 독립적인 프로그램인 "웹 애플리케이션"이라는 용어가 더 어울린다. 유연한 인터페이스를 통해 사용자와 상호작용하며 사용자가 원하는 정보를 효과적으로 표현해 주고있기 때문이다.
사용자가 원하는 데이터들은 데이터베이스에 의해서 관리되고 브라우저는 데이터베이스와 직접 통신할 수 없기 때문에 현재 서버에 새로운 요청을 하면 서버는 그 요청에 맞는 데이터를 데이터베이스에서 검색한 후 적절한 페이지를 생성하기 위해 HTML을 만드는 작업(랜더링)을 진행하게 된다. 이렇게 랜더링 된 새로운 페이지를 브라우저는 응답받고 현재 사용자가 보던 페이지를 새롭게 응답받은 페이지로 교체하게 된다.
이러한 형태의 통신이 AJAX가 탄생하기 이전에 사용자에게 새로운 정보를 표현하기 위한 작업의 일반적인 흐름이었다. “새로운 정보” = “새로운 페이지”의 공식이었기 때문에 90%가 이전 페이지와 똑같고 1%만 달라도 서버는 무조건 100%를 다시 그려야 하는 비효율적인 작업을 반복해야 했다. 서버에서 모든 페이지를 직접 그려서 HTML파일로 응답하기 때문에 이러한 방식을 SSR(Server Side Rendering)이라고 한다.
AJAX 기반의 통신방식은 요청할 때 새로운 HTML를 응답받는 것이 아닌 페이지의 일부 또는 데이터만 응답받을 수 있고 현재 사용자에게 보이는 페이지가 사라지지 않는다. 전체 페이지를 새로운 페이지로 교체하는 것이 아니라 그대로 유지하면서 변경되어야 할 부분만 서버로부터 받은 페이지의 일부분으로 교체하거나 서버로부터 받은 데이터를 가지고 브라우저에서 직접 HTML을 생성한 뒤 교체하게 된다.
이러한 방식의 장점을 요약하면 다음과 같다.
물론 장점 이외에도 복잡한 DOM 조작, 브라우저 지원등의 문제도 존재한다.
AJAX 기반의 통신방식은 웹 개발 진영에 많은 변화를 가져왔다. 웹 개발방식은 기업마다 다를 수 있고 개발자마다 다를 수 있다. AJAX를 프로젝트에 적극적으로 도입하는 개발자들도 있었고 아이디 중복확인, 검색어 추천 등 현재 페이지를 유지하면서 서버에서 데이터를 받아와야하는 필수적인 부분에만 사용하기도 했다. 앞서 말한 적극적으로 AJAX를 도입하던 개발자 그리고 팀들은 더 쉽고 빠르게 AJAX 방식으로 웹앱을 제작하길 원했고 오픈소스 라이브러리들과 프레임워크들이 하나 둘 등장하기 시작했다. AngularJS, BackboneJS, EmberJS 등의 프레임워크들이 인기를 끌기 시작했고 시간이 더 지나면서 뷰레이어에만 집중하며 비교적 가벼우면서도 학습곡선이 낮은 ReactJS, VueJS등의 라이브러리들의 인기가 점차 높아지고 있다.
이러한 프레임워크 또는 라이브러리를 이용하여 만들어진 웹앱은 일반적으로 다음과 같은 구조를 띠게 된다. 처음 페이지를 로딩할 때 서버는 내용이 없고 페이지의 구조(뼈대)에 해당하는 HTML을 응답해 준다. 당연히 컨텐츠에 해당하는 부분이 없기 때문에 사용자에게는 의미 없는 페이지이다. 하지만 해당 페이지에는 JS 링크가 들어있고 해당 JS 코드가 실행되면서 내용이 렌더링 된다. 만약 표시해야 할 내용이 데이터베이스에 보관되어있다면 AJAX요청에 의해 서버로부터 데이터를 받아온 후 내용을 화면에 랜더링 한다. 이벤트에 의해서 화면이 내용이 변경이 되어야 하는데 이 때 사용될 데이터를 서버에서 받아와야 한다면 다시 AJAX요청을 하게되고 서버로부터 데이터를 받아온 후 내용을 화면에 다시 랜더링 한다.
위 내용만으로는 CSR이 효율적인 랜더링 방식이라고 생각이 들수 있지만 단점이 없는게 아니다. 일단 최초 로딩속도가 느리다. 처음 요청 시 웹앱에 필요한 대부분의 JS파일 CSS파일들을 서버로부터 응답받아야 하며 이를 화면에 표시하기 위해서 브라우저가 열심히 작업을 수행해야 하기 때문이다. 뿐만아니라 웹앱의 규모가 크고 사용자PC의 사양이 높지 못하다면 기존 방식인 서버에서 직접 페이지를 렌더링하는 SSR 방식이 오히려 빠를 수도 있다. 물론 요즘 PC 사양이 상향 평준화 되었고 브라우저의 성능도 획기적으로 발전되고 있지만, 서비스의 성격과 대상에 따라서 단점이 부각될 수도 있다.
두번째는 검색엔진 노출이 제한되서 검색엔진 최적화(SEO)에 불리하다. CSR은 초기 요청에는 뼈대에 해당하는 페이지밖에 응답이 안 되고 JS가 동작 하면서 내용이 채워지는 방식인데 구글 검색엔진을 제외한 검색엔진은 페이지에 포함된 자바스크립트를 실행하여 완성된 결과화면을 인덱싱하지 않는다. 기술적인 측면도 있겠지만 하루에도 수 많은 웹사이트들이 생겨나고 업데이트 되기 때문에 경제적인 측면을 고려한것 같기도 하다. 따라서 CSR 방식은 구글을 제외한 나머지 검색엔진에 노출되기 어렵다고 볼 수 있다. 이는 마케팅을 목적으로 하는 서비스이거나 각 게시물이 포털사이트에 노출되어야 하는 서비스일 경우에는 큰 문제이다.
기존 방식인 SSR을 따르자니 CSR의 장점이 너무 매력적이고 CSR을 따르자니 앞서 말한 두 개의 단점이 크게 작용하는 서비스라면 웹 개발자는 고민에 빠질 수 밖에 없을 것이다. 두 가지의 선택지가 장단점이 명확하다면 두 가지 선택지의 장점을 합한 제 3의 선택지를 만드는 게 최선의 선택지라고 생각한다. 즉, 초기 요청 시에만 서버에서 완성된 페이지를 응답해 주고 나머지는 CSR 방식을 따라가면 된다. 이렇게 되면 CSR 방식의 단점을 완벽히는 아니지만 어느 정도 해결할 수 있다. 성능이 좋은 서버가 첫 페이지를 빠르게 그려주면 사용자는 초기 화면을 빨리 볼 수 있어서 좋고 검색엔진도 인덱싱이 가능하다. 다행히도 Angular, Ember.js같은 프레임워크와 ReactJS, VueJS같은 라이브러리들은 SSR을 지원하고 있다. 더군다나 React 진영에는 Next.js, Vue진영에는 Nuxt.js라는 SSR기능이 내장되어있는 프레임웍이 있어 어렵지 않게 CSR과 SSR의 이점을 동시에 이용할 수 있다. (추후에 Next.js에 다뤄보자!)
잘보고 갑니다!!!