I''ve been doing some profiling recently of a rather simple application. Its using the Morph function, which was leaking memory, i''ve fixed that but now it seems that over 60% of my applications time is spent either calling setStyle or camelize. 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. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Okay, so i''ve played around a little, my main concern is with the use on name.camelize() the camelize routine is horribly inefficient in Gecko (i havent tried other browsers). 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. On Feb 17, 10:27 pm, "Malard" <mal...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I''ve been doing some profiling recently of a rather simple > application. Its using the Morph function, which was leaking memory, > i''ve fixed that but now it seems that over 60% of my applications time > is spent either calling setStyle or camelize. > > 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.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 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----- --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
How can you detect different versions of the browser dynamically and compile them. You can easily change the user agent value that the browser sends to the server, but you cant change if certain parts of the javascript engine exist or not. So i''m pretty confident that javascript based checking is the only way to go. Another note. i did''nt know about prototype-core group, at www.prototypejs.org the mailing list directs here. On Feb 18, 2:47 am, Marius Feraru <altb...-9gptZ63fvgw@public.gmane.org> wrote:> -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > 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-------~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
> 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. ;-)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 :) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
The quote you made, was not from myself. I dont believe that the web server should decide how to serve the javascript. 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. On 2/18/07, Mislav <mislav.marohnic-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > 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. ;-) > > 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 :) > > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---