IE9 Javascript slower than IE8 - that's weird! - javascript

I'm having difficulty in explaining why the following code runs slower in IE9 than IE8!
Here's some test code that runs smoothly in about half a second in (latest) FF/Chrome/Safari on OS X, WinXP, and Win7 plus IE7 & 8 on WinXP (for simplicity I removed the tweak that makes it work in IE6).
For some reason I can't explain, it's awful in IE9, slow and clunky. Reducing the time for the setTimeout makes it a bit quicker but no less jerky.
I've tried removing and benchmarking a number of what might be the choke points (Math.min for example ... all with no change.
I'm stumped ... can anyone please point me in the right direction?... preferably one that does not require browser-sniffing?
Here's the test code ...
<div id = 'panel' class='noShow' style='background-color: #aaa;'>
<div id = 'wrapper' class='slideWrapper'>
<p>xxxxxxxxxxx</p><p>xxxxxxxxxxx</p><p>xxxxxxxxxxx</p><p>xxxxxxxxxxx</p><p>xxxxxxxxxxx</p><p>xxxxxxxxxxx</p><p>xxxxxxxxxxx</p><p>xxxxxxxxxxx</p><p>xxxxxxxxxxx</p><p>xxxxxxxxxxx</p>
</div>
</div>
<script type = 'text/javaScript'>
var e = document.getElementById('panel');
var w = document.getElementById('wrapper');
w.style.overflow = 'hidden';
w.style.height = '1px';
var sh = w.scrollHeight;
show();
function show()
{
setTimeout(function()
{
w.style.height = Math.min(sh, (w.offsetHeight + Math.ceil(sh/15))) + 'px';
if(
(w.offsetHeight < sh)
)
{
show(e);
}
else
{
w.style.height = 'auto';
}
}, 20);
}
</script>

IE9 defaults to software rendering on VMware Virtual Machines (as of 7/8/2011) there is supposed to be a hotfix released in the near future but no timeline is given per this blog post.

Are you running the 64 bit version of IE 9 or the 32 bit version? The 64 bit version is not running Chakra which is the optimized JavaScript engine from the 32 bit version

There are always odd performance variations when running in a virtualized environment. The selection of drivers and how the software offloads the processing will have an impact. Have you tried updating the drivers on your system?

Related

Why is inline Javascript over 10 times slower than in the Console, in Chrome 57?

Using Debian 8, the latest version of Chrome (Chromium) available from the standard repositories is 57. I've been doing some very simple speed tests and obtaining strange results.
When I run the following one-liner in the Console, it completes in about 1 second:
var a = 0;for (var i = 0; i < 10000000; i++) {a = Math.sqrt(33 * Math.random());}console.log(a);
But if I create a button with an onclick handler containing the same code, execution takes more than 15 seconds:
<button onclick="var a = 0;for (var i = 0; i < 10000000; i++) {a = Math.sqrt(33 * Math.random());}console.log(a);">Test</button>
Can anyone shed some light on why this is?
EDIT:
If I separate the code out into a function in a script tag, and reference that function in the button onclick handler, it works as fast as in the Console, a little faster actually.
Especially V8 focused its performance improvement on "every day code", so they took some popular webpages and tried to make them load as fast as possible. That means: if you will behave like the crowd your code will run fast, if you do some special stuff (like inline js) it will run slow because no one put the effort into optimizing as its not worth it.
More information can be found on the V8 GitHub wiki (albeit out of date), while their benchmarks README specifically mentions 50 popular pages that were tested.

Self-written rollout animation stuttering in Firefox

