A little question about "Why designer of JavaScript library are
designing that way ?"
1. Context
I'm developper on a CMS using Prototype/Scriptaculous as first
JavaScript layer.
- The CMS is using many library to handle tooltips, in place editing,
contextual menu, ...
- The CMS must have good response time.
2. Library
Usally, library (like InPlaceEditor):
- Provides a Class that will be created like: new Ajax.InPlaceEditor(
element, url, {options});
- Code will be called "onload" on a $$('css on the page')
3. Issue
So each time a page is displayed there is
- $$('') parsing the page
- Object created, Draggable, DOM Manipulation ...
So each time the page is modifed with an Ajax update of the DOM the
initialisation must be reroll ...
4. Solution
We have made the choice to be lazy:
4.1 On load we listen on clic on the window/document
4.2 On click we look for a css class on the clicked element or one of
it's parent
4.3 Then we initialise the good component.
So pages are no longer slow down by parsing the DOM on load because we
work on the element onclick.
So the visitor who navigate from page to page don't pay the cost of $$()
For instance:
- On document click
=> We find a Span with class editInPlace
=> We create EditInPlace Editor
=> We call editor.enterEditMode('click');
- On document click
=> We find a link with a class ctxmenu
=> We made an AJAX Call to retrieve the menu
=> We display it
We have made performance test:
- It's faster
- Less memory leak (no object created => gc later)
5. Question
- Is there drawbacks with this solution ?
- Why Libraries (InPlaceEditor, Prototip, ... ) do not use this design
pattern ?
=> One drawback: You can't display visual effect on the page like
AjaxInPlaceEditor highlighting. But in fact you can use at least CSS
declaration.
Best Regards,
Jp
PS: 6. Sample Code
Event.observe(window, 'load' , function() { JCMS.ajax.Edit.init();
});
'JCMS.ajax.Edit'.namespace({
init: function(){
if (JcmsJsContext.isIE){ // Needs channel.js
Event.observe(document, eventName ,
JCMS.ajax.Edit.edit.bindAsEventListener()); // InternetExplorer
} else {
Event.observe(window, eventName ,
JCMS.ajax.Edit.edit.bindAsEventListener()); // FireFox
}
},
edit: function(event){
var elt = Event.element(event);
var tag = $(elt.fastUp('A', 'ajax-edit', true));
if (!tag || !tag.hasClassName('ajax-edit')) {
return;
}
if (!tag.hasEditor){
Event.stop(event);
tag.hasEditor = true;
var editor = new Ajax.InPlaceEditor(tag, '/demoajaxreturn.html',
{rows:15,cols:40});
editor.enterEditMode('click');
}
}
});
--
Jean-Philippe Encausse - Veille / R&D Jalios SA
Jp [at] encausse.net - http://www.encausse.com - http://www.jalias.com
GTalk: jp.encausse [at] gmail.com - SMS: sms [at] jp.encausse.net
Mob: +33 6 82 12 56 99 - Job: +33 1 39 23 92 83 - Tel: +33 1 39 18 90 15
Do it Once, Use it Twice ~ Do it Twice, Make It Once
on 2008-06-10 11:08
on 2008-06-11 01:36
On Jun 10, 7:07 pm, "Jean-Philippe Encausse" <J...@encausse.net> wrote: > [...] > work on the element onclick. > So the visitor who navigate from page to page don't pay the cost of $$() This is called event delegation - you wait for an event to bubble, see where it came from, then decide if you want to do something with it. > => We display it > > We have made performance test: > - It's faster > - Less memory leak (no object created => gc later) There are well known strategies to deal effectively with memory leaks, I don't think that should be an issue. Nor does this model necessarily decrease the likelihood of leaks. > > 5. Question > > - Is there drawbacks with this solution ? 1. Not all events bubble, so you don't have the full range of event listeners available. 2. Passing parameters from the event to the called function is more complex - strategies like additional class names or custom attributes are often employed. > - Why Libraries (InPlaceEditor, Prototip, ... ) do not use this design > pattern ? Ask their authors. Don't forget that web 0.1 inline listeners don't have any of the issues highlighted above and can be used in exactly the same way (i.e. event bubbling) and you don't have to wait for window.onload or DOM:ready. Consider the difference between using logic at the sever to add class names and custom attributes to be used by a listener added at the client versus using exactly the same logic to add an inline listener with parameters. I'm not suggesting that inline listeners are the answer for everything, just that they have their place and shouldn't be dismissed out of hand for not being hip. -- Rob
on 2008-06-11 05:59
There are no silver bullets. Both event delegation and inline event handlers have their pros and cons. The benefits of delegation could be easily outweighed by the time it takes to traverse a deep document (think frequent events like mousemove/over/out, window's "resize", etc.) Inline event handlerts on the other hand are notorious for the maintanence nightmares they bring. When used appropriately, these techniques could defnitely make a huge difference in app performance. - kangax On Jun 10, 5:07 am, "Jean-Philippe Encausse" <J...@encausse.net>
on 2008-06-11 09:05
To be sure I correctly understand your answer: Inline events are events declared in the HTML ? <a href=".." onclick="..." >Click Me</a> or <script>stuff</script> Well I agree this code is fast because it is directly bind to function. But as you said there is pros and cons. I wasn't thinking about this Web 0.1 feature because: 1. You mix HTML and JavaScript 2. Designer must understand the "magic" to write in the page In the real world: - You will have performance issue asking you to put code at the bottom of the page - Open API issue, the XHTML must be readable, can be parsed - People makes mistakes it is more complicated to write a <script> tag than simply class names In a generic Portal/CMS it is too complicated. Users need magic like "Put CSS class tooltip you will have a tooltip" or "Add class editable the field will be editable". It is so true that the developer of Lightview (Prototype Lightbox) do not clearly answer on it's ofuscated code behavior) and answer "don't use the code use html declaration only" :-) So at this point : - You can look for all '.myclass' in the document to bind stuff but you parse the document and pay for the parsing cost. In a previous version we play with Draggable in a Tree and it was really painfull. - You can use the bubbling pattern. I was really surprised by the speed of document event dispatching. Playing with http://thinkweb2.com/projects/prototype/detect-idl... it is really fast and convenient. About MemoryLeaks: Well I agree in theory we know how to handle memory leaks. In the real world, - Someone build a CMS - An other one use/include library - An other one code custom library with holes - Some beginers works on a the without memory leak knowledges ... Well a big mess where the must be called only when needed :-) Thanks for your answer Jp Jean-Philippe Encausse - Veille / R&D Jalios SA Jp [at] encausse.net - http://www.encausse.com - http://www.jalias.com GTalk: jp.encausse [at] gmail.com - SMS: sms [at] jp.encausse.net Mob: +33 6 82 12 56 99 - Job: +33 1 39 23 92 83 - Tel: +33 1 39 18 90 15 Do it Once, Use it Twice ~ Do it Twice, Make It Once
on 2008-06-11 11:12
On Jun 11, 5:05 pm, "Jean-Philippe Encausse" <J...@encausse.net> wrote: > To be sure I correctly understand your answer: Inline events are > events declared in the HTML ? > <a href=".." onclick="..." >Click Me</a> Yes. > or <script>stuff</script> No. > Well I agree this code is fast because it is directly bind to > function. But as you said there is pros and cons. I wasn't thinking > about this Web 0.1 feature because: > > 1. You mix HTML and JavaScript So what. > 2. Designer must understand the "magic" to write in the page No, they don't. For example, instead of: <table class="... sortable ..." ...> they write: <table onclick="sort()" ... > If your HTML programmers can't handle that, you have a serious skills issue. If you have the logic on the server, then the HTML authors add an attribute in the HTML that is stripped when processed by the server and replaced by the inline listener (or whatever other scheme you use). So the HTML author never needs to write any script, nor does the listener get added at the client. > In the real world: > > - You will have performance issue asking you to put code at the bottom > of the page Putting script elements at the bottom of the page *improves* performance. > - Open API issue, the XHTML must be readable, can be parsed Inline listeners don't have any effect on the readability of the markup, it's simply an attribute value that should usually be a simple function call. > - People makes mistakes it is more complicated to write a <script> tag > than simply class names How is writing a script tag any more complex than an img tag? If you want script in your page, you've gotta put at least one element in there somewhere. > In a generic Portal/CMS it is too complicated. Users need magic like > "Put CSS class tooltip you will have a tooltip" or "Add class editable > the field will be editable". > > It is so true that the developer of Lightview (Prototype Lightbox) do > not clearly answer on it's ofuscated code behavior) and answer "don't > use the code use html declaration only" :-) Sure, all I'm saying is that the server can parse the HTML and add an inline handler, you don't have to do it at the client. > So at this point : > > - You can look for all '.myclass' in the document to bind stuff but > you parse the document and pay for the parsing cost. In a previous > version we play with Draggable in a Tree and it was really painfull. And if done at the server before serving the page... ? > - You can use the bubbling pattern. I was really surprised by the > speed of document event dispatching. Playing withhttp://thinkweb2.com/projects/prototype/detect-idl...... > it is really fast and convenient. Yes, bubbling is a useful technique - it is independent of how you add listeners. > Well a big mess where the must be called only when needed :-) Inline listeners don't have *any* issues with memory leaks. > Thanks for your answer Just to clarify, I am not saying "never dynamically add event listeners", I'm just saying to keep an open mind and consider adding them at the server in some cases instead of at the client. And by "add them at the server" I am not saying the HTML author needs to add them, but that they can be added by the server using the same logic that you are currently employing on the client. -- Rob
on 2008-06-11 15:39
I think we are agree > > Just to clarify, I am not saying "never dynamically add event > listeners", I'm just saying to keep an open mind and consider adding > them at the server in some cases instead of at the client. > I agree with you > > And by > "add them at the server" I am not saying the HTML author needs to add > them, but that they can be added by the server using the same logic > that you are currently employing on the client. > Well in project where our software is used it is not so simple: 1. Someone makes a beautifull non web graphical chart in photoshop (let's say displaying a table) 2. A big corporation decide to use our CMS 3. Then an other one decide to use a plugin, or featue that sort all tables in front office. At the end a third company will try to mix all 3 points. And in worst case they will cut and past some part of the html code, throw images in a directory and that's it ... the result must be clean, fast, ... I agree that in a perfect world people must be skilled. But in fact they write something horrible like <table onclick="say("hello john")" ... > In fact, I agree working on server side is possible, but I like the separation of CSS, HTML (semantic) and JS. -- Jean-Philippe Encausse - Veille / R&D Jalios SA Jp [at] encausse.net - http://www.encausse.com - http://www.jalias.com GTalk: jp.encausse [at] gmail.com - SMS: sms [at] jp.encausse.net Mob: +33 6 82 12 56 99 - Job: +33 1 39 23 92 83 - Tel: +33 1 39 18 90 15 Do it Once, Use it Twice ~ Do it Twice, Make It Once