レンダリング管理

レンダリング管理システムは、ブロックを再レンダリングするタイミングをレンダラに指示します。ブロックが変更されると(フィールド値が設定された場合など)、 ブロックの形状がそれに合わせて更新されます。

対応が必要なケース

次の場合は、このシステムを操作する必要があります。

  • ブロックの形状を変更するメソッドを Blockly に追加します。
  • ブロックに関する更新されたサイズ情報または配置情報に依存するメソッドを Blockly に追加しました。

仕組み

  1. 自動的にキューに入れる。ブロックが変更されるたびに、Blockly はキューに入れられます。 ブロックのレンダリングを行います。レンダリングをキューに入れる変更の例を次に示します。

    • フィールドの値の設定
    • 入力の追加または削除
    • 子ブロックの接続または接続解除
  2. セットを作成します。ブロックがキューに追加されると、レンダリング管理システムは その親ブロックをすべて、追加する必要のあるブロックのセットに 再レンダリングされます

  3. コールバックをリクエストします。レンダリング管理システムは、requestAnimationFrame を使用してコールバックをリクエストします。このコールバックは、 現在のフレームが描画される前ににブラウザによって呼び出されます。

  4. セットを(ツリーとして)再レンダリングします。requestAnimationFrame コールバックが呼び出されると、レンダリング管理システムは、リーフブロックからルートブロックまで、セット内のすべてのブロックをレンダリングします。これにより、子ブロックに 親ブロックがレンダリングされる前に正確なサイズ情報が提供されるため、 親ブロックは子の周囲を拡大できます。

仕組み

現在のフレームが描画される直前までブロックの再レンダリングを待機すると、レンダリング管理システムはレンダリング リクエストの重複を排除できます。ブロックが 常に即座にレンダリングされるため、同じブロックが不必要にレンダリングされる 連続して複数回出現します代わりにレンダリング リクエストはバッチ処理され、 変更されたブロックは、状態が変化した後、フレームの終了時に 1 回だけ描画されます。 ファイナライズされます。レンダリング オペレーションの重複除去により、Blockly の効率が大幅に向上します。

たとえば、他の 2 つのキューの間に 1 つのブロックを挿入すると、キュー 11 はレンダリングされますが、 実際には 3 つ(ブロックごとに 1 つ)が発生します。3.6 倍のパフォーマンス向上です。

活用方法

通常はレンダリング管理システムを気にする必要はありません ブロックを変更すると自動的に機能します。一部のケースで 直接操作する必要があります。

レンダリングをキューに追加

ブロックのシェイプを更新する新しいメソッドを ブロックするには、BlockSvg.prototype.queueRender を呼び出してキューに入れ、 ブロックします。

レンダリングが完了するまで待つ

Blockly に新しいメソッドを追加し、サイズの更新や そのブロックのポジショニングに関する情報が renderManagement.finishQueuedRenders() Promise。この Promise は キューに入れられたレンダリングはすぐに完了するか、キュー内のレンダリングがない場合はすぐに完了します。

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 で削除される予定です。