The Diff DOM (Document Object Model) algorithm is used to compare two versions of the DOM, such as before and after an update on a web page. It aims to efficiently identify the changes between both DOMs, minimizing the number of manipulations required to update the user interface.
The Diff DOM Streaming library extends the traditional Diff DOM algorithm by introducing support for comparing a DOM node with a streaming reader. This enables the library to process the changes incrementally as they occur during the diff process.
For more info, read this:
Install:
bun install diff-dom-streaming
Then import it:
import diff from "diff-dom-streaming";
Install:
bunx jsr add @aralroca/diff-dom-streaming
Then import it:
import diff from "@aralroca/diff-dom-streaming";
Just import it:
import diff from "https://unpkg.com/diff-dom-streaming@latest";
const res = await fetch(/* some url */);
// Diff between the current document and the reader:
await diff(document, res.body.getReader());
diff(oldNode: Node, reader: ReadableStreamDefaultReader, options?: Options)
This function performs a diffing operation between the oldNode
and the DOM tree streamed through reader
. It applies the necessary changes to update the oldNode
accordingly. An optional options
that include:
type Options = {
// calback to handle each new docoument node during the streaming
// (default: undefined)
onNextNode?: NextNodeCallback;
// update the DOM using document.startViewTransition (default: false)
transition?: boolean;
};
Keys help to identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) => (
<li key={number.toString()}>{number}</li>
));
(Example with JSX)
The diff-dom-streaming
library takes into account the key
attribute for these cases, if it does not exist, then see if they have id
.
You can activate the View Transition API updating the DOM with this property:
await diff(document, res.body.getReader(), {
+ transition: true
})
Tip
To access the transition with JavaScript/TypeScript you can access the global property window.lastDiffTransition
Many times it will make more sense to use a complete transition instead of incremental, especially if we do not use suspense and we want a single transition at once instead of several, in this case, instead of using the configuration, we can use the View Transition API directly:
+ document.startViewTransition(async () => {
await diff(document, res.body.getReader(), {
- transition: true,
});
+});
In the repo we have examples for you to try.
There are some examples:
- Run
bun run example:boxes
- Run
bun run examples:spa-like
You can run the boxes demo with Vanillajs here.
The Diff DOM Algorithm with HTML Streaming is inspired by the set-dom library by @dylan_piercey and a technique for parsing streams pioneered by @jaffathecake.
See Contributing Guide and please follow our Code of Conduct.