some time ago I started to write some code in JavaScript to learn it a little bit. I picked a rollin/rollout animation as 'project'. (I know about JQuery's slideDown/slideUp, but I wanted to work with pure JavaScript.)
I finished my effect, and the result looks pretty good in all major browsers except Firefox (tested versions 22.x to the latest (25.0.1)). In Firefox, the rolling (in and out) stutters while it rolls smoothly in Chrome, Opera, and Internet Explorer.
The general approach is (unsurprisingly) to have an element's style.height (or width) attribute increased/decreased several times by some pixels over a given time. To avoid calculating sizes every time the effect takes place, I calculate them one time and place them in an array (first item (0 + stepSize), last item wanted height/width). The decrease of the element's height is done by this function:
var verticalRollInWorker = function(step) {
if (step > 0) {
$(btt).style.height = stepSizes[step - 1];
setTimeout(function() { verticalRollInWorker(step - 1); }, delay);
} else {
$(btt).style.display = "none";
$(btt).style.height = 0;
// Enable roll out effect:
stateChange(false);
if (afterFullRollIn != null) {
afterFullRollIn();
}
}
}
In the particular example, I'm using 20 steps over 400ms. The step sizes in the array are rounded to integers, that's why the last step just sets 0 - to handle rounding differences.
(For convenience, I wrote my own $(element) helper, there's no JQuery involved here.)
I tested Firefox without Add-Ons, no difference.
I highly appreciate any help you can provide :)
One problem that I noticed in the above code is that you used $(btt). So, every 20s when the function is iterated, the browser needs to obtain the jQuery object. You could rather store it into a variable say 'var BTT=$(btt);' and use this BTT. Fetching jQuery object is a time consuming task.
Since you are using setTimeout(), the function will be executed every 20ms regardless of the completion of the current execution, this may also cause a drag. As Dagg Nabbit said, you could use setInterval() instad of setTimeout.
Another possible reason might be browser-reflow. I made a personalised scrollbar, and found browser reflow was noticeably greater in my FF than Chrome or IE. This depends on the size of the element, DOM tree depth, overflow property, and more...
And again use this code and see if it is fixed. reduces the subtraction into 1 code.
var BTT=$(btt).get(0);
var verticalRollInWorker = function(step) {
if (step > 0) {
step--;
BTT.style.height = stepSizes[step];
setTimeout(function() { verticalRollInWorker(step); }, delay);
}
else {
BTT.style.display = "none";
BTT.style.height = 0;
// Enable roll out effect:
stateChange(false);
if (afterFullRollIn != null) {
afterFullRollIn();
}
}
}
Further Comments can be made only after seeing a live example.
Regards.

HTML 5 Canvas / requestAnimationFrame broken in Safari 7.0?

Can someone tell me why this suddenly isn't working anymore in Safari 7.0? Is it a bug in Safari?
It has been working fine in previous versions of Safari and also works in all other browsers I've tested.
(function animloop(time){
var delta = (time - currentTime) / 1000;
currentFrame += (delta * fps);
var frameNum = Math.floor(currentFrame);
if (frameNum >= totalFrames) {
currentFrame = frameNum = 0;
}
requestAnimationFrame(animloop);
drawFrame(ctx, img, 104, 124, frameNum);
currentTime = time;
})(currentTime);
JSFiddle here: http://jsfiddle.net/XjCYN/
Code taken from this excellent article: http://awardwinningfjords.com/2012/03/08/image-sequences.html
Thanks! :)
Andreas
Yes. I've personally confirmed that you're correct in asserting this is broken in Safari 7 / Mavericks, yet functional in Chrome and pre-Mavericks Safari.
There are numerous bugs related to HTML5 canvas and video elements in Safari 7 / Mavericks, this included.
I have reported a bug to Apple regarding the issues with the video tag and have referenced this stack overflow question as an "Additional Note".
I suggest doing the same over at http://bugreport.apple.com and maybe we can convince Apple to resolve these issues.
In case you want to reference my bug report within yours, the ID in their system is 15363385 -- and here's a copy of the report in a gist: https://gist.github.com/keyvanfatehi/7259921

Javascript: Overcoming standards mode differences

