Matt-Esch/virtual-dom

How to patch server-side rendered html efficiently

glennfu opened this issue · 1 comments

Hello! I'm very new to this project, but it seems incredibly promising, but I'm stuck one issue. When I try to patch in new html to replace an element from the server, the entire dom node is replaced instead of just the diff being applied. Here's my code:

var diff = require('virtual-dom/diff');
var patch = require('virtual-dom/patch');
var parser = require('vdom-parser');
var select = require("vtree-select");

var tree;
document.addEventListener('DOMContentLoaded', initialDiff)
function initialDiff() {
  tree = parser(document.body)
  document.removeEventListener("DOMContentLoaded", initialDiff)
}

window.fastReplace = function(selector, html) {
  var thisTree = select(selector)(tree)[0];
  var newTree = parser(html);
  var patches = diff(thisTree, newTree);
  patch($(selector).get(0), patches);
}

As an example of my problem, when I run this in FireBug:

window.fastReplace("body .main", $("body .main").get(0).outerHTML)

I see the entire <div class="main" /> has been replaced, even though the HTML is identical and visually nothing has happened. If I change that line to read .outerHTML.replace("The", "TheBlah") I can see that visually the change happens exactly as I want, but monitoring from FireBug shows me that the element has been replaced, not patched.

What am I doing wrong here to prevent the diff from working as it should? Is this even possible with virtual-dom? Thanks!

Update to this:

window.fastReplace = function(selector, html) {
    var el = $(selector).get(0);
    var thisTree = parser(el);
    var newTree = parser(html);
    var patches = diff(thisTree, newTree);
    patch(el, patches);
  }

This is working great, except the first call always replaces the whole node. Every subsequent call patches efficiently. Is there something else I can do to "seed" the VirtualDom before I run this? Also, assuming I can do that, how can I predict if it has been seeded and will patch efficiently?