SEO 처리를 위해 알아야할 JavaScript의 기본

지금 SEO를 고려한다면 JavaScript를 정확하게 이해하고 있는지가 중요하다. 또한 JavaScript가 검색 성능에 마치는 잠재적인 영향을 이해하는 것도 중요하다. 검색엔진이 사이트를 크롤링할 수 없거나, 사이트 내용을 분석하고 파악하지 못하면 페이지가 제대로 인덱싱되지 않게 되어 검색순위를 얻어내지 못하게 된다.

SEO에서 JavaScript는 가장 중요하게 봐야할 부분은 검색엔진이 컨텐츠를 확인허가나 웹사이트 상태를 체크하거나 할 수 있는지, 그리고 만약 할 수 없다면, 어떤 솔루션을 이용하면 해결되는지가 중요하다.

기본 지식

JavaScript란?

  • HTML(Hypertext Markup Language): 사이트의 중추적인 역할을 하며 컨텐츠를 구성하는 역할이다. 구체적으로는 웹사이트의 구조(제목, 단락, 목록등)을 보여주는 정적인 컨텐츠를 정의한다.
  • CSS(Cascading Style Sheets): 디자인, 모양, 스타일등을 웹사이트에 제공한다. 즉, 페이지의 프리젠테이션 레이어 기능을 한다.
  • JavaScript: 양방향 실행을 가능하게 하며 동적인 웹의 핵심 구성 요소이다.

JavaScript는 HTML 문서에서 <script>요소를 사용하여 만들거나, 링크로 참조한다. 현재 JavaScirpt라이브러리와 프레임웍에는 jQuery, Angular, React등의 다양한 종류가 있다.

Ajax?

Ajax(Asynchronous JavaScript and XML)는 JavaScript와 XML를 결합한 웹개발 방법으로 웹애플리케이션에서 현재 보고 있는 페이지에 간섭없이 백그라운드에서 서버와 통신할 수 있도록 한 것이다.

Asynchronous(비동기)는 스크립트 실행 중에 다른 기능이나 코드를 실행할 수 있다는 뜻이다. 브라우저에서 정상적인 JavaScript는 하나의 코드를 실행하는 것을 중지하고 다른 코드를 실행하는 동기화적인 행동을 하지만 Ajax는 다른 코드 실행 여부에 관계없이 코드를 실행하는 비동적인 처리가 특징이다.

XML은 데이터를 전달하는 주요 언어였지만, 현재는 비XML 데이터 형식을 사용하는 것도 많다. 예를 들어, 현재는 JSON형식으로 데이터를 전달하는 경우가 많지만, 그래도 Ajaj(Asunchronous JavaScript and JSON)이라고 표현하지 않는다.

Ajax의 일반적인 용도는 웹페이즈를 통째로 업데이트하지 않아도 해당 페이지 내용이나 레이아웃을 업데이트할 수 있도록 한 것이다.

일반적으로 브라우저가 다른 페이지를 로드할 때, 해당 페이지의 HTML을 서버에서 가져오고 또한 페이지에서 참조하는 모든 리소스(이미지, CSS등)를 서버에서 검색한 다음 해당 페이지에서 표시할 필요가 있기 때문이다.

그러나 Ajax를 사용하면, 페이지에서 내용을 변경하는 컨텐츠 및 자신만을 새로운 서버에서 검색하고 표시하기 위해서 페이지를 통째로 업데이트할 필요가 없는 사용자 경험(UX)이 향상된다.

Ajax는 소규모 서버 호출이라고 볼 수 있다. Ajax가 가장 잘 적용된 서비스를 손에 꼽는다면 구글지도이다. 구글지도는 전체페이지를 다시 로드하지 않고, 페이지가 업데이트될 때마다 필요한 부분만 업데이트된다.

DOM(Document Object Model)?

SEO담당자라면 DOM에 대해서도 이해하고 있어야 한다. 그 이유는 구글이 DOM을 이용하여 웹페이지를 분석하고 파악하기 때문이다. 쉽게 말하면,  DOM은 브라우저가 현재 보고 있는 페이지의 정보 및 상태이다. 브라우저는 우선 HTML문서를 수신한다. 그 다음 이 문서의 내용분석을 시작하여 이미지, CSS, JavaScript파일같은 추가 리소스를 얻는다. DOM은 이런 정보와 리소스를 분석하여 생성하는 것이다. 웹 페이의지 HTML이나 이미지같은 모든 정보를 브라우저가 처리할 수 있도록 구조화하고 정리하는 것이다.

