有谁知道 DOM diff 算法是否可以应用于深度优先搜索(DFS)而不是宽度优先搜索(BFS)?几天来我一直在尝试让 DOM diff 算法与流式 HTML 一起使用,但我遇到了麻烦(与 React 不同的方法)。有谁知道开源示例吗?
现在我做了这个助手来从流中获取节点:
const decoder = new TextDecoder();
export default async function* parseHTMLStream(
streamReader: ReadableStreamDefaultReader<Uint8Array>,
doc = document.implementation.createHTMLDocument(),
lastChunkNode: Node | null = null,
): AsyncGenerator<Node> {
const { done, value } = await streamReader.read();
if (done) return;
doc.write(decoder.decode(value));
let lastNode = lastChunkNode
? getNextNode(lastChunkNode)
: doc.documentElement;
for (let node = lastNode; node; node = getNextNode(node)) {
if (node) lastNode = node;
yield node;
}
yield* await parseHTMLStream(streamReader, doc, lastNode ?? lastChunkNode);
}
/**
* Get the next node in the tree.
* It uses depth-first search in order to work with the streamed HTML.
*/
function getNextNode(node: Node | null, deeperDone?: Boolean): Node | null {
if (!node) return null;
if (node.childNodes.length && !deeperDone) return node.firstChild;
return node.nextSibling ?? getNextNode(node.parentNode, true);
}
然后我可以直接使用流节点:
const reader = res.body.getReader();
for await (const node of parseHTMLStream(reader)) {
console.log(node);
}
但是随后你会失去它是否是子节点、slibing 以及它必须与哪个真实 dom 进行比较的上下文,而不会通过仅更新已更改的 DOM 节点来创建错误。我开始认为,如果 React 和所有示例都是广度优先,那么并不是说你不能用深度优先实现 DOM diff 算法。是这样吗?如果没有,有人有一个如何实施的例子吗?