렌더링 관리

렌더 관리 시스템은 블록을 다시 렌더링할 시기를 렌더러에 알립니다. 블록이 수정될 때 (예: 필드 값이 설정되거나 입력이 추가됨) 블록의 모양이 일치하도록 업데이트됩니다.

중요한 경우

다음과 같은 경우 이 시스템과 상호작용해야 합니다.

  • Blockly에 블록의 모양을 수정하는 메서드를 추가합니다.
  • 블록에 관한 업데이트된 크기나 위치 정보에 의존하는 메서드를 Blockly에 추가합니다.

사용 방법

  1. 자동으로 대기열에 추가. 블록이 수정될 때마다 Blockly는 해당 블록의 렌더를 '큐에 추가'합니다. 렌더를 큐에 추가하는 수정의 예는 다음과 같습니다.

    • 필드 값 설정
    • 입력 추가 또는 삭제
    • 하위 블록 연결 또는 연결 해제
  2. 세트를 만듭니다. 블록이 큐에 추가되면 렌더링 관리 시스템은 블록과 모든 상위 블록을 다시 렌더링해야 하는 블록 세트에 추가합니다.

  3. 콜백을 요청합니다. 그러면 렌더링 관리 시스템이 requestAnimationFrame를 사용하여 콜백을 요청합니다. 이 콜백은 현재 프레임이 그려지기 직전에 브라우저에서 호출합니다.

  4. 세트를 나무로 다시 렌더링합니다. requestAnimationFrame 콜백이 호출되면 렌더링 관리 시스템은 세트의 모든 블록을 리프 블록에서 루트 블록으로 렌더링합니다. 이렇게 하면 상위 블록이 렌더링되기 전에 하위 블록이 정확한 크기 정보를 갖게 되므로 상위 블록이 하위 요소 주위로 확장될 수 있습니다.

작동 이유

현재 프레임이 그려지기 직전까지 블록 재렌더링을 기다리면 렌더링 관리 시스템이 렌더링 요청을 중복 삭제할 수 있습니다. 블록이 항상 즉시 렌더링된다면 같은 블록이 불필요하게 연속으로 여러 번 렌더링될 수 있습니다. 대신 렌더링 요청이 일괄 처리되고, 변경된 각 블록은 상태가 확정된 후 프레임 끝에 한 번만 그려집니다. 렌더링 작업을 중복 제거하면 Blockly가 훨씬 더 효율적입니다.

예를 들어, 다른 두 개의 대기열에 하나의 블록을 삽입하면 11이 렌더링되지만 실제로는 3개만 발생합니다 (블록마다 하나씩). 성능이 3.6배 향상되었습니다.

사용 방법

일반적으로 렌더링 관리 시스템은 블록을 수정할 때 자동으로 작동하므로 신경 쓸 필요가 없습니다. 그러나 직접 상호작용해야 하는 몇 가지 경우가 있습니다.

큐 렌더링

블록의 모양을 업데이트해야 하는 새 메서드를 Blockly에 추가하는 경우 BlockSvg.prototype.queueRender를 호출하여 블록을 렌더링하도록 큐에 추가해야 합니다.

렌더가 완료될 때까지 대기

블록에 관한 크기 조정 또는 배치 정보를 업데이트해야 하는 새 메서드를 Blockly에 추가하려면 renderManagement.finishQueuedRenders() 프로미스를 기다려야 합니다. 이 프로미스는 큐에 추가된 렌더가 완료된 후 또는 큐에 추가된 렌더가 없는 경우 즉시 해결됩니다.

import * as renderManagement from './renderManagement.js';

function async myNewMethod() {
  block.somethingThatModifiesTheShape();
  // Await the promise.
  await renderManagement.finishQueuedRenders();
  myThingThatReliesOnPositioningInfo();
}

큐에 추가된 렌더 즉시 트리거

블록에 관한 크기 조정 또는 배치 정보를 업데이트해야 하는 새 메서드를 Blockly에 추가하려고 하며 그리고 렌더의 다음 프레임이 완료될 때까지 기다릴 수 없는 경우 renderManagement.triggerQueuedRenders를 호출하여 큐에 추가된 렌더가 즉시 발생하도록 강제할 수 있습니다.

import * as renderManagement from './renderManagement.js';

function async myNewMethod() {
  block.somethingThatModifiesTheShape();
  // Trigger an immediate render.
  renderManagement.triggerQueuedRenders();
  myThingThatReliesOnPositioningInfo();
}

일반적으로 이 방법은 성능이 떨어질 수 있으므로 권장하지 않습니다. 지연으로 인해 사용자 환경이 저하되는 경우에만 필요합니다. 예를 들어 삽입 마커에는 위치 정보가 필요하며 삽입 마커는 사용자에게 즉각적인 피드백을 제공하므로 즉시 렌더링을 트리거해야 합니다.

이전 버전과의 호환성을 위해 즉시 렌더링을 트리거하는 몇 가지 핵심 위치도 있습니다. 이들 기능은 v11에서 제거될 예정입니다.