In this series, How lit-html works, I will explore (not explain) internal implementation of lit-html.
In the last 4 posts, we saw what TemplateResult
and SVGTemplateResult
looks like.
From now on, I will explore the render
function.
render
function
render
function is defined beside a variable whose name is parts
.
export const parts = new WeakMap<Node, NodePart>();
export const render =
(result: unknown,
container: Element|DocumentFragment,
options?: Partial<RenderOptions>) => {
let part = parts.get(container);
if (part === undefined) {
removeNodes(container, container.firstChild);
parts.set(
container,
part = new NodePart(
{
templateFactory,
...options,
},
undefined));
part.appendInto(container);
}
part.setValue(result);
part.commit();
};
This function receives two arguments. First one is an instance of TemplateResult
or SVGTemplateResult
. Second is the container
, which is a DOM parent inside which the content is rendered.
Searching Cache
Firstly, render
function checks if an instance of NodePart
class is stored in parts
with the container
as a key.
Create a New NodePart
If a cached NodePart instance is not found, then all the direct children of the container are removed by removeNodes
function.
export const removeNodes =
(container: Node, start: Node|null, end: Node|null = null): void => {
while (start !== end) {
const n = start!.nextSibling;
container.removeChild(start!);
start = n;
}
};
The algorithm is quite similar to reparentNodes
function that I saw in the last post. Only difference is how the functions manipulate DOM tree.
After cleaning up the container
, a new NodePart instance is registered into the parts
and is associated with with the container
.
Rendering
Finally, render
function lets the NodePart instance call three methods of it, but I will explore this part in later posts. Instead, I will recap what WeakMap is, because it's worth using in other development as well.
WeakMap
MDN says that the WeakMap object is a collection of key/value pairs and the keys must be objects.
The word "weak" here means that the reference from weak map to the key object doesn't prevent the object from being garbage collected.
Thus, it is really convenient to store data in a WeakMap as a cache. We don't have to check, every time we do something or periodically the data of the object, whether the data is no longer used.
Just for information, there are also Map, Set, WeakSet, each of which has suitable situation.
Summary
So far, I learned the following points:
-
render
function caches NodePart. -
render
function creates a new NodePart if no corresponding cache is found. -
render
function delegates actual rendering process to the NodePart instance.
From the next post, I will dive into the NodePart class.
Top comments (0)