여러분들은 웹 유저로서 아주 다양한 페이지를 방문한 경험이 있으실 것입니다. 여러 페이지를 살펴볼 때 마치 하나의 앱처럼 부드럽게 움직이는 페이지를 본 적이 있으신가요? 없으시다면 토스 뱅크의 사이트를 한번 접속해 보세요. 아주 부드러운 웹페이지를 경험할 수 있습니다. 이것은 토스 뱅크가 기능별로 구분되어 있는 페이지들을 하나의 html 파일에서 컨트롤하기 때문입니다. 이러한 최근의 웹페이지 제작 방식을 Single Page Application(이하 SPA)이라고 부릅니다. 이러한 웹페이지들은 본질적으로 SEO(검색엔진최적화)를 진행하기에 어려운 부분이 있음에도 많은 웹페이지가 SPA로 제작되고 있습니다. 지금부터 SPA가 정확히 무엇인지 알아보고 SPA에서 SEO를 진행하기 위해서는 어떤 부분을 신경 써야 하는지 알아보겠습니다.
[목차]
SPA란 무엇인가?
SPA의 장단점
SPA에서 SEO가 어려운 이유
SPA SEO 방법
SPA는 앞서 말씀드린 대로 하나의 html 파일에서 구동 되는 웹 앱 형태의 페이지를 의미합니다. 기존의 웹페이지들은 복수의 html 페이지를 사용자의 요청에 따라 계속 전송하여 사용자와 통신했습니다. 과거에는 html에 담을 내용(텍스트, 사진, 그래픽 등)이 그렇게 많지 않았고 요청이 올 때마다 새로운 html 문서를 전송해도 큰 문제가 없었습니다.
하지만 html에 담아야 하는 내용이 점차 많아지고 이미지와 그래픽의 크기가 커졌습니다. 따라서 이러한 내용들을 매번 새로운 html에 담아서 전송하면 유저의 컴퓨터 통신에 과부하가 생길 가능성이 높아졌습니다. 점점 유저의 요청에 늦게 반응하는 일이 빈번해졌고 이는 웹페이지의 사용자 경험을 부정적으로 만들었습니다.
이러한 상황에서 웹 개발자들이 생각한 방식이 바로 SPA입니다. 여러분들이 요청에 따라 PPT 페이지를 수정해야 하는 상황에 있다고 가정을 하겠습니다. 여러분들은 페이지를 모두 지우고 다시 작업하지 않고 수정해야 하는 부분만 고칠 것입니다. 전자의 방법은 기존의 웹페이지의 통신 방법입니다. 후자의 방법은 SPA의 통신 방법과 비슷합니다. SPA는 브라우저에 최초 한 번만 요청하여 페이지 전체를 로드합니다. 그 이후의 유저 요청에 의한 변화는 데이터를 업데이트하여 필요한 부분만 로드합니다.
SPA는 Virtual DOM(가상 DOM)에 트리 형태로 html 정보를 저장하고 있습니다. 그리고 유저의 요청이 발생하면 기존의 html 문서의 정보와 비교하여 모든 변화를 한 번에 적용하여 화면을 갱신합니다. 이렇게 Virtual DOM을 지원하는 웹 프레임워크는 React, Vue 등이 있습니다. DOM에 대해서 더 알고 싶으시다면 “mdn web docs: DOM 소개”를 방문해 보세요.
SPA에는 여러 장점이 있습니다. 우선 유저의 요청에 반응하는 속도가 매우 빠릅니다. 기존 웹페이지의 버튼을 누르면 페이지가 잠시 없어졌다가 나타나는데, SPA에서는 이런 간극을 최대한 줄일 수 있습니다. 따라서 유저가 느끼는 웹페이지 경험도 좀 더 개선될 수 있습니다. 또한 SPA에서는 컴포넌트 기반 개발 방식을 활용합니다. 컴포넌트는 웹페이지의 조립 가능한 블록이라고 생각하시면 됩니다. 이러한 블록들은 재활용이 용이하고 유지 관리도 쉽기 때문에 유용합니다.
하지만 이러한 SPA에도 단점은 존재합니다. SPA 페이지는 대부분 첫 로딩 시간이 깁니다. 기존의 웹사이트들은 대부분의 코드가 html에 들어 있기 때문에 빠르게 로드될 수 있으나, SPA는 많은 자바스크립트(스크립트) 파일을 로드해야 하기 때문에 시간이 걸립니다. 앞서 보았던 토스 뱅크 웹페이지도 브라우저 검사를 통해서 다운로드 된 리소스를 확인하면 많은 자바스크립트 파일을 볼 수 있습니다. 또한 일반적으로 클라이언트 사이드 렌더링 (CSR)을 주로 사용하여 쿠키에 데이터를 저장하기 때문에 보안이 취약할 수 있습니다. 클라이언트 사이드 렌더링에 대해서는 뒤에서 좀 더 자세히 설명하겠습니다.
SPA의 단점 중에서 가장 마케터에게 중요한 것은 SEO가 어렵다는 점일 것입니다. 검색엔진의 크롤러는 링크를 타고 페이지를 돌아다니며 웹 문서(html) 파일을 읽습니다. 이러한 작업을 통해 단일한 url의 페이지마다 색인을 만들고 검색 결과로 색인된 페이지를 보여줍니다. 하지만 SPA는 url이 한 개지만 여러 가지 뷰(view)를 보여줍니다.
따라서 SPA에서 변화하며 보이는 수십 가지의 기능을 가진 뷰가 단 한 개의 페이지로 색인됩니다. 이런 경우에 다양한 페이지 뷰가 단일한 Meta data로 보입니다. 따라서 SEO에 치명적입니다. 페이지의 뷰는 변화해도 페이지의 타이틀과 디스크립션을 바꿀 수 없기 때문에 사용자 경험 개선 및 검색엔진의 최적화가 어렵습니다.
트위터에서는 이러한 문제의 심각성을 파악하고 해결 방법을 연구하였습니다. 트위터의 입장에서는 계정 정보 및 댓글 데이터가 검색에 노출되는 것이 중요하기 때문에 해당하는 URL을 고유하게 만들고 싶어 했습니다. 이 과정에서 활용된 것이 해시 뱅(hash bang) 태그입니다.
화면 전체를 로드하지 않고 댓글의 데이터만 바꾸는 SPA의 장점을 살리면서도 댓글 URL에 “#!” 태그를 부착하였습니다. 이에 따라 고유한 URL을 가지도록 한 것입니다. 하지만 이것은 실제 리소스 위치에 대해 알 수 있는 방법이 아니었기 때문에 웹 표준에 어긋나는 것이었습니다. 또한 자바스크립트로 바꾼 url에 오류가 생길 수도 있다는 점이 문제점이었습니다.
해시 뱅과 같은 해결법 이외에도 동일한 URL 내에 완전히 복제된 사이트를 만들어서 색인할 수 있는 방법이 연구되곤 했습니다. 하지만 이런 방식은 중복된 웹사이트를 여러 가지 만들었기 때문에 유지 보수에 엄청난 힘이 들었습니다. 결론적으로, 이러한 솔루션들은 장기적인 솔루션으로 보기는 어려웠습니다. 현재는 두 방법 모두 사용하지 않는 추세입니다.
네이버는 검색 최적화 어드바이저 가이드에서 url에 timestamp나 hash 값을 넣어서 강제로 url을 업데이트하지 말라고 조언합니다. 또한 검색 봇 수집 리소스가 제한되어 있기 때문에 알고리즘 상으로 중요하다고 생각되는 페이지에 대해 수집 우선순위가 있다고 말합니다. 현재 구글, 네이버 등의 검색 엔진은 html 문서와 함께 자바스크립트 리소스를 함께 수집하고 있습니다. 하지만 SPA는 스크립트 리소스가 많아서 검색 봇 수집 리소스 할당량이 높아지기 때문에 색인 우선순위에서 뒤로 밀릴 수 있는 불안도 존재합니다.
그렇다면 SEO를 고려하여 SPA 방식의 웹페이지를 사용하지 않는 것이 좋을까요? 그렇지 않습니다. SPA는 사용자의 웹 경험을 최상으로 만들기 위해 고안된 방법이고 이를 통해 웹페이지의 이탈률을 줄일 수 있습니다. 이렇게 좋은 웹페이지 구성를 포기하는 것은 너무 아쉽습니다. 그리고 다양한 시도 끝에 SPA 페이지의 SEO의 개선 방법이 상당히 진전되었다는 점이 긍정적입니다. 이제부터 그 방법들을 소개해 드리도록 하겠습니다.
현대의 브라우저들은 window 객체의 하위 객체인 history 객체를 가지고 있습니다. 만약 이전 활동 기록이 있는 페이지에서 여러분들이 window.history.back().이라는 명령어를 콘솔 항목에 입력한다면 뒤로 가기를 누른 것과 같은 동작을 할 것입니다. 이렇게 사이트 내에서 유저가 이동한 기록을 남겨주는 기능이 history API입니다. 이 history API의 메서드 중 하나인 pushState를 활용하면 SPA SEO의 문제를 해결할 수 있습니다.
pushState() 메소드는 각각 (데이터 상태 객체, 빈 문자열, 표시할 URL)을 인자로 받습니다. 이 메소드가 호출되면 전달된 url이 브라우저의 url 창에 표시됩니다. 이해가 쉽도록 예시를 들어보겠습니다. seo.tbwakorea.com 페이지를 켜고 콘솔 창에 하단의 명령어를 입력해 보세요.
var stateObject={데이터_종류:”중요한 데이터”};
history.pushState(stateObject, “”,”새페이지.html”)
이 명령어를 입력하면 url이 “seo.tbwakorea.com/새페이지.html” 로 바뀝니다. 물론 저희 블로그 디렉토리에 “새페이지,html”이라는 파일이 없기 때문에 페이지의 변화는 없습니다. 핵심은 명령어를 통해서 url을 바꿀 수 있다는 것입니다. SPA에서 구분이 필요한 뷰로 진입할 때마다 pushState 메서드로 주소를 바꿔준다면 해당 뷰를 새 콘텐츠가 있는 새 페이지로 인식한 검색엔진 봇이 해당 페이지를 크롤링하고 색인을 생성할 것입니다.
이 방법을 통해 SPA는 여러 가지 페이지를 가진 것처럼 검색 엔진에 표시될 수 있습니다. 실제로 트위터에서는 이 방법을 통해서 유저가 SPA를 탐색할 때 새 페이지가 열리는 것처럼 주소 표시줄에 나타나게 합니다. 만약 여러분들이 SPA 페이지의 마케팅 담당자라면 pushState의 사용법을 인지하신 후, 개발자와의 협업으로 색인 페이지를 어떻게 나눌지 회의하는 것이 좋습니다.
history API를 활용하는 것이 SPA SEO를 위한 완벽한 방법일까요? 그렇지는 않습니다. pushState는 페이지만 바꿀 뿐 아니라 페이지 간의 데이터도 전송합니다. 그러나 pushState로 전달할 수 있는 데이터는 직렬화된 데이터만 포함되기 때문에 데이터의 양에 제한이 있습니다. 이것을 다시 말하자면 SPA가 더 복잡한 기능을 가지고 많은 State 데이터(유저 로그인 여부 등)를 생산할 경우에는 연속성 있게 페이지를 연결할 수 없다는 것입니다. 이러한 문제의 대안으로 활용할 수 있는 것이 바로 서버 사이드 렌더링입니다.
우선 서버 사이드 렌더링(SSR)과 클라이언트 사이드 렌더링(CSR)을 설명하겠습니다. 인터넷을 사용할 때 컴퓨터 사이에는 늘 통신이 이루어집니다. 정보를 보내는 쪽의 컴퓨터를 서버, 정보를 받는 쪽의 컴퓨터를 클라이언트라고 합니다.
SSR은 서버 쪽에서 화면을 전부 렌더링 해서 보내는 것입니다. 반면에 CSR은 서버 측으로부터 필요한 리소스를 다운로드하고 스크립트를 실행시켜 서버에 필요한 데이터를 요청하여 콘텐츠를 렌더링 하는 것입니다. 필요한 데이터를 중복으로 서버에 요청하는 것은 효율적이지 않기 때문에 클라이언트(브라우저)의 쿠키에 데이터를 저장하여 재사용합니다. 일반적으로 중요한 유저의 데이터를 쿠키로 다량 보관하는 것은 보안에 그리 좋은 사항은 아닙니다.
일반적으로 SPA는 CSR을 활용합니다. 하지만 Next.js나 Remix 같은 SSR 프레임워크를 활용한다면 SSR을 활용한 SPA를 만들 수 있습니다. 물론 회사마다 개발 현황이 다르기 때문에 CSR로 구동되고 있는 SPA를 SSR로 바꾸기 위해서 갑자기 SSR 프레임워크를 도입할 수는 없습니다. 웹 프레임워크의 도입은 신중하게 생각해야 할 점들이 많기 때문입니다. 프레임워크를 활용하여 CSR SPA를 SSR로 바꿀 수 있는 방법은 다양합니다. 하지만 이러한 내용은 이 글의 주제를 넘어가는 것이기 때문에 이 글에서는 다루지 않겠습니다. “React로 서버측 렌더링하기”에 관련 내용이 있으니 참고하시면 좋을 것 같습니다.
SPA의 작동 방식은 html 문서의 body 태그를 업데이트하는 것입니다. 이 과정에서 head에 대한 업데이트는 잘 이뤄지지 않습니다. head 태그는 검색 결과에 영향을 미칠 수 있는 meta 태그 등 중요한 SEO 요소가 있기 때문에 페이지마다 달라지도록 관리해야 합니다. 따라서 head를 업데이트할 수 없는 SPA는 SEO에 취약할 수밖에 없습니다.
React Helmet
이때 활용할 수 있는 웹 라이브러리가 바로 React Helmet입니다. Helmet은 react라는 SPA 웹 프레임 워크에서 유저가 앱을 조작할 때마다 그에 맞는 head 태그를 업데이트하는 기능을 가지고 있습니다. 앱 내에서 기능별로 나누어진 컴포넌트에 <Helmet>컴포넌트를 추가하여 사용하면 됩니다. <Helmet>컴포넌트 내에서는 아래의 코드와 같이 html로 SEO 작업을 진행하면 됩니다. 만약 적용이 잘 되었다면 SPA 페이지임에도 사용자의 이동에 따라서 <head>태그가 바뀌는 것을 볼 수 있습니다.
하지만 이렇게 동적으로 head 태그에 내용을 추가해도 몇몇 검색 봇은 이 바뀐 내용을 크롤링 하지 못할 수 있습니다. 모든 검색 엔진이 자바스크립트 파일을 수집하는 것은 아닐 뿐더러, 자바스크립트를 수집하고 해석하는 것은 html 페이지의 해석보다 몇 배 이상의 리소스가 필요한 작업이기 때문입니다.
React Snap
따라서 주요 영역은 검색 엔진 봇이 html 만으로 콘텐츠를 읽을 수 있게 구성하는 것이 좋습니다. 이러한 문제를 해결해 주는 것이 바로 React Snap입니다. 이 라이브러리는 변화하는 html 파일을 스냅 사진 찍듯이 고유한 html 파일로 변환하여 앱을 빌드 해줍니다. 이 과정을 통해 SSR 방식을 사용하지 않고 고유한 html를 만들어낼 수 있게 됩니다.
이러한 방법을 Prerendering이라고 합니다. 이러한 방법을 통해서 CSR 방식으로 이미 웹앱 개발이 완료된 시점에서 대안적으로 SEO를 개선할 수 있습니다. 다만 현재는 유지 보수를 하지 않는 라이브러리이기 때문에 이 점을 유의하여 사용을 결정하시길 바랍니다.
지금까지 SPA에서 SEO를 진행하는 방법을 알아보았습니다. 아무래도 웹 개발의 영역까지 포괄적으로 다뤄야 하는 내용이기 때문에 마케터 분들께서는 이해하기 쉽지 않으셨을 것 같습니다. 다양한 방안을 말씀드렸지만 가장 추천드리는 방법은 SSR로 SPA를 구현하는 것입니다. CSR 방식을 유지하면서 계속 추가되는 SPA 기능의 SEO를 유지 관리하는 것은 꽤 많은 노력이 필요하기 때문입니다.
네이버의 웹 마스터 가이드에서도 SPA 사이트에 SSR을 사용할 것을 권장하고 있습니다. SPA의 SEO를 개선하는 일은 웹 페이지의 구조를 바꿔야 하는 일이기 때문에 꼭 사내의 개발자와 미팅 후에 우선순위를 파악하여 진행해 주시길 바랍니다.
SEO는 비즈니스의 여러 분야를 고려해야 하는 종합적인 기술입니다. SPA SEO처럼 복잡한 영역은 전문가의 기술이 필요합니다. 저희 TBWA Data Lab은 이러한 전문적인 SEO 기술로 고객사가 가진 문제를 통찰하고 해결합니다. 만약 SEO와 관련하여 컨설팅을 받고 싶으시다면 아래 링크를 통해서 문의주세요.
>> TBWA DATA LAB 본문 바로가기
>> TBWA KOREA SEO 컨설팅 서비스 바로가기
해당 글은 TBWA 데이터랩과 모비인사이드의 파트너쉽으로 제공되는 기사입니다.
모비인사이드의 뉴스레터를 구독해보세요