adamhaile / surplus

High performance JSX web views for S.js applications
636 stars 26 forks source link

Maybe do not evaluate elements. #54

Open uvelichitel opened 6 years ago

uvelichitel commented 6 years ago

First, thanks for sharing. I'm very appreciate and use your code in own projects. Now, JSX compiler emits nodes with perfectly readable code

view = function () {
    var __, ...
   __ = createElement(...
    ...
    return __;
}()      // here it call function end evaluate element. I'd like to remove this call.

I can mount view document.body.appendChild(view) only once because of DOM rules

If the given child is a reference to an existing node in the document, appendChild() moves it from its current position to the new position (there is no requirement to remove the node from its parent node before appending it to some other node).

Maybe will be meaningful to leave view() been a function but not evaluate it. This allow instantiate document.body.appendChild(view()) any times needed. Also it allows to easily write functional components const Component = ((props) => <div>{props.content}<div>) and use em like a template

var view = <div>
<Component content={S(some_computation)}>
</div>;

If you agree this can make sense, than I can pull request, or you can do it yourself - just remove )() call in compiler's codegen(). I done it and test in my local repo and things work as expected.

adamhaile commented 6 years ago

Hi @uvelichitel -- You're right that, unlike React, a JSX expression in Surplus can't be used to make multiple nodes. Being a real DOM node and not a template , it can only go one place in the tree.

The IIFE that the compiler generates was largely just to give us our own lexical namespace, so that we don't pollute surrounding code with our symbols.

It's an interesting idea, that a JSX expression would produce functions instead of nodes. The two concerns that immediately jump to mind are:

  1. It would be a major change, breaking all existing Surplus code.

  2. Don't you think it's more natural that <div/> produces a div element and () => <div/> a template, than that <div/>() and <div/> do? It seems to me like the template use case is far less common than the single node case, and that when you do want a template, () => ... is an easy and clear way to get one.

-- Adam

uvelichitel commented 6 years ago

OK than

brodybits commented 6 years ago

The IIFE that the compiler generates was largely just to give us our own lexical namespace, so that we don't pollute surrounding code with our symbols.

+1

  1. It would be a major change, breaking all existing Surplus code.

Is this really a major problem in pre-1.0.0 stage?

  1. Don't you think it's more natural that <div/> produces a div element and () => <div/> a template, than that <div/>() and <div/> do?

I was thinking that in JSX should produce code that produces my-html-element when needed, upon demand.

I do really like the idea that Surplus eliminates the need for VDOM nodes and generates code that produces real DOM nodes. I would love to see a more flexible approach where Surplus generates code that produces the real DOM nodes upon demand, when needed.

P.S. Another consequence of the idea discussed here is that it would not be possible to change attributes like view.className = 'bar' on view defined like var view=<div>...</div> or const view=<div>...</div>. I do really like this idea but think it should be further discussed and fleshed out with sample documentation before incorporating.

irisjae commented 6 years ago

If something that 'produces a node on demand' is needed, isn't it basically the same as this?

() => <jsx-here />

To me, that's one of the clearer ways you can express this idea.

True, if a function is generated, then some features like caching or whatnot for performance can be added, but that seems a completely different territory as well.

Qix- commented 5 years ago

Plus, seeing as how Surplus is still one of the fastest JSX frameworks according to benchmarks, I think V-Doms are less of an issue.