지금의 DOM은 동적 HTML이라고 총칭되는 기술에 대한 초기 HTML문서와는 크게 달라진 경우가 많다. 동적인 HTML은 HTML, CSS, JavaScript를 사용하여 사용자 입력, 환경조건등의 변수에 따라 페이지 내용을 변경할 수 있다.

아래 예는 JavaScript를 사용한 <title>요소 내용을 작성한 것이다.

[HTML소스]

[JavaScript가 처리한 결과의 DOM]

헤드리스 브라우징?

헤드리스 브라우징은 간단하게 말하자면, 사용자 인터페이스를 사용하지 않고 웹페이지를 검색하는 행위이다. 이를 이해가 위해서는 구글이나 바이두가 헤드리스 브라우징을 이용하여 사용자 경험과 웹페이지 컨텐츠를 보다 정확하게 파악할 수 있도록 하고 있다.

Zombie.js스크립트 기반 헤드리스 브라우저에서 일반적으로 테스트를 위해 웹상에서 작업을 자동화할때나 첫번째 요청하면 정적인 HTML스냅샷을 표시하는데 사용된다.

 

JavaScript가 SEO에게 안좋은 이유

사이트에서 JavaScript를 이용함에 있어 단점이 3가지가 있다.

  • 탐색의 용이성: 봇이 사이트를 크롤링할 수 있는지에 대한 여부
  • 취득의 용이성: 봇이 정보에 접근하고 내용을 분석할 수 있는지에 대한 여부
  • 사용자가 인식하는 사이트 표시 속도: 크리티컬 렌더링 경로 문제

탐색의 용이성

봇에 URL을 찾아달라고 사이트의 구조를 이해할 수 있을까에 대한 문제이다. 여기서는 아래 두가지 요소가 중요하게 생각된다.

  • 검색엔진이 JavaScript를 취득할 수 없도록 차단해 버리지 않고 있는가?
  • 내부 링크가 올바르게 설정되어 있는가? JavaScript 이벤트로 HTML태그 대신 사용하거나 하지 않는가?

JavaScript블록이 상당히 큰 문제가 될 수 있다. 검색엔진은 JavaScript를 크롤링할 수 없는 경우, 사잍의 모든 상태를 받을 수 없게 된다. 즉, 최종 사용자가 보고 있는 것과 같은 내용을 검색엔진을 볼 수 없게 된다. 왜 이런 문제가 생길까? 검색엔진이 파악한 사이트 내용은 사이트관리자가 이미지한 것과는 다르기 때문에 결과적으로 호소력이 약해지기 때문이다. 또한 은폐한다고 볼 수 있다. 참고로 Fetch as Google , TechnicalSEO Fetch & Render등의 도구를 사용하면 구글봇이 차단된느 리소스를 찾는데 도움이 된다.

물론 이 문제를 해결하는 가장 간단한 방법은 사용자 경험을 이해하는데 필요한 리소스에 대해 검색엔진이 접근할 수 있도록 하는 것이다.

내부링크

