Javascript framework performance

D

David Mark

Your "lab"?

Yes, the lab formerly known as my guest bedroom. The commute is
roughly ten paces and the view is terrific. I'd certainly never go
back to driving for miles to park myself in a cube for eight hours. :)
 
P

Peter Michaux

Yes, the lab formerly known as my guest bedroom.  The commute is
roughly ten paces and the view is terrific.  I'd certainly never go
back to driving for miles to park myself in a cube for eight hours. :)

My commute is two paces with a nice forest view.

I don't have a "lab", unfortunately. Just a desk. I suppose I could
market it as a "home office". I should consider upgrading to a lab.
What do I need exactly?

I'm not going back either.

Peter
 
P

Peter Michaux

Yes, but XHR normalization doesn't add up to much.

No it doesn't but still is nice to have a library that makes
initiating an XHR request possible with a single function call. I
don't know why the native XHR API doesn't work that way. I really
don't like the Java-like APIs of the world where you have to create an
object and then send it a certain sequence of messages just to get
something done.
I do question
whether most apps need yet another "addEvent."

I wouldn't like to be without a wrapper for DOM2 and IE event APIs.

Peter
 
D

David Mark

My commute is two paces with a nice forest view.

I traded the forest for a garden (less deer to ruin my landscaping.)
I don't have a "lab", unfortunately. Just a desk. I suppose I could
market it as a "home office". I should consider upgrading to a lab.
What do I need exactly?

A couple of old Windows PC's for testing and a new Mac for doing
actual work.
I'm not going back either.

Yeah, I'd sooner die. When you think about it, your life is over
anyway (at least on weekdays.) :)
 
P

Peter Michaux

Testing for what?

Well, I've been using my JavaScript library, Fork, in production for a
couple years. It hasn't needed any fixes but I'd still like to update
it have a new API more to my current tastes. I'd also like to change
the way the feature testing works. The original Fork had these
isSupported functions to test if various parts of the API will work. I
think I'd rather wrap those bits of code in their feature tests so
that the bits of code are not even defined if they won't work.

Now the library is

FORK.Event.addListener = function(){};
FORK.Event.isSupported = function(){return test ? true : false;};

and a user would write

if (FORK.Event.isSupported()) {
Fork.Event.addListener();
}

I'd rather have the library be

if (test) {
FORK_addListener = function(){};
}

and then the user would write

if (typeof FORK_addListener == 'function') {
FORK_addListener();
}

I've digressed a lot but if you have any thoughts on the above please
comment.

What I need to test for is in the event library. Safari 2.0.3-, if I
remember correctly, had a bug where a click or double click event
could not be preventDefault'ed. You've may seen me write about this
before. I wrote about it in the appendix of one article you've read

http://peter.michaux.ca/articles/cross-browser-widgets

// Feature test that the Safari workaround will work
// This is *not* a browser sniff! Browsers other
// than Safari will use the workaround if they
// have the necessary features. This is not a problem.
// Tested Safari 1.0, 1.2, 1.3, 2.0 and they all
// need the workaround and all return typeof 'object'
// for unset global.onclick property.

My event library worked around this using DOM0 event handlers. That is
a bunch of ugly code that I'd like to eliminate almost purely for
aesthetic reasons but actually the workaround could clobber an
existing DOM0 handler. Also having the workaround as the comment above
says requires an onunload event which messes with Firefox's caching
system, I think.

These old Safari browsers were auto updated and I doubt there are even
many 2.x users now anyway. Maybe less than 0.1% of web users have one
of these browsers.

I could ignore the problem and Safari 2.x- users just get some buggy
behavior. This doesn't seem good enough.

You could argue that the default behavior of following the link should
be acceptable. In fact, maybe you did argue that once. I don't like
this rationalization and where my scripts are used I don't always have
complete control (over business decisions.) Sometimes there are
"working in groups" compromises that I have to make to move on in life
and not make enemies while belaboring a point about graceful
degradation.

