Chrome 13에서는 구조화된 클론이라는 알고리즘을 사용하여 웹 워커 간에 ArrayBuffer
를 전송하는 기능을 도입했습니다. 이를 통해 postMessage()
API는 문자열뿐만 아니라 File
, Blob
, ArrayBuffer
, JSON 객체와 같은 복잡한 유형의 메시지를 수락할 수 있게 되었습니다. 구조화된 클론은 이후 버전의 Firefox에서도 지원됩니다.
빠를수록 좋습니다
구조화된 클론은 유용하지만 여전히 복사 작업입니다. 32MB ArrayBuffer
를 Worker에 전달하는 오버헤드는 수백 밀리초가 될 수 있습니다.
새 버전의 브라우저에는 전송 가능한 객체라는 메시지 전달을 위한 대규모 성능 개선사항이 포함되어 있습니다.
전송 가능한 객체를 사용하면 데이터가 한 컨텍스트에서 다른 컨텍스트로 전송됩니다. 제로 복사 방식이므로 Worker로 데이터를 전송하는 성능이 크게 개선됩니다. C/C++ 환경에 익숙하다면 참조 전달이라고 생각하면 됩니다. 그러나 참조 전달과 달리 호출 컨텍스트의 '버전'은 새 컨텍스트로 전송된 후에는 더 이상 사용할 수 없습니다. 예를 들어 기본 앱에서 Worker로 ArrayBuffer
를 전송하면 원래 ArrayBuffer
가 삭제되어 더 이상 사용할 수 없게 됩니다. 내용이 Worker 컨텍스트로 전송됩니다.
전송 가능한 항목을 사용하려면 전송 가능한 객체를 지원하는 새 버전의 postMessage()
가 있습니다.
worker.postMessage(arrayBuffer, [transferableList]);
window.postMessage(arrayBuffer, targetOrigin, [transferableList]);
작업자 케이스의 경우 첫 번째 인수는 ArrayBuffer
메시지입니다. 두 번째 인수는 전송해야 하는 항목의 목록입니다. 이 예에서는 전송 가능한 목록에 arrayBuffer
를 지정합니다.
벤치마크 데모
전송 가능한 항목의 성능 향상을 확인할 수 있도록 데모를 준비했습니다.
이 데모에서는 postMessage()
를 사용하여 32MB ArrayBuffer
를 워커로 전송하고 다시 가져옵니다. 브라우저가 전송 가능한 항목을 지원하지 않으면 샘플은 구조화된 클론으로 대체됩니다. 여러 브라우저에서 평균 5회 실행한 결과는 다음과 같습니다.
MacBook Pro/10.6.8/2.53GHz/Intel Core 2 Duo에서는 구조화된 클론을 사용하는 FF가 가장 빠르게 실행되었습니다. 32MB ArrayBuffer
를 작업자에게 전송하고 기본 스레드에 다시 게시하는 데 평균 302ms가 걸렸습니다 (RRT - 왕복 시간). 전송 가능한 항목과 비교하면 동일한 테스트에 6.6ms가 걸렸습니다. 성능이 크게 향상되었습니다.
이러한 속도를 사용하면 대규모 WebGL 텍스처/메시를 Worker와 기본 앱 간에 원활하게 전달할 수 있습니다.
기능 감지
이 경우 특징 감지가 약간 까다롭습니다. 작업자에게 작은 ArrayBuffer
를 보내는 것이 좋습니다. 버퍼가 전송되고 복사되지 않으면 .byteLength
가 0으로 전환됩니다.
var ab = new ArrayBuffer(1);
worker.postMessage(ab, [ab]);
if (ab.byteLength) {
alert('Transferables are not supported in your browser!');
} else {
// Transferables are supported.
}
지원: 현재 Chrome 17 이상, Firefox, Opera, Safari, IE10 이상
업데이트 (2011-12-13): webkitPostMessage()
서명이 창과 작업자에서 다르다는 것을 보여주는 코드 스니펫을 업데이트했습니다.
업데이트됨 (2016-11-03): 공급업체 접두사가 삭제되고 코드 스니펫이 업데이트되었습니다.