지금까지 JavaScript기반의 웹사이트(Ajax기반 웹사이트)는 URL에 조각식별자(#)을 사용했다. 하지만 검색엔진에서는 제대로 사이트 컨텐츠를 크롤링시 JavaScript가 페이지 내용을 고쳐나갈때 URL구조를 어떻게 사용하는지가 중요하다.

권장하지 않는 사용방법

  • 단독 해시기호(#) : 단독 해시기호는 크롤링되지 않는다. 해시행커링크(점프링크)를 식별하는데 이용된다. 앵커링크와 같은 페이지 컨텐츠로 이동하는 링크이다. URL의 해시기호 뒤에 기술된 내용은 서버로 전송되지 않고 ID가 일치하는 첫번째 요소까지의 페이지가 자동으로 스코롤된다. Ajax사리트에서는 URL에 #을 사용하지 않는 것을 구글이 권장하고 있다.
  • 해시밴(#!) : 해시밴을 붙인 URL은 일단 탐색을 가능하게 하기 위한 대책이었다. 그러나 현재 구글은 그 사용을 권장하지 않으면 Bing만 지원하고 있다. 구글은 사용자경험을 체크하도록 하기 위해 “_escaped_fragment_”는 두가지 사용자 경험을 제공하는데 원래의 체험을 위한 간결한 URL은 “#!”(해시밴)을 URL에 포함시켜 표시하는데 메타요소를 추가하여 이스케이프 조각 존재를 나타낼 필요가 있다. (meta name=”fragment” content=”!”) 그외 중복된 URL은 검색엔진 봇이 해시밴을 “_escaped_fragment_”로 대체하여 서버에 접근한다. 그런 접근에 대해서는 HTML스냅샷을 제공하는 구조였지만 중복URL이라는 이유로 문자가 완벽하게 보이지 않는다.

권장 사용방법

  • pushState History API: pushState는 JavaScript명령에서 History API로  주소표시줄의 URL을 업데이트하고 해당 페이지에서 변경이 필요한 부분만 업데이트되도록 한다. 따라서 JavaScript 기반의 웹사이트가 깔끔한 URL을 사용할 수 있게 된다. pushState는 현재 구글에서 지원되며 클라이언트측 또는 하이브리드 렌더링에서 브라우저 탐색에 대응한다.
    • history.pushState(data, title, url);
    • history.replaceState(data, title, url);
  • 무한스크롤은 사용자가 스크롤하면서 새 컨텐츠가 Ajax를 통해 새롭게 읽혀진 주소표시줄에서 URL이 변경된다. 이상적인 사용자경험은 사용자가 페이지를 업데이트하면 똑같은 위치가 나타나야 한다. 그러나 페이지 업데이트를 사용자가 할 필요가 없다. 스크롤 조작에 의해 컨텐츠가 업데이트되면 주소표시줄에 URL이 업데이트되기 때문이다.

 

취득의 용이성

검색엔진은 사용자경험 및 페이지 컨텐츠를 보다 정확하게 파악할 수 있도록 헤드리스 브라우징을 이용하여 DOM을 렌더링할 수 있다. 즉, 구글은 일부 JavaScript를 처리하는 인덱스하는 내용을 처리하는데 DOM을 사용하고 있는 셈이다. 그러나, 동시에 검색엔진에서 JavaScript 이해에 어려움을 겪고 있는 상황을 볼 수 있다. 자신의 사이트나 고객사 사이트가 빠지지 것을 원하지 않을 것이다. 봇이 어떻게 사이트의 컨텐츠와 상호작용을 하는지 이해하는 것은 상당히 중요하다. 모르면 테스타라도 해서 이해하기 바란다.

검색엔진 봇은 JavaScript를 실행할 수 있는 것으로 검색엔진이 컨텐츠를 검색할 수 있도록 하기 위한 중요한 요소는 아래와 같다.

  • 사용자가 작업을 실행 시, 표시되는 내용이 있어도 검색엔진은 아마도 그 내용을 확인할 수 없다.
    • 구글 봇은 클릭도, 스크롤도, 로그인도 하지 않는다. 완벽한 사용자 경험을 제공하기 위해 사용자 조작을 요구하는 경우에도 봇도 동일한 경험을 할 수 있도록 세심한 주의가 필요하다.
  • JavaScript 로드 이벤트가 시작되고 나서 실행되는데 5초이상 걸리면 검색엔진은 그 내용을 보고 하지 않을 수 있다. 5초에 대한 근거는 아래와 같다.
    • 시간 초과값이 지정된 것은 아니지만, 사이트가 5초 이내 로드되도록 하는 것을 목표로 한다. (참고: Google JavaScript Sites in Search Working Group)
    • 구글 봇은 컨텐츠 렌더링까지 기다리는 시간은 5초정도라는 것이다. (참고: Screaming Frog 테스트)
    • 로드 이벤트 시작이 5초 이내라는 기준은 구글 PageSpeed Insights 및 Fetch as Google에서도 사용되고 있다. (참고: maxeight.com)
  • JavaScript에 오류가 있는 경우, 전체코드가 실행되지 않으면 브라우저와 검색엔진 모두 동작을 완료하지 못하고 페이지 일부가 안보일 수 있다.

 

검색엔진(구글 등)에서 컨텐츠를 확실하게 얻을 수 있도록

1. 테스트

JavaScript 문제를 해결하기 위해 가장 많이 사용되는 솔루션은 없다. 구글을 검색하는 사용자와 동일한 경험을 하고 싶어한다. 구글이 “웹(즉, JavaScript)를 보다 정확하게 이해”할 수 있게 되었다고 발표한 것은 2014년 5월이었다.

그러나, 업계 전문가들이 이 발표가 있기 전부터 구글이 JavaScript를 탐색하는 능력이 있다고 이야기들을 한바 있다. 즉, DOM내용을 확인할 수 있다면, 컨텐는 구글 해석이 가능할 것이다. 올해초, “Can Google properly crawl and index JavaScript framework? JavaScript SEO experiment.“라는 실험내용도 공개되었다. 이는 구글이 어떻게 페이지를 취급하여 URL 및 컨텐츠를 인덱싱하는 것과 Google Search Console이 어떻게 작동되는지를 확인하였다. 그결과 구글이 다양한 형식의 JavaScript를 처리할 수 있다는 것과 일부 난위도가 높은 프레임웍도 가능했다.

이런 연구결과는 사실 SEO를 처리해야하는 담당자라면 이해하고 미리 대책을 세울 수 있어 좋은 지표가 된다. 그렇지만 테스트 및 리뷰를 할 때 아래 내용을 고려하자.

  1. 콘텐츠가 DOM에 표시되어 있는지 확인한다.
  2. 페이지 일부를 테스트하고 구글이 컨텐츠를 인덱싱할 수 있는지 확인한다.

좀더 상세히 이야기하면 아래와 같다.

컨텐츠 인용을 수동으로 체크한다.

  • Fetch as Google에서 페이지를 검색하고 내용이 표시되어 있는지 확인한다.
  • Fetch as Google 검색은 이미 로드 이벤트가 발생할 때 또는 그 전에 이루어질 것으로 보인다. 이 테스트는 구글에 컨텐츠를 확인받을 수 있는지, 또는 robots.txt에서 JavaScript를 차단하지 않았는지 확인하는데 최적이다. 단, Fetch as Google은 100% 확실하지 않지만, 노력의 출발점으로써는 충분하다.
  • Google Search Console에서 사이트확인을 마치지 않았다면, Technicalseo.com의 Fetch & Render As Any Bot을 사용하길 권장한다.

이 테스트를 통해 잘되지 않는 부분이 있는지, 검색엔진이나 봇 인덱싱, 컨텐츠를 얻는데 막혀 있지 않은지를 확인할 수 있다. 하지만 다른 검색엔진등을 고려하면 좀더 복잡해지지만 트위터 Summary 카드나 페이스북 Open Graph 태그등은 다른 봇이 해석하느 경우 메타정보를 이용하는 경우도 있다. 이런 것들에 대한 테스트에서 문제가 발견되거나 우려할 문제가 생기면 그것을 해결하는 것은 HTML스냅샷에서 설명하겠다.

2. HTML스냅샷

HTML 스냅샷은 완전히 렌더링된 페이지를 서버에서 직접 리턴한 DOM이라고 할 수 있다. 보통 서버사이드 렌더링이라고 불리며, JavaScript로 하는 것과 같은 처리를 서버측에서 실시한 결과 상태를 HTML로 유지하는 것이다.

구글은 2008년에 HTML스냅샷을 도입했지만, 2015년 폐지했다. 이후 2016년 후반부터 구글은 사용을 피해야 한다고 이야기하고 있다.

HTML스냅샷은 구글에게는 무엇인가 논쟁거리로 보여진다. 하지만 상황에 따라서는 필요하기 때문에 HTML스냅샷을 이해하는 것이 중요하다.

검색엔진(또는 페이스북같은 사이트)이 JavaScript 처리를 할 수 없는 경우, 컨텐츠가 인덱싱되지 않고 처리되지 않는다고 보기보다는 HTML스냅샷을 리턴하는 것이 좋다. 사이트가 서버측에서 어떤 형태로 사용자 에이전트를 감지하고 그에 맞는 HTML스냅샷을 리턴할 수 있으면 이상적이다. 그러나 구글이 사용자 동일한 경험을 원하는 것을 기억해야 한다.

독자가 HTML스냅샷을 고려한다면, 구글이 HTML스냅샷 방식을   Ajax에서 권장하지 않는 것을 꼭 기억해 둘 필요가 있다. 구글은 지금도 기술적인 지원을 제공하고 있지만, 이용을 하지 않는쪽을 권장한다. 구글은 이전 사고방식을 바꾸고 지금은 사용자와 동일한 경험을 제공하면 좋겠다는 생각을 하고 있다. 이 정책전환은 타당한데, 사용자경험에 가까운 경험을 봇이 얻을 수 있게 되기 때문이다.

다음 고려해야할 사항은 클로킹(cloaking)으로 간주되는 위험에 대해서이다. HTML스냅샷이 페이지 경험을 재현하지 못하는 경우, 클로킹으로 간주될 위험이 있다.

장점

  • 검색엔진과 크롤러 체험을 파악할 수 있는 지식이 있다. 특정 유형의 JavaScript는 구글이 인식되기 어려운 경우가 있다.
  • 다른 검색엔진과 크롤러(Naver, Bing, 페이스북 등)가 체험을 파악할 수 있게 된다. 특히 Bing은 javaScript 크롤링 및 인덱싱을 할 수 없다고 한다. JavaScript를 많이 사용하는 사이트(삼성 글로벌 사이트 등)는 HTML스냅샷이 Bing에 대한 유일한 해결책이 될 수 있다. 하지만 적용되는지에 대한 테스트를 미리하고 진행해야 한다.

 

사이트 표시 지연

브라우저가 HTMl문서를 수신하여 DOM을 만들 때 대부분의 리소스가 로드된 HTML문서에 표시된다. 따라서, HTMl문서가 매우 큰 파일이 지정된 경우, 브라우저는 그 큰 파일을 우선 서버에서 검색하고 읽어들이게 된다. 구글의 핵심 렌더링 경로는 사용자가 필요로 하는 것을 빨리 로드해야 한다고 생각하고 있다. 즉, 가장 중요한 것은 사용자 전에 한시라고 빨리 제시하자는 것으로 바꾸어 말할수 있다.

크리티컬 렌더링 경로는 HTML, CSS, JavaScript 바이트 수신에서 이런 픽셀로 렌더링하는데 필요한 처리까지의 중간 단계를 이루고 있다.

페이지를 표시하는데 최적화에 있어서 전체페이지를 읽거나 처리에 눈을 가지고 가는 것이 아니라, 이런 브라우저 실행을 파악하고 그에 따라 코드와 리소스를 최적화하는 것이 중요하다. 이렇게 하면 페이지가 나타날때까지의 시간(즉, 사용자 체감속도)를 크게 개선할 수 있다.

이 말은 전체 페이지 보기가 완료까지 걸리는 시간이 같아도 크리티컬 렌더링 경로에 최적화되어 있는 경우와 아닌 경우 사용자 체감속도는 달라진다. 자세히 이야기하면 페이지 초기화면에 불필요한 리소스 및 JavaScript파일이 있으면 그로 인해 페이지 로딩은 느려진다. 이는 렌더링을 방해하는 JavaScript라고 말할 수 있다. 이런 요소를 최적화하여 이미 로드되어 있는 것처럼 사용자에게 체험할 수 있도록 한다.

렌더링을 방해하는 JavaScript 대응방법

페이지 속도는 PageSpeed Insights도구WebPageTest.org등으로 사용하여 분석하자.

  • 렌더링을 방해하는 JavaScript에 대한 대응은 총 3가지로 이야기할 수 있다.
  • 인라인: JavaScript를 외부파일이 아닌 HTML문서 내에 추가한다.
  • 비동기화: JavaScript를 비동기(async속성 추가)를 선언한다.
    • <script async src=”test.js”>
  • 하단배치: JavaScript 배치위치를 HTML head대신 body뒤로 이동한다.

스크립트는 실행 우선순위가 높은 순서로 기술할 필요가 있다는 것을 꼭 기억하자. 가장 중요한 내용을 로드하는데 사용되는 스크립트는 우선시 해야 하기 때문에 하단배치는 하지 말자. 또한, 다른 파일을 참조하는 스크립트는 참조파일이 로드된 이후에 사용 가능하다.

 

마지막으로 크롤러와 검색엔진이 JavaScript를 탐색, 실행, 해석하기 위해 최선을 다하고 있지만 그것이 성공한다는 보장은 없다. 다만, 컨텐츠를 크롤링 및 검색이 가능한 상태로 사이트 표시에 지연을 초래하지 않도록 하기 위함에 집중하자. 그렇기 때문에 모든 상황을 고려한 테스트를 하는 것이며, 테스트결과를 통해 해결책을 찾을 수 있다고 본다.

Site Footer