So i'm just looking at the setStyle now, while i try and do some self
optimisation to the code, maybe people would be willing to see how
they could optimise it further. One of the first things that strikes
me is that on every call we're finding out what version of the browser
we're in.
Would'nt it make sence to do this on page load once, then just check
variables.?
setStyle: function(element, style) {
element = $(element);
for (var name in style) {
var value = style[name];
if(name == 'opacity') {
if (value == 1) {
value = (/Gecko/.test(navigator.userAgent) &&
!/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
0.999999 : 1.0;
if(/MSIE/.test(navigator.userAgent) && !window.opera)
element.style.filter = element.getStyle('filter').replace(/
alpha\([^\)]*\)/gi,'');
} else if(value == '') {
if(/MSIE/.test(navigator.userAgent) && !window.opera)
element.style.filter = element.getStyle('filter').replace(/
alpha\([^\)]*\)/gi,'');
} else {
if(value < 0.00001) value = 0;
if(/MSIE/.test(navigator.userAgent) && !window.opera)
element.style.filter = element.getStyle('filter').replace(/
alpha\([^\)]*\)/gi,'') +
'alpha(opacity='+value*100+')';
}
} else if(['float','cssFloat'].include(name)) name = (typeof
element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
element.style[name.camelize()] = value;
}
return element;
},
Please comment.
I came up with this:
Index: prototype.js
===================================================================
--- prototype.js (revision 6770)
+++ prototype.js (working copy)
@@ -9,7 +9,11 @@
var Prototype = {
Version: '1.5.0',
BrowserFeatures: {
- XPath: !!document.evaluate
+ XPath: !!document.evaluate,
+ isIE: false,
+ isGecko: false,
+ isKHTML: false,
+ isKonquerer: false
},
ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
@@ -1393,23 +1397,28 @@
element = $(element);
for (var name in style) {
var value = style[name];
- if(name == 'opacity') {
- if (value == 1) {
- value = (/Gecko/.test(navigator.userAgent) &&
- !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
0.999999 : 1.0;
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
+ if(name === 'opacity') {
+ if (value === 1) {
+ value = (Prototype.BrowserFeatures.isGecko && !
Prototype.BrowserFeatures.isKonqLike) ? 0.999999 : 1.0;
+ if (Prototype.BrowserFeatures.isIE && !window.opera) {
element.style.filter =
element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
- } else if(value == '') {
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
+ }
+ } else if (value == '') {
+ if(Prototype.BrowserFeatures.isIE && !window.opera) {
element.style.filter =
element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+ }
} else {
- if(value < 0.00001) value = 0;
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
- element.style.filter =
element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
- 'alpha(opacity='+value*100+')';
+ if (value < 0.00001) {
+ value = 0;
+ }
+ if (Prototype.BrowserFeatures.isIE && !window.opera) {
+ element.style.filter =
element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
'alpha(opacity='+value*100+')';
+ }
}
- } else if(['float','cssFloat'].include(name)) name = (typeof
element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
- element.style[name.camelize()] = value;
+ } else if(name === 'float' || name === 'cssFloat') {
+ name = (typeof element.style.styleFloat != 'undefined') ?
'styleFloat' : 'cssFloat';
+ }
+ element.style[name] = value;
}
return element;
},
@@ -2513,4 +2522,13 @@
}
}
-Element.addMethods();
\ No newline at end of file
+Element.addMethods();
+
+(function(browserAgent) {
+ Prototype.BrowserFeatures.isGecko = /Gecko/.test(browserAgent);
+ Prototype.BrowserFeatures.isIE = /MSIE/.test(browserAgent);
+ Prototype.BrowserFeatures.isSafari = /Safari/.test(browserAgent);
+ Prototype.BrowserFeatures.isKonqLike = /Konqueror|Safari|
KHTML/.test(browserAgent);
+ Prototype.BrowserFeatures.isKonq = /Konqueror/.test(browserAgent);
+ Prototype.BrowserFeatures.isKHTML = /KHTML/.test(browserAgent);
+})(navigator.userAgent);
\ No newline at end of file
Ideally the isX values could be used throughout prototype aswell. With
these changes i reduced the cpu load of my app by around 30%, the only
'loss of functionality' is the ability to put text-align or
uncamelized values in setStyle.
But i've always camelized the values so i dont have to wrap the key in
the object with quotes anyway.
Malard wrote:
> One of the first things that strikes me is that on every call we're
> finding out what version of the browser we're in.
Which is an already well known pile of crap. Any user-agent based validation
is feeble, but for one reason (or another) we still have some bytes based on
this clumsy checking. Hopefully we'll get rid of them sooner or later. But
let's keep'em to minimum for now, so please don't promote such kludges ;-)
> Would'nt it make sence to do this on page load once, then just check
> variables.?
Wouldn't it make even more sense for instance to skip doing all these
checks? How? By dynamically compiling different versions of those methods
based on the capabilities of the browser running them. ;-)
Anyway, I concur, setStyle can really be a PITA to folks (ab)using s.a.u
Effect.* ;-)
Prototype-core should be a better place for discussions on this topic.
cheers
- --
Marius Feraru
-----BEGIN PGP SIGNATURE-----
iD8DBQFF175YtZHp/AYZiNkRAimOAKCWynWShH0FKqWOTqow/i2bIpCoXACg9/I+
sUytngjcxFzQXBRfCY9ziN0=
=N8md
-----END PGP SIGNATURE-----
Another note. i did'nt know about prototype-core group, at www.prototypejs.org
the mailing list directs here.
Well, duh! ;-P
see http://dev.rubyonrails.org/ticket/6696
I agree that we should move this discussion to the core ML. Malard,
there was more than one link on http://prototypejs.org/discuss :)
As for optimisations, you use include alot, its incredibly expensive
to use that function when just looking for 2 items in array.
I was doing some tests, and the cheapest way to do this was to use an
if statement,
i.e if (foo === 'bar' || foo === 'bar2') {}
Do you think instead of just using rubyesque functions for the sake of
using them over performance is the best action to take, or should code
used in prototype use the fastest applicable.