The problem I am having is with this code:
function scrollLeft() {
document.body.scrollLeft -= scrollSpeed;
}
It works perfectly in Chrome and Safari but in IE and Firefox it is doing nothing. I have narrowed this down to the fact that in Firefox and IE standards mode they accept document.documentElement.scrollLeft instead of document.body.scrollLeftand my page is being rendered in standards mode.
Please note that I run this script at an interval of 10ms so I can't afford to have a large clunky detection script running each time this function needs to perform.
Does anyone know a cross browser way or an extremely light way of overcoming this? I am using the jQuery library in this script but Firefox and IE aren't recognising $('body').scrollLeft() either and I'm not sure why that is.
KISS: use scrollBy
window.scrollBy( -scrollSpeed, 0 )
Use the logical or operator to fall back.
document[body || documentElement].scrollLeft -= scrollSpeed
This is very quick, so very little overhead for you.
For bonus points do this instead
scrollLeft = (function () {
var docEl = document[body || documentElement];
return function () {
docEl.scrollLeft -= scrollSpeed;
};
})();
This only finds the relevant element reference once and closes over the temporary variable that holds it.

javascript: detect if XP or Classic windows theme is enabled

Is there any way to detect which windows XP theme is in use?
I suspect that there is no specific api call you can make, but you may be able to figure it out by checking something on some DOM element, ie feature detection.
Another question: does the classic theme even exist on windows vista or windows 7?
edit - this is my solution:
function isXpTheme() {
var rgb;
var map = { "rgb(212,208,200)" : false,
"rgb(236,233,216)" : true };
var $elem = $("<button>");
$elem.css("backgroundColor", "ButtonFace");
$("body").append($elem);
var elem = $elem.get(0);
if (document.defaultView && document.defaultView.getComputedStyle) {
s = document.defaultView.getComputedStyle(elem, "");
rgb = s && s.getPropertyValue("background-color");
} else if (elem.currentStyle) {
rgb = (function (el) { // get a rgb based color on IE
var oRG =document.body.createTextRange();
oRG.moveToElementText(el);
var iClr=oRG.queryCommandValue("BackColor");
return "rgb("+(iClr & 0xFF)+","+((iClr & 0xFF00)>>8)+","+
((iClr & 0xFF0000)>>16)+")";
})(elem);
} else if (elem.style["backgroundColor"]) {
rgb = elem.style["backgroundColor"];
} else {
rgb = null;
}
$elem.remove();
rgb = rgb.replace(/[ ]+/g,"")
if(rgb){;
return map[rgb];
}
}
Next step is to figure out what this function returns on non-xp machines and/or figure out how to detect windows boxes. I have tested this in windows XP only, so vista and windows 7 might give different color values, it should be easy to add though.
Here is a demo page of this in action:
http://programmingdrunk.com/current-projects/isXpTheme/
Interesting question. The only thing that comes to mind is checking the size of a default button. It is styled differently in both themes, and I suppose it has a different size. This could be half-way reliable if you give the button a fixed text size.
I'll start the XP virtual machine and check whether the sizes actually differ.
Update: They do differ.
Google "I'm feeling lucky" button
in classic skin: 99 x 23.75 (sic!) pixels
in XP skin: 97 x 21.75 pixels
A second, less reliable approach that comes to mind is giving an element a CSS system colour and then parsing the resulting computed colour. In classic mode, the ButtonFace property will have a specific shade of grey and I think a different one in the default skin. Again, would have to be tested.
Update: they differ, too.
ButtonFace CSS system colour
in Windows classic skin: #D4D0C8
in XP skin: #ECE9D8
Obviously, both approaches will break if the user did any customization to colours and/or font sizes. The font size approach is the more reliable IMO, as there are fewer people playing around with that.
You would, of course, have to have comparison tables for all Windows generations, as presumably, the values for classic and default skin will differ.
just to give a starting point look for IsThemeActive()

Categories

Resources