What I am willing to do is just put either the Safari 2.0.3- users or
even the whole Safari 2.x- users down the degradation path. For them
the event library just wouldn't be defined at all. Ideally they would
have the same user experience as IE5 or NN4 users get: a script-free
user experience. (Note this is much different than what I wrote in the
previous paragraph where the Safari users would see a mostly
JavaScript enabled experience and sometimes see a broken JavaScript
experience as they would only be partly degraded and event handlers
would be firing.)

So I need to identify either Safari 2.0.3- or Safari 2.x- browsers. I
don't think there is an acceptable direct test for the problem of a
click or double click not being preventDefault'ed. The direct test
would require simulating a click or double click and seeing if the
page refreshes. That is too disruptive. So I was thinking about using
multiple object inference for objects only old Safari browsers have
and that no one in their right mind would ever add to another browser.
Yes it is sniffing but it is the most robust kind of sniffing if
enough really exotic objects are tested that only ever existed in
Safari.

I just need to find the right set of objects to test and I've
procrastinated for a long time.

Peter
 
P

Peter Michaux

I traded the forest for a garden (less deer to ruin my landscaping.)

I like when the deer walk past.

A couple of old Windows PC's for testing and a new Mac for doing
actual work.

Well I have one dusty Windows PC and Parallel's Desktop on my Mac so
that makes two PC's and a Mac. I'm all set. I do have a lab and didn't
even know it. I'm getting a white lab coat and raising my contracting
rates!

Peter
 
D

David Mark

Well, I've been using my JavaScript library, Fork, in production for a
couple years. It hasn't needed any fixes but I'd still like to update
it have a new API more to my current tastes. I'd also like to change
the way the feature testing works. The original Fork had these
isSupported functions to test if various parts of the API will work. I
think I'd rather wrap those bits of code in their feature tests so
that the bits of code are not even defined if they won't work.

Now the library is

FORK.Event.addListener = function(){};
FORK.Event.isSupported = function(){return test ? true : false;};

and a user would write

if (FORK.Event.isSupported()) {
  Fork.Event.addListener();

}

I'd rather have the library be

if (test) {
  FORK_addListener = function(){};

}

and then the user would write

if (typeof FORK_addListener == 'function') {
  FORK_addListener();

}

I've digressed a lot but if you have any thoughts on the above please
comment.

I would add a convenience function to check more than one at a time.
Something like:

if (FORK_features('addListener', 'createXhrObject')) {
...
}
What I need to test for is in the event library. Safari 2.0.3-, if I
remember correctly, had a bug where a click or double click event
could not be preventDefault'ed. You've may seen me write about this
before. I wrote about it in the appendix of one article you've read

http://peter.michaux.ca/articles/cross-browser-widgets
Yes.


// Feature test that the Safari workaround will work
// This is *not* a browser sniff! Browsers other
// than Safari will use the workaround if they
// have the necessary features. This is not a problem.
// Tested Safari 1.0, 1.2, 1.3, 2.0 and they all
// need the workaround and all return typeof 'object'
// for unset global.onclick property.

My event library worked around this using DOM0 event handlers. That is
a bunch of ugly code that I'd like to eliminate almost purely for
aesthetic reasons but actually the workaround could clobber an
existing DOM0 handler. Also having the workaround as the comment above
says requires an onunload event which messes with Firefox's caching
system, I think.

It disables fast history navigation in virtually every browser.
Libraries have been using the event for years, which boosted the
demand for Ajax. It's a backwards approach.
These old Safari browsers were auto updated and I doubt there are even
many 2.x users now anyway. Maybe less than 0.1% of web users have one
of these browsers.

I agree you should lose that workaround. As long as your design does
not break if clicks are not prevented, you don't have a problem.
Document this for history buffs and move on.
I could ignore the problem and Safari 2.x- users just get some buggy
behavior. This doesn't seem good enough.

