블로그 페이지 속도 개선하기 MutationObserver 활용방법

블로그 페이지 속도 개선하기 MutationObserver 활용방법

블로그 로딩 속도를 높이고 불필요한 리소스를 차단하는 웹사이트 성능 최적화 전략을 알아보세요. MutationObserver API지연 로드(Lazy Load)를 활용해 방문자 경험(UX)과 구글 SEO 점수를 비약적으로 향상시킬 수 있습니다.

티스토리나 워드프레스 플랫폼 운영 시, 사용자가 직접 설치하지 않은 수많은 외부 자바스크립트(External JavaScript)와 불필요한 트래킹 리소스들이 블로그 속도를 저하시키는 것을 흔히 볼 수 있습니다. 이는 구글의 핵심 순위 결정 요소인 코어 웹 바이탈(Core Web Vitals) 점수에 치명적인 영향을 미칩니다.

블로그 최적화 2편의 핵심인 이 방법은, 브라우저가 리소스를 요청하기 전에 개입하여 불필요한 스크립트를 원천 차단하고 필수 리소스를 선별적으로 로드하여 웹 성능을 향상시킵니다.

1. 외부 자바스크립트가 블로그 속도 및 SEO에 미치는 영향

대부분의 스킨은 사용자 분석 도구(Tiara), 외부 광고 서버(Pubmatic, Dable), 라이브러리(jQuery) 등을 기본 호출합니다. 이러한 리소스 제어가 되지 않을 경우 다음과 같은 문제가 발생합니다.

  • 렌더링 차단 리소스(Render-Blocking): 브라우저가 스크립트를 완전히 로드하고 실행할 때까지 화면 출력을 멈추므로 페이지 로딩 속도가 급격히 느려집니다.
  • 불필요한 CPU 점유: 모바일 환경에서 과도한 자바스크립트 실행은 기기 발열을 유발하고 FID(최초 입력 지연) 시간을 증가시킵니다.
  • 데이터 소모 및 이탈률 증가: 보이지 않는 영역의 광고 스크립트 로딩으로 실제 콘텐츠 확인이 늦어지면 방문자는 즉시 사이트를 이탈합니다.

2. MutationObserver를 활용한 고급 자바스크립트 제어 방식

최적화의 핵심은 리소스 요청 전 단계에서의 개입입니다. MutationObserver API는 DOM(Document Object Model)의 변화를 실시간으로 감시하여 특정 요소가 추가되는 즉시 제어권을 가집니다.

2.1 MutationObserver의 핵심 개념과 동작 원리

일반적인 이벤트 리스너가 사용자의 상호작용에 반응한다면, 이 API는 HTML 구조 자체가 변하는 순간을 포착합니다.

  • Mutation(변화): 새로운 태그(Node)가 추가되거나 속성이 변경되는 모든 행위.
  • Observer(관찰자): 실시간 감시를 통해 조건에 맞는 요소 발견 시 즉시 차단 또는 수정 로직 실행.

2.2 코드 내 실시간 감시 및 노드 필터링 4단계

  1. 전체 감시 시작:observer.observe를 통해 HTML 문서 전체를 감시 대상으로 설정합니다.
  2. 노드 삽입 포착: 외부 서버나 광고 모듈이 스크립트를 삽입하려는 찰나를 가로챕니다.
  3. 블랙리스트 검문: 해당 경로가 차단 리스트(blockList)에 포함되어 있는지 즉시 대조합니다.
  4. 강제 제거 및 지연 로드: 광고나 트래킹 요소는 node.remove()로 원천 제거하고, 필수 리소스는 지연 로드하여 초기 속도를 확보합니다.

2.3 성능 최적화의 치트키가 되는 이유

사후에 지우는 방식이 아니라, 브라우저가 파일을 다운로드하기 전 DOM 추가 시점에 가로채기 때문에 네트워크 대역폭 낭비를 막고 메인 스레드 부하를 획기적으로 줄입니다. 이것이 바로 구글 PageSpeed Insights 점수를 올리는 비결입니다.

const observer = new MutationObserver(mutations => {
    for (let m of mutations) {
        for (let node of m.addedNodes) {
            
        }
    }
});

3. 기술적 SEO 최적화 세부 전략

검색 엔진이 선호하는 최적화된 구조를 만들기 위한 세부 기술들입니다.

블로그 속도 저하의 주범인 동영상(유튜브 임베드 영상)을 효율적으로 관리합니다.

  • 레이지 로딩(Lazy Loading):loading='lazy' 속성을 주입하여 사용자가 영상 위치까지 스크롤하기 전에는 데이터를 불러오지 않습니다.
  • 개인정보 보호 도메인 사용: 주소를 youtube-nocookie.com으로 전환하여 개인정보 수집을 줄이고 영상 로딩 속도를 개선합니다.

