서드 파티 스크립트의 비용을 줄이려면 어떤 서비스가 로드되는지 파악하고, 실제 작업에 미치는 영향을 측정한 뒤, 방문자가 즉시 필요로 하지 않는 작업을 제거하거나 늦춰야 합니다. async와 defer는 실행 시점을 바꾸지만 실행 비용을 없애지는 않습니다. 따라서 초기 로딩뿐 아니라 동의 선택, 상품 선택, 검색, 고객 지원까지 점검해야 합니다.
사업에 필요한 스크립트도 잘못된 시점에 로드될 수 있습니다. 어떤 페이지와 상호작용에서 필요한지, 누가 결정하는지, 서비스가 중단되면 사이트가 어떻게 동작해야 하는지를 정하는 것이 핵심입니다.
직접 추가하지 않은 스크립트까지 목록에 포함합니다
랜딩 페이지, 기사, 상품 페이지, 해당하는 경우 결제 진입 페이지처럼 대표적인 템플릿을 선택합니다. Chrome DevTools의 Network 패널에서 새 탐색을 기록하고 도메인, 리소스 유형, 요청 시작 주체를 확인합니다. 작은 시작 스크립트가 많은 의존성을 불러올 수 있으므로 첫 파일만 평가하지 말고 서비스와 후속 요청을 함께 기록합니다.
선택적 추적에 동의하거나 채팅을 열고 삽입된 미디어를 재생한 뒤에도 반복합니다. 동의 전 상태와 비교하고 태그 관리자 컨테이너, 직접 삽입한 태그, 앱, 프레임, 콘텐츠 관리 시스템이 추가한 코드를 포함합니다. 도메인 목록만으로 책임 주체를 알 수는 없습니다. 자체 도메인 URL에서도 공급업체 코드가 제공될 수 있습니다.
서비스마다 목적, 담당자, 영향을 받는 템플릿, 로딩 조건, 제거 절차를 적습니다. 전송량, CPU 작업, 화면 동작은 별도로 기록합니다. 작은 파일이 많은 연산을 수행할 수 있고, 큰 미디어는 대역폭을 사용하면서도 다른 JavaScript 실행 특성을 보일 수 있습니다.
고객 식별자는 수집하지 않습니다. 재현에는 시나리오와 설정이 필요하지, 결제 개인정보가 담긴 기록이 필요한 것은 아닙니다. 민감한 정보를 제거한 추적 기록과 함께 브라우저 버전, 화면 크기, 네트워크 설정, 동의 상태를 남깁니다.
원인을 단정하기 전에 같은 조건으로 비교합니다
기준 기록을 만든 뒤 DevTools 요청 차단으로 의심스러운 URL이나 도메인의 로딩을 막습니다. 페이지를 다시 열고 같은 동작을 수행합니다. 차단을 해제한 후에도 반복합니다. 공급업체 응답, 캐시 상태, 백그라운드 작업이 달라질 수 있으므로 같은 조건에서 여러 차례 비교합니다.
차단은 진단 실험입니다. 상품 구성 도구가 사라졌다면 더 빠른 결과가 적절한 대안은 아닙니다. 사라진 기능도 성능 변화와 함께 기록합니다. 태그 관리자를 막으면 여러 공급업체가 한꺼번에 사라질 수 있으므로 전체 차이를 컨테이너 탓으로 돌리기 전에 하위 서비스를 따로 살펴봅니다.
Performance 기록과 네트워크 워터폴을 함께 읽습니다. 긴 작업을 찾고 주변 함수, 스크립트 URL, 상호작용을 확인합니다. 반응성 문제에는 INP 진단 절차를 적용합니다. 일반 Lighthouse 탐색 실행은 로딩과 차단 작업을 설명하지만 고객의 전체 상호작용을 재현하지는 않습니다.
이전 보고서에는 “Reduce the impact of third-party code” 감사가 있습니다. Chrome 문서는 Lighthouse 13에서 이 독립 감사가 이동했다고 설명합니다. 과거의 250 ms 기준을 보편적인 성능 예산으로 사용하거나 현재 보고서에도 같은 이름이 있다고 가정하지 않습니다. 버전을 확인하고 현재 진단 결과와 브라우저 기록을 함께 사용합니다.
기능이 실제로 필요한 가장 이른 시점을 선택합니다
로딩 정책은 기능에 맞춰 정합니다. 아래 비교는 일반 외부 스크립트에 관한 것으로, 모듈 스크립트의 기본 스케줄링은 다릅니다.
| 전략 | 적합한 상황 | 남는 비용 또는 위험 |
|---|---|---|
| 통합 제거 | 필요가 없어졌거나 기능이 중복됨 | 의존하는 작업이 유지되는지 확인 |
defer |
HTML 파싱 완료와 실행 순서가 필요함 | 메인 스레드는 계속 사용함 |
async |
문서 순서와 무관하게 실행 가능함 | 중요한 페이지 작업과 겹칠 수 있음 |
| 화면에 가까워질 때 로드 | 아래쪽에서만 필요한 삽입 콘텐츠 | 실제 사용 전에 다운로드할 수 있음 |
| 명시적 동작 후 로드 | 영상, 지도, 채팅이 선택 기능임 | 활성화 후 초기화 대기가 생김 |
| 필요한 동의 후 로드 | 설정된 서비스에 권한이 필요함 | 동의 직후 작업이 몰릴 수 있음 |
속성을 바꾸기 전에 공급업체의 통합 문서를 확인합니다. 라이브러리가 이미 있다고 가정하는 인라인 초기화 코드는 비동기 로딩으로 바꾸면 실패할 수 있습니다. 오류 표시를 없애는 것으로 끝내지 말고 이벤트가 한 번씩, 올바른 순서와 동의 상태로 도착하는지 확인합니다.
“첫 상호작용 후 모든 태그 로드” 같은 일괄 규칙은 피합니다. 빠르게 반응해야 할 클릭에 작업을 몰아줄 수 있습니다. 임의의 타이머 역시 비용 발생 시점을 바꿀 뿐 적절한 순간임을 증명하지 않습니다. 먼저 태그 수와 적용 페이지를 줄이고 기능을 단순화합니다.
선택적 임베드를 접근 가능한 파사드로 바꿉니다
파사드는 기능을 가벼운 화면으로 표현하고 요청받았을 때 실제 임베드를 로드하는 방식입니다. Google의 서드 파티 임베드 권장사항에서도 이 패턴을 설명합니다. 기능을 쓰지 않는 방문자의 불필요한 초기화를 피하는 데 의미가 있습니다.
다음 예제 HTML은 키보드로 누를 수 있는 버튼과 프레임용 공간을 만듭니다. 예제 주소를 프레임 삽입이 허용된 승인 URL로 바꾸고 화면 문구는 사이트 언어에 맞춰 수정합니다.
<div class="media-slot" id="media-slot">
<button type="button" id="load-media">Load product video</button>
</div>
<p id="media-status" role="status"></p>
<style>
.media-slot { aspect-ratio: 16 / 9; background: #edf2f7; }
.media-slot iframe { width: 100%; height: 100%; border: 0; }
</style>
<script type="module">
const button = document.querySelector('#load-media');
const slot = document.querySelector('#media-slot');
const status = document.querySelector('#media-status');
button.addEventListener('click', () => {
button.disabled = true;
status.textContent = 'Loading video';
const frame = document.createElement('iframe');
frame.title = 'Product video';
frame.src = 'https://example.com/embed/product-video';
frame.allowFullscreen = true;
frame.addEventListener('load', () => {
status.textContent = 'Video frame loaded';
});
slot.replaceChildren(frame);
frame.focus();
}, { once: true });
</script>이 코드는 로딩 패턴이며 완성된 플레이어 통합은 아닙니다. 프레임의 load 이벤트만으로 다른 출처의 플레이어가 사용 가능한지 알 수 없습니다. 공급업체가 제공하는 준비 완료 API를 사용하고, 운영 환경에서는 일반 대체 링크와 복구 경로도 추가합니다. 프레임을 생성하기 전에 Content Security Policy, 권한, 필요한 동의를 확인합니다.
예약한 비율은 최종 임베드와 일치해야 합니다. 그렇지 않으면 초기 로딩을 줄인 대신 콘텐츠가 눈에 띄게 움직일 수 있습니다. 레이아웃 이동 방지 안내를 참고해 광고와 채팅 패널에도 같은 원칙을 적용합니다. 키보드 작동과 교체 후 포커스 이동도 확인합니다.
채팅은 한 번만 로드하고 실패에서 복구할 수 있게 합니다
스크립트 기반 위젯에는 하나의 로딩 Promise를 유지해 반복 클릭으로 같은 스크립트가 삽입되지 않게 합니다. 아래 예제는 로더만 보여 줍니다. 공급업체 URL과 준비 완료 콜백은 통합 방식에 맞춰야 합니다. 다운로드 완료가 채팅 준비 완료를 뜻하지는 않습니다.
let chatScriptPromise;
export function loadChatScript() {
if (chatScriptPromise) return chatScriptPromise;
chatScriptPromise = new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = 'https://example.com/widgets/chat.js';
script.async = true;
script.onload = () => resolve();
script.onerror = () => {
script.remove();
chatScriptPromise = undefined;
reject(new Error('Chat script could not be loaded'));
};
document.head.append(script);
});
return chatScriptPromise;
}필요한 권한을 확인한 다음 채팅 버튼 클릭 처리기에서 함수를 호출합니다. 로딩 상태를 표시하고 실패를 처리하며 다른 연락 수단을 제공합니다. 로딩 중 반복 활성화를 막은 뒤 문서화된 API로 위젯을 엽니다. 존재하지 않는 전역 메서드나 성공한 초기화를 가정하지 않습니다.
첫 활성화와 이후 메시지를 모두 측정합니다. 로더가 작아도 내려받는 위젯 자체는 무거울 수 있습니다. 공급업체 코드의 동기 시작 작업이 길다면 축소된 통합이나 지원되는 단계별 초기화가 있는지 문의합니다. JavaScript 실행 시간 줄이기에서는 코드 다운로드를 줄이는 것과 실행 시점을 조정하는 것을 구분합니다.
동의 변경도 성능 시나리오로 다룹니다
선택적 권한 없음, 권한 허용, 이후 권한 변경의 세 경로 이상을 시험합니다. 배너 모습뿐 아니라 네트워크도 확인합니다. 배너가 정상처럼 보여도 테마의 다른 위치에서 서비스가 이미 초기화되었을 수 있습니다.
동의 제어와 로딩 제어는 관련 있지만 동일하지 않습니다. 사이트의 승인된 동의 정책과 공급업체의 지원 모드를 설정합니다. defer가 데이터 수집을 막는다고 해석하지 않습니다. 권한이 필요한 기능은 초기화 전에 조건을 검사합니다. 영상이나 채팅을 연다고 공급업체가 요구할 수 있는 모든 권한이 자동으로 부여되지는 않습니다.
동의를 수락하면 화면을 신속하게 갱신하고 모든 선택 기능을 한 동기 처리기에서 초기화하지 않습니다. 필요한 이벤트 순서를 유지하고 분석 지연으로 놓치는 측정도 문서화합니다. 데이터가 줄어드는 것은 의도적인 선택일 수 있지만, 근거 없이 수집 결과가 같다고 주장해서는 안 됩니다.
거절과 철회도 시험합니다. script 요소를 제거해도 이미 실행된 코드, 타이머, 요청은 되돌아가지 않습니다. 공급업체의 정리 및 동의 갱신 인터페이스를 사용합니다. 이는 구현 점검이며 모든 관할권의 규정을 충족한다는 선언은 아닙니다.
태그 관리자가 또 하나의 앱이 되지 않게 합니다
담당 팀과 컨테이너 설정을 내보내거나 검토합니다. 중복 분석 설치, 종료된 캠페인, 모든 페이지에 적용되는 광범위한 조건, 반복된 사용자 정의 HTML, 과도하게 실행되는 리스너를 찾습니다. 플랫폼 앱이 같은 이벤트를 이미 보내는지도 확인합니다.
트리거를 고치기 전에 이벤트 규약을 정합니다. 구매라면 이름, 전송 위치, 중복 제거 식별자를 합의하되 실제 주문 데이터를 문서에 넣지 않습니다. 공급업체 디버깅 도구와 네트워크 기록에서 확인합니다. 거래를 두 번 세는 빠른 페이지는 작업이 끝난 상태가 아닙니다.
서버 측 태깅은 일부 처리를 브라우저 밖으로 옮길 수 있지만 브라우저 수집기와 작업을 자동으로 제거하지 않습니다. 데이터와 운영 요건을 가진 별도의 아키텍처 변경으로 다룹니다. 서버 엔드포인트가 있다는 이유만으로 클라이언트 비용이 없다고 보지 말고 남은 코드를 측정합니다.
자체 호스팅과 공급업체 변경을 명시적으로 결정합니다
자체 호스팅은 연결과 캐시 동작을 바꿀 수 있지만 스크립트 연산량 자체를 줄이지는 않습니다. 코드를 복사하기 전에 라이선스, 업데이트 방식, 공급업체 요건을 확인합니다. 보안과 호환성 업데이트 담당자를 정합니다. 원격 API가 바뀌는데 파일만 고정하는 것은 지속 가능한 최적화가 아닙니다.
실험 서비스를 기다리며 주요 콘텐츠를 무기한 숨기지 않습니다. 담당자와 대체 동작을 정하고 지연과 중단을 시험합니다. 결제, 신원 확인, 부정 사용 방지 같은 중요한 통합은 책임 팀과 조율하고 전체 흐름을 테스트합니다. 목표는 점수가 녹색이 될 때까지 의존성을 삭제하는 것이 아니라 안정적인 기능입니다.
새 통합마다 담당자와 제거 절차를 지정합니다
다음 태그를 켜기 전에 성능 체크리스트에 항목을 만듭니다. 목적, 페이지, 활성화 규칙, 효과 근거, 시험 시나리오, 되돌리기 절차, 재검토 날짜를 기록합니다. 조직 내 사람이나 팀을 지정해야 나중에 사용하지 않는 통합을 정리할 수 있습니다.
측정한 기준과 업무 요구에 따라 전송량, 메인 스레드 작업, 영향받는 상호작용의 예산을 정합니다. 모든 사이트에 맞는 서드 파티 허용량은 없습니다. 배포 후 실제 사용자 결과를 템플릿과 동의 상태별로 점검합니다. 남은 원인이 이미지, 스타일, 자체 코드라면 페이지 속도 안내에서 관련 진단을 이어갑니다.
용도가 불분명하면서 비용이 큰 통합부터 시작합니다. 비용을 재현하고 여전히 필요한지 확인한 뒤 되돌릴 수 있는 방식으로 제거하거나 적용 범위를 줄입니다. 마지막으로 방문자가 원래 하려던 작업을 다시 테스트합니다.