Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1st patch is slow #8

Open
JSteunou opened this issue Oct 27, 2017 · 9 comments
Open

1st patch is slow #8

JSteunou opened this issue Oct 27, 2017 · 9 comments

Comments

@JSteunou
Copy link
Contributor

This might be a question for the idom team but maybe you will have some answers.

Playing with some performance measure on a quite simple view, my 1st render using patch is in average 2.5x slower than using innerHTML with default Handlebars text output. Consecutive patch with some text change are 2x faster. Is this possible to get the better of both?

@atomictag
Copy link
Owner

2x for the initial patch seems a bit high - guess it really depends on what your templates are / do (guess your templates are precompiled, right?). Said that, I don't think there's much of an advantage with just about any dom renderers vs native parsing of HTML strings (e.g. via innerHTML and so). That's what browsers are optimized for, after all, and it is all done outside of the JS runtime. So for huge, highly static HTML that need no repaint / re-render plain HTML strings will always do. However, where incremental-dom and all other dom renderers shine is in the repaint / redraw operations - not only in terms of performance (which honestly nowadays is pretty good on all devices regardless from the technology used) but in the simplicity of changing "state" by simply re-rendering the whole thing. FWIW incremental-bars (and therefore Handlebars) adds very little overhead to hand-written incremental-dom so yeh, maybe that's a question better suited to the incremental-dom maintainers.

@atomictag
Copy link
Owner

atomictag commented Oct 27, 2017

Another thing worth mentioning here (despite being a fairly obvious one): idom patch performs a lot of writes on the dom subtree passed to it, so it's always better / faster to perform the first patch on a detached node or a document fragment and then append the resulting sub-tree to the dom, rather than pass an element already attached to the dom to the patch function.

@JSteunou
Copy link
Contributor Author

JSteunou commented Oct 27, 2017

I had the same conclusion.

And yes I'm using a documentFragment as source for the patch, precompiled templates through the webpack loader and my templates are rather thin.

Like you said, it's really dom renderers vs native parsing. x2 seems a lot but we are talking about milliseconds here, like 4ms vs 2ms. This is not much, but multiply by hundreds of views / components this is quite a slow down for the 1st render / paint of a whole web application.

The only solution I can think of would be server rendering and patching over existing DOM...

@atomictag
Copy link
Owner

Guess it really depends if there is really a performance issue that perceivably slows things down.
This site is all incremental-bars with lots of subviews & friends as it's as fast as it can get for a data-driven one-page application.

@blikblum
Copy link

idom patch performs a lot of writes on the dom subtree passed to it, so it's always better / faster to perform the first patch on a detached node or a document fragment and then append the resulting sub-tree to the dom, rather than pass an element already attached to the dom to the patch function.

In modern browsers seems that this not true anymore. I read that sometimes ago, although i don't remember exactly where.

But there are some facts that points toward that.

The main virtual dom implementations (React, Snabbdom) patch the elements in place instead of detaching or using documentFragment.

This perf https://jsperf.com/document-fragment-vs-innerhtml-vs-looped-appendchild directly appending is little faster both in chrome 61 and Firefox 57

@JSteunou
Copy link
Contributor Author

JSteunou commented Oct 27, 2017

Now I'm confused... appending is 2.75% faster than innerHTML in this benchmark (on my computer) but my benchmark between innerHTML and idom patch is 100% (sometimes more, again on my computer) slower and I though idom 1st patch was merely kind of appending (because I'm pre-compiled)

@blikblum
Copy link

The higher cost of first render when using virtual dom approaches is expected. It has to build the virtual tree than apply all dom operations. On subsequent render it also has to build the entire virtual tree but only do a few dom operations.

incremental-dom is a kind of virtual dom, the difference is that instead of building a separate tree, it stores the virtual info as an expando property in the html element in the first render.

Regarding incremental-dom performance, in this comment google/incremental-dom#214 (comment) , there's a mention of "our slowdown" without explaining much. Maybe @jridgewell, that worked in performance, can clarify the supposed idom performance issues.

@blikblum
Copy link

my 1st render using patch is in average 2.5x slower than using innerHTML with default Handlebars text output

@JSteunou
Did you considered the time spent by Handlebars to generate the string?

This is important because incremental-bars does everything in one pass unlike traditional string template that first needs to build the string than set innerHTML

Given this info, i would benchmark a template with a non trivial amount of HTML elements. This could show some difference come from the string concatenation and posterior parsing by the browser

@JSteunou
Copy link
Contributor Author

Yep, I measured inside the render logic of a Marionette View with both precompiled templates, both just before just after rendering appending / patching logic.

But my template was pretty thin, one element with 3 children. Worth trying with a bigger and more complex structure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants