
O SceneGraph é o coração do desenvolvimento moderno de aplicativos para Roku. Mais do que uma simples camada visual, ele define como a UI é estruturada, como os eventos fluem e como o BrightScript se conecta ao comportamento real do app. Quem domina SceneGraph deixa de “brigar com a plataforma” e passa a construir apps estáveis, performáticos e aprovados com mais facilidade.
Este artigo é um guia humano, profissional e aprofundado, focado em uso real, não em teoria solta. Aqui você vai entender como XML e BrightScript trabalham juntos, quais são os padrões corretos e por que SceneGraph é decisivo para apps VOD, FAST e projetos de streaming em escala.
O que é SceneGraph (além da definição oficial)
Tecnicamente, SceneGraph é um framework de UI baseado em nós (nodes).
Na prática, ele é:
- uma árvore de componentes visuais
- um sistema orientado a eventos
- um contrato claro entre layout (XML) e lógica (BrightScript)
SceneGraph foi criado para resolver problemas clássicos de TV:
- hardware limitado
- foco via controle remoto
- playback contínuo
- estabilidade acima de tudo
Por isso ele é declarativo, previsível e restritivo de propósito.
A separação fundamental: XML ≠ BrightScript
Se você entender apenas uma coisa sobre SceneGraph, que seja esta:
XML define “o que existe”
BrightScript define “o que acontece”
Essa separação é o que torna os apps Roku:
- mais estáveis
- mais fáceis de manter
- menos propensos a crash em produção
Papel do XML (estrutura e visual)
No XML você define:
- hierarquia de nós
- componentes visuais (Label, Poster, MarkupGrid, Video)
- layout e posicionamento
- IDs e campos observáveis
O XML não decide lógica, apenas declara a cena.
Exemplo real: Scene XML bem definido
<component name="HomeScene" extends="Scene">
<children>
<MarkupGrid
id="contentGrid"
itemSize="[400,225]"
numRows="2"
translation="[60,120]" />
</children>
</component>
Esse XML já responde perguntas importantes:
- existe uma cena principal
- existe um grid
- o foco será nesse grid
- o layout é previsível
Nada de lógica aqui — e isso é bom.
Papel do BrightScript no SceneGraph
O BrightScript entra para:
- carregar dados
- reagir a eventos
- observar mudanças de estado
- controlar navegação
- iniciar playback
- tratar erros
Ele nunca deveria redesenhar a UI, apenas alterar estado e conteúdo.
Exemplo prático: Scene BrightScript conectado ao XML
sub init()
m.grid = m.top.findNode("contentGrid")
m.grid.observeField("itemSelected", "onItemSelected")
loadCatalog()
end sub
sub loadCatalog()
items = ApiService_GetCatalog()
if items = invalid then return
m.grid.content = buildContentNode(items)
end sub
Aqui vemos o padrão correto:
init()conecta a lógica à UIobserveFieldescuta eventos- dados entram como
ContentNode - nenhuma manipulação visual direta
SceneGraph é orientado a eventos (não a comandos)
Um erro comum de quem vem do web ou mobile é tentar “mandar” na UI.
No SceneGraph:
- você observa
- você reage
- você altera estado
- a UI se atualiza sozinha
Exemplo clássico: seleção de item
sub onItemSelected()
index = m.grid.itemSelected
selectedItem = m.grid.content.getChild(index)
navigateToPlayer(selectedItem)
end sub
O evento acontece → o app reage.
Esse modelo reduz bugs e simplifica raciocínio.
A árvore de nós (Node Tree): como pensar corretamente
Todo app SceneGraph é uma árvore viva.
- Scene (raiz)
- Containers
- Grids
- Posters
- Labels
- Video
- Overlays
Boas práticas reais:
- reutilizar nós sempre que possível
- evitar criar/destruir nós em excesso
- manter a árvore previsível
- não “inflar” a cena sem necessidade
Performance em Roku não é sobre GPU, é sobre organização da árvore.
SceneGraph + Streaming (VOD e FAST)
VOD
- usuário escolhe conteúdo
- grid → player
- pausa, resume, próximo episódio
FAST (TV linear)
- fluxo contínuo
- EPG
- troca de programas
- ads frequentes
- tolerância a falhas
SceneGraph funciona bem nos dois, desde que:
- a lógica de player seja isolada
- a cena principal não fique “pesada”
- estados sejam observados corretamente
Integração com Player: estados são obrigatórios
O maior erro em apps Roku é não observar o estado do Video node.
m.video.observeField("state", "onVideoState")
sub onVideoState()
if m.video.state = "error"
showFallback()
end if
end sub
Isso evita:
- tela preta
- travamento silencioso
- reprovação na revisão da Roku
SceneGraph e performance: o que realmente importa
O que impacta performance de verdade:
- loops longos na thread de UI
- parse de JSON gigante sem cuidado
- criação excessiva de nós
- imagens grandes sem otimização
- não tratar
invalid
O que não impacta tanto quanto parece:
- “complexidade” do XML
- quantidade de arquivos
- número de componentes (bem organizados)
Organização vence micro-otimização.
Arquitetura recomendada (padrão profissional)
/components
/scenes
/ui
/services
/utils
source/
manifest
- Scene: coordena
- UI Components: reutilizáveis
- Services: API, EPG, playback
- Utils: helpers e parsers
Isso escala para:
- VOD
- FAST
- apps white-label
- múltiplos canais
Onde SceneGraph brilha (e onde não)
Brilha quando:
- você respeita o modelo
- separa bem XML e BrightScript
- pensa em eventos e estados
- prioriza estabilidade
Cobra seu preço quando:
- você tenta “imitar React”
- força lógica no XML
- ignora estados do player
- não trata erro e rede ruim
Por que SceneGraph é decisivo para o sucesso do app
A Roku avalia silenciosamente:
- tempo de inicialização
- estabilidade da UI
- comportamento com controle remoto
- falhas de playback
- consumo de memória
Apps que dominam SceneGraph:
- quebram menos
- passam mais rápido na revisão
- escalam melhor
- monetizam com mais previsibilidade