오프스크린 캔버스—웹 작업자로 캔버스 작업 속도를 높이세요.

Tim Dresser

캔버스는 널리 사용되는 화면에 모든 종류의 그래픽을 그리는 것과 WebGL의 세계로의 진입점이 됩니다. 도형이나 이미지를 그리고 애니메이션을 실행하거나 동영상 콘텐츠를 표시 및 처리하는 데 사용할 수 있습니다. 주로 미디어가 풍부한 웹 애플리케이션과 멋진 사용자 경험을 만드는 데 사용되기도 합니다. 있습니다.

스크립트를 작성할 수 있습니다. 즉, 캔버스에 그려진 콘텐츠를 프로그래매틱 방식으로 만들 수 있습니다. 예를 들어 JavaScript에서 가능합니다. 이렇게 하면 캔버스의 유연성이 높아집니다.

동시에 최신 웹사이트에서 스크립트 실행은 사용자 반응의 소스 문제를 확인합니다. 캔버스 로직과 렌더링은 사용자 상호작용과 동일한 스레드에서 발생하므로 애니메이션과 관련된 (때로는 과도한) 계산이 앱의 실제 화면 인지 성능을 측정할 수 있습니다

다행히 OffscreenCanvas는 대응 수단입니다

브라우저 지원

  • 69
  • 79
  • 105
  • 16.4

소스

이전에는 캔버스 그리기 기능이 <canvas> 요소에 연결되었습니다. 즉, DOM에 직접 종속되어 있었습니다. OffscreenCanvas는 이름에서 알 수 있듯이 DOM과 Canvas API를 화면 밖으로 이동하여 분리합니다.

이러한 분리 덕분에 OffscreenCanvas 렌더링은 DOM에서 완전히 분리되고 동기화 기능이 없기 때문에 일반 캔버스에 비해 속도가 약간 향상됩니다. 있습니다.

그러나 더 많은 것은 DOM을 사용할 수 있습니다. 이를 통해 모든 종류의 흥미로운 사용 사례를 지원할 수 있습니다.

작업자에서 OffscreenCanvas 사용

작업자 는 웹 버전의 스레드로, 이를 사용하면 백그라운드에서 작업을 실행할 수 있습니다.

일부 스크립팅을 worker로 이동하면 앱에서 사용자에게 중요한 작업을 수행하기 위한 헤드룸을 더 많이 확보할 수 있습니다. 기본 스레드에 있습니다. OffscreenCanvas가 없으면 작업자에서 캔버스 API를 사용할 방법이 없었습니다. DOM을 사용할 수 없습니다.

OffscreenCanvas는 DOM에 의존하지 않으므로 사용할 수 있습니다. 다음 예에서는 OffscreenCanvas를 사용합니다. 를 사용하여 작업자의 그라데이션 색상을 계산합니다.

// file: worker.js
function getGradientColor(percent) {
  const canvas = new OffscreenCanvas(100, 1);
  const ctx = canvas.getContext('2d');
  const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
  gradient.addColorStop(0, 'red');
  gradient.addColorStop(1, 'blue');
  ctx.fillStyle = gradient;
  ctx.fillRect(0, 0, ctx.canvas.width, 1);
  const imgd = ctx.getImageData(0, 0, ctx.canvas.width, 1);
  const colors = imgd.data.slice(percent * 4, percent * 4 + 4);
  return `rgba(${colors[0]}, ${colors[1]}, ${colors[2]}, ${colors[3]})`;
}

getGradientColor(40);  // rgba(152, 0, 104, 255 )

기본 스레드 차단 해제

무거운 계산을 작업자로 이동하면 상당한 리소스가 필요합니다. transferControlToOffscreen 사용 메서드를 사용하여 일반 캔버스를 OffscreenCanvas 인스턴스에 미러링할 수 있습니다. 작업이 적용됨 OffscreenCanvas가 소스 캔버스에서 자동으로 렌더링됩니다.

const offscreen = document.querySelector('canvas').transferControlToOffscreen();
const worker = new Worker('myworkerurl.js');
worker.postMessage({canvas: offscreen}, [offscreen]);

다음 예에서는 색상 테마가 변경될 때 많은 계산이 이루어집니다. 몇 밀리초가 걸릴 수 있습니다. 기본 스레드에서 애니메이션을 실행하도록 선택할 수 있습니다. 또는 worker의 내부에 저장됩니다. 기본 스레드의 경우, 과도한 스레드가 제거될 때는 버튼과 상호작용할 수 없습니다. 스레드가 차단되었음을 알립니다. 작업자의 경우 UI 응답성.

<ph type="x-smartling-placeholder">
</ph>
데모

다른 방식으로도 작동합니다. 사용량이 많은 기본 스레드는 실행되는 애니메이션에 영향을 주지 않습니다. 작업자라고 합니다 이 기능을 사용하면 시각적인 버벅거림을 피하고 부드러운 애니메이션을 보장할 수 있습니다. 기본 스레드 트래픽에도 불구하고 작동합니다.

<ph type="x-smartling-placeholder">
</ph>
데모

일반 캔버스의 경우 기본 스레드가 인위적으로 과로되면 애니메이션이 중지됩니다. 작업자 기반의 OffscreenCanvas가 원활하게 재생되는 동안

OffscreenCanvas API는 일반적으로 일반 캔버스 요소와 호환되므로 이를 점진적으로 개선하며 업계 최고의 그래픽 라이브러리 중 일부와 함께 사용합니다.

예를 들어 특성을 감지할 수 있으며, 가능한 경우 다음을 지정하여 Three.js와 함께 사용할 수 있습니다. 캔버스 옵션을 사용할 수 있습니다.

const canvasEl = document.querySelector('canvas');
const canvas =
  'OffscreenCanvas' in window
    ? canvasEl.transferControlToOffscreen()
    : canvasEl;
canvas.style = {width: 0, height: 0};
const renderer = new THREE.WebGLRenderer({canvas: canvas});

여기서 한 가지 알아야 할 점은 Three.js가 캔버스에 style.widthstyle.height 속성이 있을 것으로 예상한다는 것입니다. OffscreenCanvas는 DOM에서 완전히 분리되었으므로 보유하고 있지 않으므로 직접 제공해야 합니다. 스텁 처리하거나 이러한 값을 원본에 연결하는 로직을 제공하여 캔버스 크기입니다.

다음은 작업자에서 기본 Three.js 애니메이션을 실행하는 방법을 보여줍니다.

<ph type="x-smartling-placeholder">
</ph>
데모

DOM 관련 API 중 일부는 작업자에서 바로 사용할 수 없다는 점에 유의하세요. 텍스처와 같은 고급 Three.js 기능을 사용하고 싶은 경우 추가 해결 방법이 필요할 수 있습니다. 새로운 유형의 실험을 시작하는 방법에 대한 아이디어를 얻으려면 Google I/O 2017 동영상을 참고하세요.

캔버스의 그래픽 기능을 많이 사용하는 경우 OffscreenCanvas는 앱 성능에 영향을 줄 수 있습니다. 작업자가 캔버스 렌더링 컨텍스트를 사용할 수 있게 됨 다중 코어 시스템을 더 잘 활용하는데 도움이 될 수 있습니다.

추가 리소스