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

Use innerHTML for static elements? #23

Closed
Rich-Harris opened this issue Nov 23, 2016 · 15 comments
Closed

Use innerHTML for static elements? #23

Rich-Harris opened this issue Nov 23, 2016 · 15 comments

Comments

@Rich-Harris
Copy link
Member

Would need to compare performance, but it's entirely possible that in cases where you just have a bunch of static markup inside an element, it would be quicker to use node.innerHTML = markup rather than constructing the DOM programmatically.

@evs-chris
Copy link
Contributor

It seems that innerHTML is usually faster for larger bits of markup (according to jQuery, jsperf has been mia for a while so good cross browser comparisons are harder to come by). It also has the advantage of being considerably less code. Event listeners are a little trickier, but having a document ast means you could easily attach listeners with a direct path to the child. I believe the same approach to transitions would even be reasonable.

@trueadm
Copy link
Contributor

trueadm commented Nov 23, 2016

Actually, in my testing, even with a large amount of node, createElement and appending it to the DOM is still quicker in all my testing. Good luck with svelte though – I like the name :)

@Rich-Harris
Copy link
Member Author

Yeah, digging around it seems you get different answers depending on what browser you're looking at and what time of day it is! @trueadm are your tests in a reproducible form online somewhere? Would be keen to poke them a bit – Inferno is still a tiny bit quicker than Svelte at dbmonster, but if I steal enough of your research that may change 😀

Event listeners are a little trickier

By static I was excluding nodes with any kind of directive (on:, bind:, ref: and so on), but yeah, you're right – I guess it'd be just as easy to plonk some innerHTML in and do...

div.innerHTML = `<div class='inner'><span>click the button</span><button/></div>`;
var button = div.childNodes[0].childNodes[1];

...if there was a situation where that was faster. (I guess you could even optimise for specific browsers at build time if there was a difference...)

@trueadm
Copy link
Contributor

trueadm commented Nov 23, 2016

I have the benchmarks somewhere. I'll dig around for them tonight. On a side note I need to update the inferno benchmarks online, they use a slower older version. I'd recommend doing the JS-framework benchmark too.

I know this is unrelated: but supporting JSX like Vue2 does would be a huge win. You'd be able to pull in a lot of users who have moved to that way of building components, even letter people mix it up a bit. Would that be possible?

On 23 Nov 2016, at 17:11, Rich Harris notifications@github.com wrote:

Yeah, digging around it seems you get different answers depending on what browser you're looking at and what time of day it is! @trueadm are your tests in a reproducible form online somewhere? Would be keen to poke them a bit – Inferno is still a tiny bit quicker than Svelte at dbmonster, but if I steal enough of your research that may change 😀

Event listeners are a little trickier

By static I was excluding nodes with any kind of directive (on:, bind:, ref: and so on), but yeah, you're right – I guess it'd be just as easy to plonk some innerHTML in and do...

div.innerHTML = <div class='inner'><span>click the button</span><button/></div>;
var button = div.childNodes[0].childNodes[1];
...if there was a situation where that was faster. (I guess you could even optimise for specific browsers at build time if there was a difference...)


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@Rich-Harris
Copy link
Member Author

You mean https://github.com/krausest/js-framework-benchmark? Yeah, it's on my TODO list, once I've wrapped my head round it.

Would that be possible?

I thought about it, yeah. I don't think it is. Svelte works because it has very clear compile-time guarantees about the structure of your application. I don't really see a way that that's possible with JSX, since it's 'just JavaScript' and therefore impossible to fully statically analyse.

But I don't think that's a huge problem. I know a lot of people really like JSX, but in my experience people who are familiar with both React and Vue or React and Ractive prefer the Vue/Ractive style. Templates are just a better fit for the task of describing a UI, in my view. Rule of least power and all that. You probably disagree with me on that :)

I expect people to be sceptical at first, but to come round when they realise the benefits. Maybe not to Svelte in particular, but to the idea in general of declarative components that compile to raw JS.

"What, this new framework has a runtime? Ugh. Thanks, I'll pass" –developers in 2018

@yyx990803
Copy link

Re JSX: I actually thought about the possibility of writing an alternative Vue 2 codegen like this, but making it compatible with raw render function usage seems quite hard. You either have to include a vdom runtime (which defeats the purpose of svelte), or try to statically analyze the render function code. However templates are naturally much more statically-analyzable as compiler inputs - JSX/render functions involves too much runtime JS behavior to safely generate svelte-style output.

@trueadm
Copy link
Contributor

trueadm commented Nov 29, 2016

@yyx990803 I've actually been playing around with the idea of compiling pure render functions into Rust and then using them in WASM. Hasn't been smooth, but I've not had a lot of time to invest into it to be honest. From my initial experiments, all I can say is: it's definitely the future in terms of raw performance. I wish I could show you benchmarks even if the render functions were trivial – you'd be stunned (legal reasons why I can't, sorry).

@yyx990803
Copy link

@trueadm wow, I assume the code compiled to WASM still needs to talk to the DOM? At that point the real bottleneck would be the browser not the frameworks ;)

@trueadm
Copy link
Contributor

trueadm commented Nov 29, 2016

@yyx990803 something like that ;)

@mrkishi
Copy link
Member

mrkishi commented Nov 30, 2016

@trueadm Hey, did your benchmarks include a <template>-based solution, by any chance? I wonder if they might be competitive with createElement at this point.

@Ryuno-Ki
Copy link

@mrkishi was faster!

I think, DocumentFragment is an alternative, but <template> is rather in the process of standardising.

@PaulBGD
Copy link
Member

PaulBGD commented Jul 11, 2017

Have there been any benchmarks in the last 8 months showing DocumentFragment performance? From what I've seen with a few searches, there aren't many benefits unless you're doing a lot of cloning (such as 2 copies of a component in 2 places in the DOM, assuming they have the same state.)

Rich-Harris added a commit that referenced this issue Sep 19, 2017
Rich-Harris added a commit that referenced this issue Sep 19, 2017
Rich-Harris added a commit that referenced this issue Sep 19, 2017
use textContent and innerHTML where appropriate
@Rich-Harris
Copy link
Member Author

Implemented this in 1.39.4 — we now use textContent and innerHTML where it makes sense to do so.

@JadedBlueEyes
Copy link

"What, this new framework has a runtime? Ugh. Thanks, I'll pass" -- developers in 2018

Sadly not.

@nathancahill
Copy link

Found an interesting side effect/bug(?) with this. When a <script> tag is inserted via innerHTML the script isn't executed. In development mode, the script is executed since it's created as an element. This means that the problem only surfaces in production. The workaround is to add a variable to the <script> tag to force element creation.

Here's an example of the broken version and the workaround: nathancahill/split@ead9da3

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

9 participants