First of all, thanks for fighting for client side rendering too.
Our efforts go to the same direction. Even if we are in a kind of
competition game.
Ideas from one project will benefit to the other. So in the end that's
a good thing.
The first version of PURE was DOM based for simplicity, elegance and
to keep a tree based logic.
Then as the screens of our app went bigger and more complex the
performance were unacceptable so I switched back to innerHTML.
A bit sad, but I quickly felt home, as this was the way I've built web
apps for years with XSLT+XML sending the result to div.innerHTML's
I'm intrigued as attaching events was not an issue with XSLT.
They were set during the transformation as well as the html. So there
was no costly attach calls after transforming.
We were developing for the quite picky big corporations. They all use
almost exclusively IE 6/7 and we didn't experience memory leaks this
way.
In our last release I've set an example on how to attach events the
same way we were using it with XSLT.
If you have some time, I'd like to have your opinion on it. Do I miss
something?
Cheers,
On Sep 1, 3:08 pm, Rizqi Ahmad <raid...@yahoo.de> wrote:
> Hi Peter,
>
> thank you for your interest! it would be great to be able to work with
> you!
>
> may be we could replace the dom with lightningDOM. but I want to
> maintain the compatibility with jQuery,since it is based on jquery.
>
> send me email!
>
> On Sep 1, 7:04 am, Peter Rust <pe...@cornerstonenw.com> wrote:
>
> > Rizqi,
>
> > First off, I like the way you think. I've been a big evangelist of
> > client-side templating and data-binding in my workplace for the past
> > couple years. Making the binding automatic and overridable is also
> > beautiful.
>
> > I wrote a data-binding layer (now in its second version) for a project
> > (www.projectrecon.net), but haven't released or documented the data-
> > binding layer publicly. Now that others are in almost the exact same
> > space (Chain.js and PURE -http://beebole.com/pure/), I'd rather not
> > create a third option for the public. Instead, I'd like to study the
> > differences, discuss the various advantages and disadvantages of the
> > differences and contribute any code or differences of approach into
> > the two already-public projects.
>
> > One of the significant differences that comes up right away is that
> > your project has a high priority on not blowing away event-handlers by
> > re-generating a lot of templated markup and stuffing it into
> > the .innerHTML property. I can see the value in this, but there are
> > times when there is so much HTML that the .innerHTML approach is the
> > only one that is fast enough. When there is such a large amount of
> > HTML, you want to attach a single click event-handler on the container
> > anyway, because attaching an event-handler for, say, 200 elements,
> > takes far too long. Possibly one approach would be to detect if there
> > are any event-handlers -- and if there are, preserve them and take the
> > slower approach.
>
> > I wrote (yet another) layer underneath my data-mapper called
> > LightningDOM, which simulates the DOM API, but really is a super-fast
> > javascript wrapper around arrays of HTML strings. The benefit of this
> > is that the code could easily switch back-and-forth between the true
> > DOM and the arrays-of-strings-based LightningDOM, without too much
> > stress on the data-mapper layer itself.
>
> > Anyway, let me know if you're interested in collaboration and input.
> > I'd love to discuss these (and other) differences and work together at
> > building the best client-side templating/data-mapping system possible.
>
> > -- Peter Rust
> > Developer, Cornerstone Systems
Thanks, Mic!
I wrote a follow-up post this morning, released LightningDOM 1.3.1 and created an interactive LightningDOM Playground.
-- Peter
>to overwrite the $$(...) selector,
>as it allows only to have the full document as the search context
In Prototype, you can use a single element as the search context via Element.select(), for example $('myDiv').select('.highlight'). It has the exact same syntax and behavior as $$(). It’s a priority to me to make LightningDOM and PURE work with both jQuery and Prototype. When John Resig finishes his library-independent super-fast CSS Selector engine, Sizzle, it might be good to make that a dependency and use it exclusively.
-- peter
Peter,
>to overwrite the $$(...) selector,>as it allows only to have the full document as the search contextIn Prototype, you can use a single element as the search context via Element.select(), for example $('myDiv').select('.highlight'). It has the exact same syntax and behavior as $$().
It’s a priority to me to make LightningDOM and PURE work with both jQuery and Prototype. When John Resig finishes his library-independent super-fast CSS Selector engine, Sizzle, it might be good to make that a dependency and use it exclusively.
Mic,
> Sorry I was quite busy with the release of the new revision
That’s ok, I’ve been busy as well. But I’m still working & thinking about client-side templating/data-mapping and following the email groups closely.
> If I understood well, it converts the element to an array and I think
> I got the power of this. Especially for recursion.
Yes, it converts the element to an array of strings, under the hood, so that it can be very fast. This is similar to your compile() process, which generates an array of strings. The difference is that compile() only generates a separate string if it needs to, only where the “pure:” attributes are. LightningDOM, on the other hand, has a separate string for every element. And, after generating a separate string for every element, it is still editable, via the same API as the DOM: LightningDOMNode.attributes, LightningDOMNode.innerHTML, LightningDOMNode.className, etc.
The benefits of the compile() approach:
· It has slightly faster startup because you only need to split where there are “pure:” attributes.
· It uses slightly less memory (fewer strings in the array)
· It join()s the final HTML slightly faster (fewer strings in the array)
The benefits of the LightningDOM approach:
· It allows you to remove all the string operations (parsing/splitting/regexing) into a separate layer.
· It can be used by a variety of templating and data-mapping engines and approaches.
· If it is a separate layer shared by multiple templating engines, it can be better optimized and tested.
· It exposes the same API as the DOM, so if the DOM is faster than innerHTML in some browsers, your code can switch between them.
· The map()ing and nodeWalk()ing is faster because they’re manipulating LightningDOM nodes, not DOM ones
· It is more flexible, allowing for user-defined onPostTemplate or onPreTemplate node manipulations
· It is more flexible, allowing for partial updates (re-templating the HTML for a particular sub-element without re-templating the whole thing)
In your current architecture, directives are mapped to the DOM, you nodeWalk the DOM and then compile to JS/strings. Then if render() is called and it’s already been compiled, you just execute the compiled functions. In a LightningDOM-based architecture, you would first parse the DOM into a LightningDOM structure and keep that structure in memory. Whenever render() is called, you would nodeWalk the LightningDOMNodes based on the directives and generate the final HTML via LightningDOM’s .outerHTML() method.
> What are the know limitation of lightningDOM?
I’ve just tested it on my own projects/templates, so there are probably some nodeTypes (comments) and some IE-isms (unclosed <li> tags) that I haven’t coded for. This is just a matter of getting it out there in beta form and me being responsive to fix bugs that crop up. As far as possible limitations in the fundamental design/architecture, there are two things.
1) It isn’t currently a perfect drop-in replacement for the DOM because properties like .innerHTML and .nextSibling have to be “functionalized” into .innerHTML() and .nextSibling(). I have thought of a way to possibly fix this (my most recent blog post), but I would have to test it to see if there is a performance tradeoff.
2) I think the nested-arrays internal data structure is too highly-grained for the best performance and I think it would be faster if I replace it with a single one dimension array. This would require caching some parsed data (className, id, endTagIndex, etc) in a separate, paired data structure (possibly an array to start out, but perhaps moving into an object tree if point 1 turns out to be valid.
I have a project that needs more speed, so I’ll be profiling and seeing if option #2 will give me what I need. I might even be able to work on it today.
To experiment with integrating the LightningDOM, we don’t have to do the whole architecture change. We could begin by simply doing the map() and nodeWalk() on LightningDOMNodes, rather than on the DOM directly. If this goes well (we see a speed increase, squash bugs, like the feel of things), then we could look at possible further integration.
-- Peter Rust
Developer, Cornerstone Systems
PS: it’s theoretically possible to “precompile” the LightningDOM for further speed increases by doing the parsing beforehand and sending a pre-JSONified LightningDOM data structure to the client. My hunch is that this isn’t necessary and isn’t worth the effort, but people may want/need a pre-compiled option…