브라우저에서 파일을 로컬로 처리하는 원리
아무것도 업로드되지 않는다면, 실제로 무엇이 어디서 작업을 하는 건가요?
여기서 말하는 로컬의 뜻
흔한 온라인 변환 서비스는 업로드 엔드포인트가 있는 웹사이트입니다. 파일은 여러분이 통제하지 않는 컴퓨터로 전송되어 거기서 처리되고, 얼마간 저장되었다가, 다운로드로 되돌아옵니다. 로컬 처리는 이 문장의 가운데를 들어냅니다. 파일을 읽는 코드는 이미 열려 있는 브라우저 탭 안에서 여러분의 프로세서로 실행되고, 결과는 여러분의 디스크에 다시 쓰입니다.
사이트 자체는 여전히 네트워크로 내려받습니다. HTML, 스타일시트, 스크립트, WebAssembly 모듈은 여느 웹 페이지와 마찬가지로 서버에서 도착합니다. 차이는 방향입니다. 프로그램 코드는 내려오고, 여러분의 파일은 올라가지 않습니다.
브라우저에는 이미 부품이 들어 있습니다
| 기능 | 제공하는 것 |
|---|---|
| File 및 Blob API | 양식 제출 없이, 사용자가 선택하거나 끌어다 놓은 파일의 바이트 읽기 |
| Web Worker | 무거운 작업을 백그라운드 스레드에서 실행해 인터페이스의 반응성 유지 |
| WebAssembly | 컴파일된 C, C++, Rust 코덱 라이브러리를 네이티브에 가까운 속도로 실행 |
| Canvas와 OffscreenCanvas | 이미지 디코딩, 그리기, 크기 조정, 재인코딩 |
| WebCodecs | 브라우저 자체의 하드웨어 가속 비디오 인코더와 디코더 사용 |
| WebGPU | 그래픽 프로세서에서 모델 추론과 병렬 픽셀 연산 수행 |
| File System Access | 지원되는 환경에서, 사용자가 고른 위치에 결과를 곧바로 기록 |
여기에 특별한 것은 없습니다. 탭 안에서 스프레드시트와 디자인 도구, 게임을 돌리는 것과 같은 플랫폼입니다. 유별난 결정은 단 하나, 여기에 서버를 붙이지 않기로 한 것뿐입니다.
파일이 거치는 경로
- 파일을 선택합니다. 브라우저는 페이지에 그 파일의 핸들을 넘깁니다. 사본이 아니라 참조입니다.
- 페이지는 확장자를 믿는 대신 앞부분 바이트를 읽어 시그니처로 실제 파일 형식을 판별합니다.
- 작업에 필요한 메모리를 추정하고, 그것이 기기가 안전하게 내줄 수 있는 양을 넘으면 작업을 거부하거나 대기열에 넣습니다.
- 바이트는 Web Worker로 전달됩니다. ArrayBuffer 전달은 복사가 아니라 소유권 이전이므로, 큰 파일이 메모리에 두 번 존재하지 않습니다.
- 워커 안에서는 WebAssembly 코덱이나 플랫폼 API가 실제 디코딩과 인코딩을 수행합니다.
- 결과는 바이트로 돌아와 Blob으로 감싸이고, 다운로드로 제공되거나 여러분이 고른 위치에 기록됩니다.
- 그 Blob의 임시 URL은 해제되고 버퍼도 반환됩니다.
판을 바꾼 것이 WebAssembly인 이유
이미지와 비디오 코덱은 수십 년에 걸쳐 정교하게 최적화된 C 코드입니다. 이를 JavaScript로 다시 쓰는 것은 애초에 현실적이지 않았습니다. WebAssembly는 브라우저가 샌드박스 안에서 네이티브 코드에 가까운 속도로 실행하는 이식 가능한 이진 명령 포맷이고, 덕분에 기존 라이브러리를 그대로 컴파일해 브라우저로 보낼 수 있습니다.
샌드박스는 속도만큼이나 중요합니다. WebAssembly 모듈에는 파일 시스템이나 네트워크, 다른 탭에 대한 기본 접근 권한이 없습니다. 페이지가 넘겨준 메모리만 볼 뿐 그 밖에는 아무것도 보지 못합니다. 악의적이거나 그저 버그가 있는 코덱이 제멋대로 돌아다니며 주어지지 않은 것을 읽을 수는 없습니다.
여전히 네트워크를 쓰는 것, 그리고 그것이 여러분의 파일이 아닌 이유
네트워크로 도착하는 것은 세 가지입니다. 페이지 자체, 여러분이 연 도구의 엔진, 그리고 배경 제거 기능의 경우에는 모델 가중치입니다. 셋 다 FileSlimmer의 정적 자산이며, 여러분의 바이트를 단 하나도 읽기 전에 FileSlimmer 자신의 오리진에서 내려받습니다. 이들은 다운로드이고, 캐시할 수 있으며, 한 번 쓰고 나면 네트워크 없이 브라우저 자체의 캐시에서 제공될 수 있습니다.
그 지점 이후의 모든 것은 로컬에서 일어납니다. 엔진은 파일 바이트를 오직 페이지가 보내는 postMessage로만 받습니다. 무언가를 보낼 URL은 애초에 주어지지 않으며, 설령 어떤 코드가 시도하더라도 콘텐츠 보안 정책이 페이지가 연결할 수 있는 곳을 제한합니다.
장단점을 있는 그대로
| 고려 사항 | 브라우저에서 | 서버에서 |
|---|---|---|
| 파일이 가는 곳 | 아무 데도 가지 않음 | 여러분이 통제하지 않는 컴퓨터 |
| 속도 | 기기가 낼 수 있는 만큼 | 운영자가 돈을 낸 만큼 |
| 아주 큰 파일 | 브라우저 메모리에 제한됨 | 운영자가 정한 한도에 제한됨 |
| 오프라인 작동 | 엔진이 캐시된 뒤에는 가능 | 불가능 |
| 특이한 포맷 | WebAssembly로 컴파일되는 것만 | 운영자가 설치한 것은 무엇이든 |
| 파일 1000개 일괄 처리 | 기기의 제약을 받음 | 대체로 더 적합함 |
로컬 처리가 언제나 더 나은 것은 아닙니다. 파일이 사적일 때, 기기의 성능이 충분할 때, 작업이 메모리에 들어갈 때 더 낫습니다. 컴퓨터 한 대가 감당할 수 있는 양을 훨씬 넘어서는 처리가 필요할 때는 서버가 낫습니다. 어느 한쪽이 어디서나 이긴다고 우기는 것보다, 지금 자신이 어느 상황에 있는지 분명히 아는 편이 더 쓸모 있습니다.
이 글이 주장하지 않는 것
이것은 이 애플리케이션이 무엇을 하는지에 관한 진술입니다. 여러분이 여는 어떤 페이지의 내용이든 읽을 수 있는 브라우저 확장 프로그램에 관한 주장도, 여러분이 다루는 어떤 파일이든 들여다볼 수 있는 운영체제에 관한 주장도, 여러분이 어떤 사이트를 방문했는지 알 수 있는 통신 사업자에 관한 주장도 아닙니다. 이들은 어떤 웹사이트도 손댈 수 없는 영역이며, 그렇지 않다고 말하는 도구는 자기 주장을 부풀리고 있는 것입니다.
이 주장은 좁고 검증 가능합니다. 여러분이 선택한 파일은 이 브라우저 안에서 로컬로 처리되며 FileSlimmer가 업로드하지 않습니다. 다음 가이드에서는 이를 믿는 대신 직접 검증하는 방법을 설명합니다.
관련 도구
출처
- W3C — File API
- W3C — WebAssembly Core Specification
- WHATWG — HTML Standard, Web Workers
- W3C — WebCodecs