Isolating Frequently Changed Nodes
A common use case for Revideo is adding subtitles to a video. Often, this gets handled like this:
import ...
export default makeScene2D(function* (view) {
const words = [
'Here',
'are',
'some',
'subtitles',
'added',
'to',
'the',
'video',
];
yield view.add(
<>
<Video
src={'https://revideo-example-assets.s3.amazonaws.com/beach-3.mp4'}
play={true}
size={['100%', '100%']}
/>
</>,
);
for (const w of words) {
const textRef = createRef<Txt>();
yield view.add(
<Txt
fontFamily={'Sans-Serif'}
fill={'white'}
fontSize={40}
ref={textRef}
text={w}
/>,
);
yield* waitFor(0.3);
textRef().remove();
}
yield* waitFor(1);
});
Speed up Rendering by not adding <Txt/>
to view
The implementation shown above can be made significantly faster, especially when we have more words in our subtitles:
The existing implementation repeatedly modifies the view
node by always adding
new <Txt/>
elements to it. All of these operations will cause Revideo to
reload the view
node and therefore also reload the <Video/>
tag, which takes
up a lot of time.
The solution to this is to not add <Txt/>
elements to the view
node
directly, but to a child container of view
that is not a parent of our
<Video/>
element. Now, we will not reload all children of view
during every
<Txt/>
change:
import ...
export default makeScene2D(function* (view) {
const textContainer = createRef<Layout>();
const words = [
'Here',
'are',
'some',
'subtitles',
'added',
'to',
'the',
'video',
];
yield view.add(
<>
<Video
src={'https://revideo-example-assets.s3.amazonaws.com/beach-3.mp4'}
play={true}
size={['100%', '100%']}
/>
<Layout size={['100%', '100%']} ref={textContainer} />
</>,
);
for (const w of words) {
const textRef = createRef<Txt>();
yield textContainer().add(
<Txt
fontFamily={'Sans-Serif'}
fill={'white'}
fontSize={40}
ref={textRef}
text={w}
/>,
);
yield* waitFor(0.3);
textRef().remove();
}
yield* waitFor(1);
});
Of course, this does not just apply to <Txt/>
nodes, but any node that you
modify frequently.