Posts Tagged ‘javascript’

Format JSON with jEdit

Thursday, January 14th, 2010

Sometimes I have to debug or check a json response from the server: I just paste the response to jEdit and reformat it with a macro (yes, I know about the online json beautifier and I think we did have a firebug extension for this, but still, it’s fun to see how flexible javascript macros are):

Download the json2.js from json.org, place it into your lib directory (see: startup.js), then use this ridiculously simple macro to reformat a valid javascript object (in buffer or selection):

(function(){
if (buffer.isReadOnly())
return;

var text = "",
selections = textArea.getSelection(),
bufferSelected = false,
obj;

if (selections.length == 1) {
text = textArea.getSelectedText(selections[0]);
} else {
text = textArea.getText();
bufferSelected = true;
}

obj = eval("(" + text + ")");
include(MACROLIBPATH + "json.org/json2.js");
textArea[bufferSelected ? "setText" : "setSelectedText"](JSON.stringify(obj, null, '\t'));
})();

You can download this and some of my other macros from here.

Javascript optimization: for vs while loop

Saturday, December 19th, 2009

Since it is nearly impossible to find up to date statistical data on the various javascript speedhacks (in google the first three ones are from 2003-2006), I decided to do a quick and dirty test to see how fast the while(i–){} method is (since for in should only be used with objects, I’m not going to test that, period).

This is 1000*1000 iterations, done 5 times and averaged (each one is relative to its own browser); first one is vanilla for, second is length property stored beforehand, third is reversed while as seen above:

chrome 3:  0: 100%  1:  42.86%   2:  41.07%
safari 4: 0: 100% 1: 50% 2: 50.11%
ff 2.0: 0: 100% 1: 69.07% 2: 45.09%
ff 3.0.3: 0: 100% 1: 82.37% 2: 48.44%
ff 3.5.6: 0: 100% 1: 153.56% 2: 154.9%
ff 3.5.6*: 0: 100% 1: 151.85% 2: 159.26%
opera 9: 0: 100% 1: 83.26% 2: 64.93%
opera 10: 0: 100% 1: 81.67% 2: 69.26%
ie8**: 0: 100% 1: 35% 2: 29%

*: portable install, no extensions
**: only one test, the rest did not work

Now, oh my, these are some interesting numbers. If you check this simple test directly, you can test for milliseconds – have some fun; my conclusions:

  1. First of all, Safari 4 (and bleeding edge webkit) is lightning fast. Honestly, I’m not even sure if I want to optimize there, because it’s unbeatable.
  2. Internet Explorer (6,7,8, you name it) is a shame; period. In version 8 I couldn’t disable the annoyingly short script execution timeout (which can be disabled in the registry for 5.5/6/7) and I did not want to do burst measurements via setTimeouts, so out of the six tests only the simplest worked and the durations are utter crap. No words can express my sadness seeing this underdog browser.
  3. To my greatest surprise Firefox 3.5 literally hates these optimization attempts. I totally don’t understand what’s going on, but using while just for making a damn loop “faster” seems a very very bad idea here.

While and array length prefetching is (and shall be) faster, but we have enough quirks here to have a serious headache. Why? As we can see, hoping for the best while using “while” is not the way to go (it should be, I admit it though); a general solution would be using a wrapper function (forEach/each), BUT that would be much slower (because of the function callback) – while being nicer. Unless in one case, which is the most common case: arrays and native forEach – Webkit, Opera, Firefox, they all support it. Internet Explorer does not – nothing new.

In the end this means that a clean forEach wrapper function (like with the javascript libraries) speedwise is not good (and I’m being very polite here), but checking for the native forEach (in case of arrays) and deciding which solution to use in place is a waste of code and is serious readability rape.

So, in the end, though only with a tiny margin, I still say that premature optimization is evil – we have no holy grail method in the world of browser quirks; and even if we have, it will go sour in a couple of months.

jQuery slideDown jerkyness

Sunday, September 6th, 2009

I do have problems with jQuery effects: last time it was effects not finishing (okay launched 50+ backgroundCoor animation effect at once, but still) now it is the slideDown: on the very end of the animation it tends to skip the last 10-20 pixels.

One possible solution is to get the container’s height, save it into somewhere (if you’re lazy like me, then just add it as an attribute), set it to overflow hidden and animate to zero height. To slideDown, just animate back to the stored height:

$("#posts .postwrap").each(function(){ $(this).attr("height", $(this).height()); });
$("#posts .postwrap").css({overflow: "hidden"}).animate({height: 0}, 1000, callback);

Now, this is getting pretty ugly, yet we’re still not there; why? Because height() doesn’t work very well with margins, so instead of collapsing .post items, I had to add a .postwrap outer wrapper; now this works with the above (even though this trick doesn’t solve the issue with slideDown function) :(

Pure – javascript template

Tuesday, September 1st, 2009

Pure is an unobtrusive javascript templating engine: I gave it a try in a smaller pet project but it makes my tiny little brain hurt. I constantly feel that I have to act like the templater wants me to act: clean inputs, mess with the incoming jsons,  preformat data, do additional helping with jQuery, add sugar etc.

Probably it’s just my old fashioned brain, but I do like the usual templating toolset, and with the textarea trick or with some sort of prerendering it’s not that bad. Anyway, I’ll keep on trying: maybe I can get the hang of it.

jQuery document ready vs Safari

Thursday, May 7th, 2009

When I had been fiddling with the tweenmenu I had to realize that sometimes offsetLeft or position().left doesn’t work in Safari/Chrome – like many others (Paul Carey, Dave Methwin, Yereth) I came to the conclusion that the problem is with jQuery document.ready though it is very very rare (assuming one moved all the css before scripts!!), but sometimes it does happen (like others noted in the bugtracker).

After some experimenting and deleting 99% of this post :) – adding an empty style tag dinamically magically fixes the problem:

(function(){
if (!/WebKit/i.test(navigator.userAgent)) return;
var el = document.createElement("style");
el.type = "text/css";
el.media = "screen, projection";
document.getElementsByTagName("head")[0].appendChild(el);
el.appendChild(document.createTextNode("_safari {}"));
})();