Not even close to good enough. It's make or break at the design
stage. That's another reason I dislike general-purpose libraries as
they can only be designed once and exist to serve every conceivable
document past, present and future.

I wonder do you support IE quirks mode or XHTML or other things.
Neither makes sense to include IMO. I assume you do not support the
latter, but likely have some code to deal with the former.
You could argue that the default behavior of following the link should
be acceptable. In fact, maybe you did argue that once.

I'm sure.
I don't like
this rationalization and where my scripts are used I don't always have
complete control (over business decisions.)

What rationalization? And I don't see where this is a business
decision.
Sometimes there are
"working in groups" compromises that I have to make to move on in life
and not make enemies while belaboring a point about graceful
degradation.

Just show them what to adjust in their design, if possible. If
painted into the corner by the design, you should point out that the
next app should be designed differently. That may not be possible if
using a framework, which leads to an oft-repeated argument against
frameworks.
What I am willing to do is just put either the Safari 2.0.3- users or
even the whole Safari 2.x- users down the degradation path. For them
the event library just wouldn't be defined at all.

I wouldn't.
Ideally they would
have the same user experience as IE5 or NN4 users get: a script-free

NN4, yes. IE5, I can't see it. It doesn't even matter that virtually
nobody uses it. It's just the idea that simple HTML document
enhancements (e.g. form validation) should require IE6 or later.
user experience. (Note this is much different than what I wrote in the
previous paragraph where the Safari users would see a mostly
JavaScript enabled experience and sometimes see a broken JavaScript
experience as they would only be partly degraded and event handlers
would be firing.)

I didn't care for that scenario either.
So I need to identify either Safari 2.0.3- or Safari 2.x- browsers. I
don't think there is an acceptable direct test for the problem of a
click or double click not being preventDefault'ed. The direct test
would require simulating a click or double click and seeing if the
page refreshes. That is too disruptive. So I was thinking about using
multiple object inference for objects only old Safari browsers have
and that no one in their right mind would ever add to another browser.
Yes it is sniffing but it is the most robust kind of sniffing if
enough really exotic objects are tested that only ever existed in
Safari.

I just need to find the right set of objects to test and I've
procrastinated for a long time.

You are looking for a multiple object inference for Safari 2.x. I'm
sure you can come up with one, but I would consider other options.
 
P

Peter Michaux

I would add a convenience function to check more than one at a time.
Something like:

if (FORK_features('addListener', 'createXhrObject')) {
...
}

Yes that is a good idea.

I agree you should lose that workaround. As long as your design does
not break if clicks are not prevented, you don't have a problem.

It is not so easy to say that can be done, at least not easily. If it
can be taken care of in the library then it isn't necessary to worry
about it in every application.

Here is a really tiny example using a popup as that is a timely
example.

<script type="text/javascript">

if (FORK_features('addListener')) {
FORK_addListener(window, 'load', function() {
FORK_addListener(document.getElementById('testLink'),
'click', function(e) {
FORK_preventDefault(e);
window.open(FORK_getTarget(e).href);
})
});
}

</script>


<a href="http://images.google.ca/images?q=sara varone">link</a>


In the buggy Safari versions, both the popup and the window containing
the link will open the link's URL. So nothing is broken in terms of
the browser throwing an error, but the behavior is not optimal. If
Safari 2.x- was down the degradation path completely then there would
be no problems.

Yes I could use a onclick attribute and avoid the problem. This is
just an example. In more complex applications I often find using
addEventListener and attachEvent better than using the onclick
attribute.

Document this for history buffs and move on.




Not even close to good enough. It's make or break at the design
stage. That's another reason I dislike general-purpose libraries as
they can only be designed once and exist to serve every conceivable
document past, present and future.

I'm not trying to fill every need ever. Not even close. I'm just
trying to fill the "usual" needs. I know "usual" is up for huge debate
here on c.l.js. I think off c.l.js most people have the same "usual"
reasonably intuitively. Unfortunately they don't care about the others
outside the usual at all. I want the majority of users (something
along the lines of IE6+, FF2+, S3+, O9+) for HTML 4.01 transitional
pages to see the fully enabled version of the page and everyone else
to go down the degradation path cleanly.

I wonder do you support IE quirks mode or XHTML or other things.

I have nothing to support either and have never felt like I was
missing out.

Just show them what to adjust in their design, if possible. If
painted into the corner by the design, you should point out that the
next app should be designed differently. That may not be possible if
using a framework, which leads to an oft-repeated argument against
frameworks.

They won't want to design the application differently just because of
an old Safari. I don't blame them. It is relatively pointless. That is
another reason it is nice to tuck the degradation into the event
library. Then I know I've cared for Safari properly.
I wouldn't.

You wouldn't what?

Thanks for the ideas.

Peter
 
P

Peter Michaux

But "intrinsic event" properties (I assume you're talking about them),
e.g. - `elRef.onclick = fnRef` - are non-standard, aren't they?

I think he just meant the normal library wrappers for addEventListener
and attachEvent.

Peter
 
D

David Mark

But "intrinsic event" properties (I assume you're talking about them),

I'm not. I'm just saying most apps need only the most basic event
normalization.
e.g. - `elRef.onclick = fnRef` - are non-standard, aren't they?

Yes. That's why should include a disclaimer when using them for event
support detection. History is the only indicator of a correlation
between those properties and supported event types.
I thought it was one of the main reasons to avoid those.

In theory. It is the only reason I can think of. In reality, if you
only need one listener per type per element, they are the simplest and
best supported option.
 
D

David Mark

Yes that is a good idea.



It is not so easy to say that can be done, at least not easily. If it
can be taken care of in the library then it isn't necessary to worry
about it in every application.

Here is a really tiny example using a popup as that is a timely
example.

  <script type="text/javascript">

    if (FORK_features('addListener')) {
      FORK_addListener(window, 'load', function() {
        FORK_addListener(document.getElementById('testLink'),
                        'click', function(e) {
          FORK_preventDefault(e);
          window.open(FORK_getTarget(e).href);
        })
      });
    }

  </script>

  <a href="http://images.google.ca/images?q=sara varone">link</a>

In the buggy Safari versions, both the popup and the window containing
the link will open the link's URL. So nothing is broken in terms of
the browser throwing an error, but the behavior is not optimal. If
Safari 2.x- was down the degradation path completely then there would
be no problems.

Yes, that one is a poser. Personally, I'd avoid the popup. Also, the
popup may fail, so you can't cancel the default behavior in that case.
Yes I could use a onclick attribute and avoid the problem. This is
just an example. In more complex applications I often find using
addEventListener and attachEvent better than using the onclick
attribute.

Seems like it is only an issue for links that open windows. Why would
you need those? I can imagine a button that opens a window, but not a
link.
I'm not trying to fill every need ever. Not even close.

Yeah, I know. That's why I usually recommend your library when
pressed for a library.
I'm just
trying to fill the "usual" needs. I know "usual" is up for huge debate
here on c.l.js. I think off c.l.js most people have the same "usual"
reasonably intuitively. Unfortunately they don't care about the others
outside the usual at all. I want the majority of users (something
along the lines of IE6+, FF2+, S3+, O9+) for HTML 4.01 transitional
pages to see the fully enabled version of the page and everyone else
to go down the degradation path cleanly.

I don't like thinking in terms of specific browsers.
I have nothing to support either and have never felt like I was
missing out.

Certainly not. You were ahead of the curve on that. Nobody uses
XHTML (real XHTML), but you should document that standards mode
rendering is required.
They won't want to design the application differently just because of
an old Safari. I don't blame them. It is relatively pointless. That is

Definitely not if it will take any real doing. I can't see that it
would, but I have no idea what you are doing with these popups. The
degradation of the behavior isn't fatal and anyone using Safari 2.x
will have similar problems on most sites.
another reason it is nice to tuck the degradation into the event
library. Then I know I've cared for Safari properly.

I just don't care for throwing out the whole browser by object
inference (especially not for something like popup windows.)
Thanks for the ideas.

No problem. Just don't use them for popup ads. :)
 
P

Peter Michaux

Yes, that one is a poser. Personally, I'd avoid the popup.

Popups are just an example but they do happen to be a "business
requirement" where I work. It doesn't matter how much I warn against
them or point out they don't always work.

Seems like it is only an issue for links that open windows.

Not at all. There are many cases. Basically any case where a click and
following preventDefault are used. Form submission by XHR or regular
form submission is an example. I could fabricate an example like the
popup one above where the form would submit twice. That is not good if
modifying the database. Handling the Safari problem cleanly in the
library would be best so it is over once and for all, in my opinion.

No problem. Just don't use them for popup ads. :)

They aren't for ads. Popups are actually handy sometimes despite
popular abuse and following backlash. The paranoia about popups on
c.l.js is exceptionally high. ;-)

Peter
 
P

Peter Michaux

I'm not.  I'm just saying most apps need only the most basic event
normalization.


Yes.  That's why should include a disclaimer when using them for event
support detection.  History is the only indicator of a correlation
between those properties and supported event types.




In theory.  It is the only reason I can think of.  In reality, if you
only need one listener per type per element, they are the simplest and
best supported option.

Yes but do you base your event library code on DOM0 handlers? Some
libraries do. I don't because someone might go into the HTML when I'm
not looking and meddle with event attributes. I'd rather my JavaScript
code continues working without clobbering whatever someone else is up
to in there.

Peter
 
D

David Mark

David said:
David Mark wrote: [...]
Yes, but XHR normalization doesn't add up to much.  I do question
whether most apps need yet another "addEvent."
But "intrinsic event" properties (I assume you're talking about them),
I'm not.  I'm just saying most apps need only the most basic event
normalization.

I see. Which event normalization are you talking about?


Yes.  That's why should include a disclaimer when using them for event
support detection.  History is the only indicator of a correlation
between those properties and supported event types.

Just realized that I'm using them in CFT
<http://yura.thinkweb2.com/cft/> which is supposed to be an example of
"proper" feature detection for developers who use sniffing.

Nothing wrong with that. Just document the rationalization for the
assumption (and use it only when needed.)
But then I'm
also using `innerHTML` in it, which you said might bring false positives
into the picture.

That's bad.
It seems that intrinsic event handlers are like `innerHTML`;
Non-standard but are almost universally supported and are often the
simplest option, as long as you know what you're doing and are aware of
the consequences (although, PointedEars will probably recommend to
replace those with event attributes).

Yes, but I think you misunderstand PE's position.
 
D

David Mark

Popups are just an example but they do happen to be a "business
requirement" where I work. It doesn't matter how much I warn against
them or point out they don't always work.

Then somebody on the business side is making a mistake (not uncommon.)
Not at all. There are many cases. Basically any case where a click and
following preventDefault are used. Form submission by XHR or regular
form submission is an example.

I can't see that. I would use the submit event.
I could fabricate an example like the
popup one above where the form would submit twice. That is not good if
modifying the database. Handling the Safari problem cleanly in the
library would be best so it is over once and for all, in my opinion.



They aren't for ads. Popups are actually handy sometimes despite
popular abuse and following backlash. The paranoia about popups on
c.l.js is exceptionally high. ;-)

I just can't see using them at this point. What's wrong with a DIV?
 
P

Peter Michaux

I can't see that.  I would use the submit event.

If there are several buttons it would be much handier to just attach
to the buttons. Using the submit event means the button has to set a
global variable and then the submit handler reads that global to know
which button was clicked. This is an ugly solution and relies on the
single threaded nature of JavaScript.
I just can't see using them at this point.  What's wrong with a DIV?

Imagine you have a page of information and you can pop open a page
that contains a notepad. That notepad is a lot more handy if you can
see the original page since that is the page about which you want to
make notes. Having the notepad open in a tab or in a div is not as
handy. Sometimes popups are handy.

Peter
 
P

Peter Michaux

Yeah, I'll get rid of innerHTML when I get a chance.

Why do we hate innerHTML right now?
There should probably also be `isHostMethod` used, but I've seen too
many people roll their eyes, seeing verbosity that `isHostMethod`
brings. It's already hard enough to convince developers not to sniff;
I'm afraid to make tests look more frightening.

What are you working on where you are worried about frightening
developers?

Peter
 
P

Peter Michaux

We don't hate it :)

As I understand it, `innerHTML` is just an unstable component when used
in a feature test. The idea is to make test as simple as possible and
eliminate anything that can affect its outcome. `innerHTML` is
non-standard and so may cause false positives (if, for example, it's not
implemented or produces botched result).

Am I missing something?

I have used innerHTML with great success every time I've used it. The
DOM methods like createElement etc are very buggy and slow in
comparison.

Neat collection.

Of course, right now I'm interested in the Safari preventDefault
problem. Looking in your page

features.IS_EVENT_PREVENTDEFAULT_PRESENT = "preventDefault" in e

It isn't enough to just know that preventDefault is there. It is
necessary to know it works. I don't have that much paranoia except in
cases were a bug has been reported. For preventDefault a bug has been
reported. (If a bug hasn't been reported then I'm ok with just
checking presence of a feature.)

So what do you do about that?

Peter
 
D

David Mark

Will do.





Yeah, I'll get rid of innerHTML when I get a chance.

There should probably also be `isHostMethod` used, but I've seen too
many people roll their eyes, seeing verbosity that `isHostMethod`
brings.

Use the areHostMethods sequel.

They have visions of seeing it everywhere, which is not how it works
(only the lowest level code calls these methods.) Regardless, if an
app requires - for example - gEBI and gEBTN, a typical gateway would
look like:

if (areHostMethods(document, 'getElementById', 'getElementsByTagName')
{
...
}

....is that more or less verbose than:

if (document.getElementById && document.getElementsByTagName) {
...
}

I don't understand the oft-repeated hangup with keystrokes either (use
macros.) I guess you could rename areHostMethods to something like
$Z. :)
It's already hard enough to convince developers not to sniff;
I'm afraid to make tests look more frightening.