3.2 불필요한 메타 데이터 및 스타일시트(CSS) 제거

필요 없는 코드나 기본 메뉴 스타일을 찾아 지우면 브라우저가 읽어야 할 파일이 줄어들어 페이지 응답성이 높아집니다. 기본 메뉴바를 제거해도 사이드바에 링크를 구성하면 기능 손실 없이 페이지 속도 개선이 가능합니다.

4. 블로그 콘텐츠 보호 및 불법 복제 방지

속도 최적화만큼 중요한 보안 설정입니다. 특정 도메인에서만 작동하는 보호 기능을 통해 정성껏 작성한 포스팅의 고유성을 지킵니다. 기본 플러그인 대신 코드를 직접 사용하는 것이 성능 면에서 유리합니다.

  • 우클릭 및 드래그 차단:contextmenu 이벤트를 제어하여 무단 복사를 방지합니다.
  • 단축키 제한: Ctrl+U, Ctrl+S, F12 등의 키 입력을 차단하여 코드 및 텍스트 유출을 최소화합니다.

5. 블로그 적용 방법 및 실전 코드

  1. 블로그 관리자의 [스킨 편집] – [html 편집]으로 진입합니다.
  2. 최적화 스크립트를 head 태그 최상단 혹은 body 시작 직후에 삽입합니다.
  3. 코드 내 도메인 확인 부분에 자신의 블로그 주소를 정확히 기입합니다.
  4. 저장 후 PageSpeed Insights에서 지표 개선 여부를 확인합니다.

5.1 전역 객체 초기화 및 기존 기능 무력화

window.loadedComments = true;
window.Tiara = window.Tiara || { __track: function(){} };
window.tistoryCommentInit = function(){};

var deferredScripts = {};
var deferredStyles = {};

5.2 제어 대상 리스트 정의 (필터링 기준)

var deferTargets = ['adsbygoogle', 'analytics', 'googletagmanager'];
var blockList = ['doubleclick.net', 'amazon-adsystem'];

5.3 MutationObserver를 이용한 실시간 가로채기

<script>
(function() {
    "use strict";

    const deferTargets = ["adsbygoogle", "analytics"]; // 지연 로딩할 키워드
    const blockList = ["unwanted-script", "test-api"]; // 완전히 차단할 키워드
    const deferredScripts = {};

    const observer = new MutationObserver(mutations => {
        for (let m of mutations) {
            for (let node of m.addedNodes) {
                // 1. 요소가 엘리먼트 노드가 아니면 건너뜀
                if (node.nodeType !== 1) continue;

                // 2. 스크립트 태그 제어
                if (node.tagName === 'SCRIPT') {
                    const src = node.src || '';
                    
                    // 지연 로딩 대상 확인
                    if (deferTargets.some(t => src.includes(t))) {
                        deferredScripts[src] = true;
                        node.remove();
                        continue;
                    }
                    
                    // 차단 대상 확인
                    if (blockList.some(b => src.includes(b))) {
                        node.remove();
                        continue;
                    }
                }

                // 3. 유튜브 iframe 최적화 (접근성 및 개인정보 보호)
                if (node.tagName === 'IFRAME' && (node.src || '').includes('youtube.com/embed/')) {
                    node.setAttribute('loading', 'lazy'); // 지연 로딩 강제 적용
                    node.setAttribute('title', 'YouTube Video Content'); // 웹 접근성 보완
                    node.src = node.src.replace('youtube.com', 'youtube-nocookie.com'); // 개인정보 보호 모드
                }

                // 4. 불필요한 광고 태그(INS) 즉시 제거
                if (node.tagName === 'INS') {
                    node.remove();
                }
            }
        }
    });

    // 전체 문서 감시 시작
    observer.observe(document.documentElement, { 
        childList: true, 
        subtree: true 
    });

    // 5초 후 감시 종료 (초기 로딩 최적화 목적이므로)
    setTimeout(() => {
        observer.disconnect();
        console.log("DOM Observer disconnected.");
    }, 5000);
})();
</script>

이 코드는 블로그의 “문지기” 역할을 수행합니다. 차단 대상은 즉시 돌려보내고, 지연 로딩 대상은 페이지의 핵심 텍스트가 모두 나타난 후 실행되도록 대기시킵니다. 결과적으로 방문자는 무거운 광고나 분석 툴을 기다릴 필요 없이 즉시 콘텐츠를 즐길 수 있습니다.

댓글 남기기