커스텀 시작 스냅샷
JavaScript 명세에는 수학 함수에서부터 정규 표현식 엔진에 이르기까지 많은 내장 기능이 포함되어 있습니다. 새로 생성된 V8 컨텍스트는 시작 시 이러한 기능들을 사용할 수 있습니다. 이를 위해, 전역 객체(브라우저의 경우 window 객체 등)와 모든 내장 기능이 V8 힙에 설정되고 초기화되어야 합니다. 이 작업을 처음부터 수행하려면 시간이 꽤 걸립니다.
다행히도 V8은 작업을 가속화하기 위해 바로 사용할 수 있는 기술을 활용합니다. 마치 빠른 저녁 식사를 위해 냉동 피자를 해동하는 것처럼, 미리 준비된 스냅샷을 힙으로 역직렬화하여 초기 컨텍스트를 얻습니다. 일반적인 데스크탑 컴퓨터에서는 컨텍스트 생성 시간을 40ms에서 2ms 이하로 줄일 수 있습니다. 일반적인 모바일 전화에서는 270ms에서 10ms로 차이가 날 수 있습니다.
V8을 포함하는 Chrome 이외의 애플리케이션은 기본 JavaScript 이상의 기능을 필요로 할 수 있습니다. 많은 경우 시작 시 “실제” 애플리케이션이 실행되기 전에 추가 라이브러리 스크립트를 로딩합니다. 예를 들어, V8 기반의 간단한 TypeScript VM은 TypeScript 소스 코드를 실시간으로 JavaScript로 변환하기 위해 시작 시 TypeScript 컴파일러를 로드해야 합니다.
두 달 전 출시된 V8 v4.3 이후, 임베더는 스냅샷을 활용하여 이러한 초기화로 인해 소요되는 시작 시간을 건너뛸 수 있습니다. 테스트 케이스를 통해 이 API의 작동 방식을 확인할 수 있습니다.
스냅샷을 생성하려면 null로 종료된 C 문자열 형태의 포함된 스크립트를 사용하여 v8::V8::CreateSnapshotDataBlob
을 호출할 수 있습니다. 새 컨텍스트를 생성한 후, 이 스크립트가 컴파일되고 실행됩니다. 예를 들어, JavaScript에 기본 제공되는 기능 위에 함수를 정의하는 두 개의 커스텀 시작 스냅샷을 생성합니다.
이후 v8::Isolate::CreateParams
를 사용하여 새로 생성된 고립 환경을 구성하고 이를 통해 커스텀 시작 스냅샷으로부터 컨텍스트를 초기화할 수 있습니다. 해당 고립 환경에서 생성된 컨텍스트는 스냅샷을 만든 컨텍스트의 정확한 복사본입니다. 스냅샷에 정의된 함수는 다시 정의하지 않아도 사용할 수 있습니다.
그러나 중요한 제한 사항이 있습니다. 스냅샷은 V8의 힙만 캡처할 수 있습니다. 스냅샷을 생성할 때 V8이 외부와 상호작용하는 것은 허용되지 않습니다. 이러한 상호작용에는 다음이 포함됩니다:
- API 콜백 정의 및 호출 (예:
v8::FunctionTemplate
를 통해 생성된 함수) - 타입 배열 생성 (백업 저장소가 V8 외부에 할당될 수 있기 때문)
그리고 물론, Math.random
이나 Date.now
와 같은 소스에서 파생된 값들은 스냅샷이 생성된 후 고정됩니다. 더 이상 실제로 무작위거나 현재 시간을 반영하지 않습니다.
제한 사항에도 불구하고, 시작 스냅샷은 초기화 시간을 절약할 수 있는 훌륭한 방법입니다. 위 예에서 TypeScript 컴파일러를 로드하는 데 소요되는 시작 시간을 100ms 줄일 수 있습니다(일반적인 데스크탑 컴퓨터에서). 여러분이 커스텀 스냅샷을 어떻게 활용할지 기대됩니다!