Gerenciamento de renderização

O sistema de gerenciamento de renderização informa ao renderizador quando renderizar novamente os blocos. Ele garante que, quando um bloco é modificado (por exemplo, valores de campo são definidos ou entradas são adicionadas), a forma do bloco é atualizada para corresponder.

Quando cuidar

Você precisará interagir com esse sistema se:

  • Adição de métodos ao Blockly que modificam a forma do bloco.
  • Adição de métodos ao Blockly que dependem de informações atualizadas de tamanho ou posicionamento sobre um bloco

Como funciona

  1. Fila automaticamente. Sempre que um bloco é modificado, o Blockly "coloca em fila" uma renderização para esse bloco. Alguns exemplos de modificações que enfileiram uma renderização são:

    • Como definir o valor de um campo
    • Adicionar ou remover uma entrada
    • Conectar ou desconectar um bloco filho
  2. Criar um conjunto. Quando um bloco é colocado em fila, o sistema de gerenciamento de renderização adiciona o bloco e todos os blocos pai a um conjunto de blocos que precisam ser renderizados novamente.

  3. Solicite um callback. Em seguida, o sistema de gerenciamento de renderização solicita um callback usando requestAnimationFrame. Esse callback é chamado pelo navegador à direita antes que o frame atual seja desenhado.

  4. Renderize novamente o conjunto (como uma árvore). Quando o callback requestAnimationFrame é chamado, o sistema de gerenciamento de renderização renderiza todos os blocos do conjunto, de blocos de folha a blocos raiz. Isso garante que os blocos filhos tenham informações de tamanho precisas antes que os blocos pais sejam renderizados. Assim, os blocos pais podem se estender em torno dos filhos.

Por que funciona Como funciona

A espera para renderizar os blocos novamente até que o frame atual seja desenhado permite que o sistema de gerenciamento de renderização elimine a duplicação de solicitações. Se os blocos fossem sempre renderizados imediatamente, o mesmo bloco poderia ser desnecessariamente renderizado várias vezes seguidas. Em vez disso, as solicitações de renderização são agrupadas e cada bloco alterado é renderizado apenas uma vez no final do frame, depois que o estado é finalizado. A eliminação de duplicações de operações de renderização torna o Blockly muito mais eficiente.

Por exemplo, ao inserir um bloco entre duas outras filas, 11 renderizações, mas apenas 3 realmente ocorrem (um para cada bloco). Isso representa um aumento de 3,6x no desempenho.

Como usar

Geralmente, não é necessário se preocupar com o sistema de gerenciamento de renderização, porque ele funciona automaticamente quando você modifica um bloco. Mas há alguns casos em que você precisa interagir diretamente com ele.

Renderizações de fila

Se você estiver adicionando um novo método ao Blockly que atualiza a forma de um bloco, é necessário chamar BlockSvg.prototype.queueRender para enfileirar a renderização do bloco.

Aguardar a conclusão das renderizações

Se você estiver adicionando um novo método ao Blockly que exige a atualização das informações de tamanho ou posicionamento de um bloco, aguarde a promessa renderManagement.finishQueuedRenders(). Essa promessa é resolvida após a conclusão de qualquer renderização na fila ou imediatamente se não houver nenhum renderizador em fila.

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

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

Acionar renderizações em fila imediatamente

Se você está adicionando um novo método ao Blockly que exige a atualização das informações de tamanho ou posicionamento de um bloco e não é possível esperar até o próximo frame para que qualquer renderização seja concluída, chame renderManagement.triggerQueuedRenders para forçar a execução imediata de qualquer renderização em fila.

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

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

Em geral, não convém fazer isso porque o desempenho é menor. Ela só é necessária nos casos em que um atraso causa uma experiência do usuário ruim. Por exemplo, os marcadores de inserção precisam de informações de posicionamento, e é importante que os marcadores de inserção forneçam feedback imediato aos usuários para acionar uma renderização imediata.

Há também alguns locais em que ele aciona renderizações imediatas por motivos de compatibilidade com versões anteriores. Eles serão removidos na v11.