홈으로 돌아가기

대용량 JSON 파싱 및 포맷팅 웹 성능 최적화 기법

웹 애플리케이션 환경에서 수 메가바이트(MB)에 달하는 대형 JSON API 페이로드를 다룰 때, 단순하게 JSON.parse()를 호출하거나 전체 데이터를 정렬 및 인덴트 처리하여 화면에 출력하려 하면 브라우저 렉(UI Freeze)이 심하게 발생합니다. 이는 자바스크립트의 싱글 스레드 특성 및 과도한 DOM 트리 노드 생성 때문입니다. 이번 글에서는 대용량 JSON 처리를 위한 Web Worker 멀티스레딩과 가상 스크롤(Virtual Scroll)을 이용한 렌더링 최적화 공식을 알아봅니다.

1. 대용량 JSON 연산 시 브라우저 렉의 원인

브라우저 렉이 발생하는 주요 원인은 크게 두 가지 병목 구간으로 요약됩니다.

  • 동기식 메인 스레드 점유 (Sync Blocking): 자바스크립트는 싱글 스레드 언어입니다. JSON.parse()JSON.stringify() 연산은 동기식(Synchronous)으로 동작하므로, 5MB짜리 JSON 파일을 파싱하는 동안 브라우저의 렌더 엔진은 멈추어 서서 화면 스크롤이나 클릭 이벤트를 일절 수신하지 못하고 얼어버립니다.
  • DOM 과부하 (DOM Thrashing): 파싱된 JSON을 트리 뷰나 예쁘게 정렬된 하이라이트 문자열로 표현하려면 수만 개의 `<span>` 및 `<div>` 노드를 화면에 한 번에 그려야 합니다. 브라우저가 이 엄청난 수의 노드를 레이아웃 계산(Reflow)하고 색칠(Repaint)하느라 완전히 과부하 상태에 빠지게 됩니다.

2. 최적화 해결책 1: Web Worker를 통한 연산 백그라운드 분리

사용자 인터페이스의 쾌적함을 유지하기 위한 첫 단계는 동기식 JSON 연산을 백그라운드 스레드로 격리하는 것입니다. **Web Worker**를 생성하여 무거운 문자열 변환 및 포맷팅 연산을 넘기고, 메인 스레드는 60FPS UI 반응을 유지하도록 설계합니다.

Web Worker 구동 흐름 예시

// 메인 스레드 코드 (app.js)
const worker = new Worker('json-worker.js');

worker.postMessage({ type: 'FORMAT', data: largeJsonString });
worker.onmessage = function(e) {
    const formattedData = e.data;
    // UI에 결과 반영
};

// 백그라운드 워커 코드 (json-worker.js)
self.onmessage = function(e) {
    if (e.data.type === 'FORMAT') {
        try {
            const parsed = JSON.parse(e.data.data);
            const formatted = JSON.stringify(parsed, null, 2);
            self.postMessage(formatted);
        } catch (err) {
            self.postMessage({ error: true });
        }
    }
};

3. 최적화 해결책 2: 가상 스크롤(Virtual Scroll)을 통한 DOM 최적화

포맷팅된 10만 행의 JSON 코드를 브라우저에 전부 로드하는 대신, 사용자의 현재 스크롤 뷰포트(Viewport)에 보이는 30~40행만 실시간으로 DOM에 렌더링하고 나머지는 가짜 스크롤바 높이로 대체하는 **가상 스크롤(DOM Virtualization)** 기술이 필요합니다. 이를 통해 메모리 점유율을 1/1000 수준으로 낮출 수 있습니다.

4. anyTools의 성능 아키텍처 의의

**anyTools**의 JSON 포매터 및 압축 도구는 위 두 가지 최적화 기술이 완전히 결합하여 동작합니다. 사용자가 기가바이트 단위의 API 로그나 JSON 원본을 복사·붙여넣기 하더라도 Web Worker 가동 및 청크(Chunk) 쪼개기 렌더링을 지원하여, 모바일 디바이스 환경에서도 키보드 멈춤이나 브라우저 다운 현상 없이 극도로 부드럽고 안전하게 포맷팅 결과를 확인할 수 있습니다.

When rendering large JSON payloads (in megabytes) on web clients, calling synchronous JSON.parse() and appending formatted HTML markup instantly freezes the user interface. This is caused by JavaScript's single-threaded nature and DOM node overhead. In this post, we discuss how to eliminate UI lag using Web Worker multi-threading and Virtual Scrolling DOM optimization.

1. Causes of Browser Lag Under Large JSON Payloads

The lag stems from two distinct runtime bottlenecks:

  • Synchronous Blocking: JavaScript runs on a single main thread. Heavy parsing calls block this thread, meaning the browser cannot handle clicks, animations, or scroll gestures until parsing finishes.
  • DOM Thrashing: Generating code highlight views for a large JSON requires inserting thousands of nested <span> tags. The rendering engine becomes exhausted recalculating layout (Reflow) and styling (Repaint).

2. Solution 1: Offloading Operations to Web Workers

To preserve UI responsiveness, we offload heavy string manipulation and formatting to a **Web Worker**. This background thread performs calculations without affecting the main UI thread:

Web Worker Code Pattern

// Main thread (app.js)
const worker = new Worker('json-worker.js');

worker.postMessage({ type: 'FORMAT', data: largeJsonString });
worker.onmessage = function(e) {
    const formattedData = e.data;
    // Render result to the viewport
};

// Web Worker (json-worker.js)
self.onmessage = function(e) {
    if (e.data.type === 'FORMAT') {
        try {
            const parsed = JSON.parse(e.data.data);
            const formatted = JSON.stringify(parsed, null, 2);
            self.postMessage(formatted);
        } catch (err) {
            self.postMessage({ error: true });
        }
    }
};

3. Solution 2: DOM Virtualization (Virtual Scroll)

Instead of creating DOM elements for a 10,000-line JSON, **Virtual Scrolling** renders only the 30-40 lines visible in the browser viewport. The scrollbar's scale is simulated using dummy container heights, reducing DOM memory footprint significantly.

4. anyTools Architecture Implementation

The JSON Formatter in **anyTools** combines Web Worker operations and lazy rendering strategies. Even on low-spec mobile browsers, users can format massive JSON structures smoothly without tab crashes or input delays.