Seems most developers are blissfully unaware of what goes on under the
hood of their favorite library. The misconception is that these
behemoths can shift nimbly from UA sniffing to object inferences to
feature testing, while preserving consistent interfaces and behavior
across the latest versions of the major browsers. Predictably, that
hasn't been the case.

As for those who are trying to make it without crutches, they will
have to conquer their fear of... what exactly is it that frightens
them? The isHostMethod function couldn't be more straightforward. No
overloading, no objects to create, no memory leaks, nothing but a
function call with two well-defined arguments. How can jQuery (or the
like) *not* scare them? There's no way to tell if any of their
methods will work, just a list of "supported browsers", which have
been "well tested" by "many eyes."

I submit that those who profess such fears memorize rather than
program. Of course, relying on fuzzy memories of jQuery and/or
browser behavior should be a much scarier prospect. The difference is
in where the individual gets their information on browser scripting.
If it's the usual suspects (e.g. Ajaxian, A List Apart, blogs, books),
their fears are going to be out of whack.
 
D

David Mark

We don't hate it :)

I don't much like it.
As I understand it, `innerHTML` is just an unstable component when used
in a feature test. The idea is to make test as simple as possible and
eliminate anything that can affect its outcome. `innerHTML` is
non-standard and so may cause false positives (if, for example, it's not
implemented or produces botched result).

Am I missing something?

Not sure what you mean by false positives, but certainly the reliance
on innerHTML for testing features that don't require innerHTML is a
bad idea and can produce invalid results.

Let me know when you fix the innerHTML problem and I'll have a look at
it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top