SharpGIS

#GIS from a .NET developer's perspective

Internet Explorer 8 whitepapers


I was looking into some of the IE8 issues we are having, and found this great site full of Microsoft white papers on IE8.

http://code.msdn.microsoft.com/ie8whitepapers

There are a lot of nice tips and tricks, both about what to be aware of that might have broken your website in IE8, but also tips and tricks on how to optimize your code to utilize some of the new features of IE8.

Opacity NOT supported
IE8 beta 1 does not support adding semi-transparency to any object, neither by using the proprietary filter object or using the CSS3 opacity style property. However, I found this interesting comment in the CSS2.1 compliance paper:

While one of Internet Explorer 8 Beta 1 for Developers' main goals is CSS 2.1 compliance, it is also forward looking towards CSS3. […] Internet Explorer 8 hopes to implement some of the most requested CSS3 features by web developers and designers'.

'opacity' is part of CSS3, and there is a feature request for it on Microsoft connect, and has already gotten a fair amount of votes. Although everyone cannot submit bugs, everyone can vote, so go vote for this missing feature here!

See update here 

VML NOT supported
Microsoft heavily Improved Namespace Support, but I think they didn't think about where that leaves VML. Basically there is no VML support (or SVG for that matter). For GIS apps this is a must. I would prefer seeing an SVG engine instead (saves us having to make two graphics APIs), but VML will do. You can vote for it here.

Here are a couple of things I found interesting in the white papers that I post here for my own reference, but you might find them useful too:

Outline (CSS2.1 compliance paper)
Outline allows you to highlight an element without affecting its size or the layout of the rest of the web page. You can think of outline as an enhanced border that is allowed to overlap other elements without changing the layout of a page. An outline is drawn right outside the border edge, and unlike the border attribute, it won't cause the size of objects to change and move around.

Syntax is the same as with border. Example:

         <div onmouseover="this.style.outline='5px solid yellow';" onmouseout="this.style.outline='';">

or

         myElement.outline = '5px solid red';

An interesting property of ‘outline' is the ability to set the color to invert. This causes the outline to take on the color which is the inversion of the pixels it is overlapping. This guarantees that the outline is always visible, no matter what type of element (even an image) it overlaps. Here is an example of an element with color set to invert: div { outline: thick solid invert }

document.getElementById (DOM Core Improvements)
In Internet Explorer 7, this method searches for and returns the first element that has an ID attribute or name attribute that case-insensitively matches the parameter string.

In Internet Explorer 8, this method finds only elements that have ID attributes that match the given parameter value in a case-sensitive manner. (ID attributes should be interpreted as case-sensitive as per the HTML 4.01 specification).

If you tested with FireFox and do the same in both browsers, this might not be an issue for you, since FireFox is case-sensitive and doesn't use the name tag.

Selecting elements by class (Selectors API)
You can now look up elements very fast by using their class name. So if you know you are doing a lot of searching for specific elements, give them a unique class name and search for them using:

var oneElement = document.querySelector('myClassName');
var elementCollection = document.querySelectorAll('myClassName');

Search for multiple classes at once:

var elementCollection = document.querySelectorAll('myClassName1, myClassName2');

You can limit the scope of the search by using the querySelector/querySelectorAll methods on the individual elements.

Neat! This is one API I hope the other browser vendors will copy!

Switching to IE7 mode (Selectors API)
You probably already know this one, but add this metatag to the page, and everything that works with IE7, should work with IE8 (but this is cheating ;-)

<meta http-equiv="X-UA-Compatible" content="IE=7">

Looping through elements within a node (Platform Performance Improvements)
Modify any chain of lookups to cache the intermediate values, so that the final lookup is the only one made repeatedly (this one is not really new to IE8, but IE8 introduces some internal caching of nodes to improve look-up).

Bad:

function badLoop(div1) {
    for(var i=0; i < div1.parentNode.childNodes.length; i++) {
        var node = div1.parentNode.childNodes[i];
        // Do something with node.
    };
}

Better:

function betterLoop(div1) { // Cache length and array to prevent multiple lookups.
    var childLength = div1.parentNode.childNodes.length;
    var childNodes = div1.parentNode.childNodes;
    for(var i=0; i < childLength; i++) {
        var node = childNodes[i];
        // Do something with node.
     };
}

Use the nextSibling method to traverse the children of an element. For example, improve betterLoop with this (nextSibling is a new property, and this is very similar to the best practice for traversing XML nodes in .NET):

function bestLoop(div1) {
    for(var node = div1.parentNode.childNodes[0]; node != null; node = node.nextSibling) {
        // Do something with node.
    }
}

String concatenation (Platform Performance Improvements)
We were taught to use Arrays for joining strings efficiently. Now we don't have to worry about that anymore:

 Before:

var smallStrings = new Array(); // Fill array with smaller strings 
var largerString = smallStrings.join('');

After:

var smallString1 = "string1";
var smallString2 = "string2";
// String concatenation using the "+" operator
var largerString = string1 + string2;

Working with arrays (Platform Performance Improvements)
Array now comes with built-in Push and Pop methods.

var standardArray = new Array();
standardArray.push("Test String");
standardArray.pop();

More connections for broad-band users (Better AJAX Development)
So here's actually one where Microsoft breaks with the standards:

 "An increasing number of users have broadband connections, so client-side bandwidth is not always a gating factor for performance. Typically, the time required to set up a connection and send a request dominates the time spent retrieving individual objects. The limit of two connections was set by the HTTP 1.1 specification (RFC 2068). By increasing the number of concurrent connections, Internet Explorer 8 Beta 1 for Developers allows Web sites to amortize that cost and churn through the list of pending objects more quickly, leading to an increase in user-perceived download time. Internet Explorer 8 Beta 1 for Developers consequently includes logic that detects whether the connection is narrow-band or broadband and increases the number of connections per host to six if it's a high speed connection. This maximum number of connections applies to any connection to a Web server, not just to downloads."

Checking browser version in IE8

IE8 comes with an "Emulate IE7" button, which will revert the page back to run as IE7. This is great for developers who can quickly test their apps in both versions (I just wish we could have an IE6 button too!).

Furthermore you can place a tag in the page that will force IE8 to render the page as IE7 would have. However this poses a problem. Lets say you make some javascript that takes IE8 into account with version checking, but the page has this IE7-compatibility tag embedded. The JavaScript browser version check would still report v8. Instead for IE you should use 'document.documentMode' to get the version number. That means that if you set your browser to run as IE7, this would return version 7 (even though it really is 8), and if you set in quirks mode, you will be getting v5. It would be safer to adjust your javascript using this property.

I ran some few tests on the fresh IE8 beta1. It still looks pretty much like IE7. This blog runs with only one minor problem. I have a gallery page that relies on AjaxControlToolkit, and this really broke on IE8. Hopefully the AjaxControlToolkit team will quickly get all those issues fixed.

There are 4 IE8 specific sessions at the Mix conference. Keep an eye on them at the Mix Website when they come online (about 24 hours after the session):

  • BCT08 - Welcome to Internet Explorer 8  Wed March 5 at 1:30 PM to 2:45 PM
  • CT07 - Cross-Browser Layout with Internet Explorer 8  Wed March 5 at 3:00 PM to 4:15 PM
  • T21 - Integrating Your Site With Internet Explorer 8  Thursday March 6 at 8:30 AM to 9:45 AM
  • T04 - Developing Cutting Edge Web Applications With Internet Explorer 8  Friday March 7 at 8:30 AM to 9:45 AM
  • Here's a picture from the first session, showing the Acid2 test:

    Visual Studio 2008 JavaScript Intellisense…

     …well maybe not for webcontrol users.

    One of the most spoken-of features of Visual Studio 2008/Orcas is the new JavaScript Intellisense that helps the client-side developer. I’m very excited about this new feature, and put a lot of effort in documenting my JavaScript with code summaries so that I will get the full benefit when VS2008 ships.

    I have been struggling to get this to work with some custom controls that emit JavaScript into the page. The JavaScript is fully documented and each file header references other assembly-embedded JavaScript files, just like the documentation tells me to do it. The problem was that I was getting no Intellisense at all for these scripts, unless I manually inserted them into the page. I also made sure that these commented JavaScript files (I also have compressed/stripped scripts embedded) of these scripts was actually registered during DesignMode.

    I was reading a blog-post the other day stating that Intellisense is provided for scripts that are included in the page either as a ScriptReference with the ScriptManager, or as a normal HTML script tag in the page. My controls did just that during the PreRender events.  I emailed one of the bloggers about this, and guess what… this is not supported. If you drag a webcontrol onto the page that emits JavaScripts to the page, you are NOT getting Intellisense for those JavaScripts. So much for building a fully documented JavaScript API.

    The reason is performance and security. For once they don’t want to execute user code on the client by rendering the control. But hey wait… isn’t that what is already happening in design time? The controls are rendered with specific design time layout, thus executing user code. OK VS is not doing it in the code editor but in the designer, but what's the difference from a security standpoint? Or could we at least get to allow certain assemblies we trust to do this? With regards to performance, I would think that either you want Jscript Intellisense or not, and if you want performance, you would just go and disable the Jscript Intellisense. They also seem to have nailed this one pretty well with JScript Intellisense being generated in the background while you're coding.

    So the proposed workaround is to manually add a ScriptReference to each script using a ScriptManager. There are just two problems to that:

    • You rarely know the full name of the embedded script, and using Reflector to find is often a violation to the EULA’s, and furthermore the name or scripts might change with each release/service pack. -not to mention that it's not very user friendly.
    • Secondly, who says I even have a ScriptManager or want one on the page? Partial Postbacks have longer page life cycles and transmit a lot more data than callbacks, so I might just want to stick with the good old lightweight callback model, or I might not even need any AJAX functionality at all.

    The funny thing is that the reply I got from Microsoft started out with saying that they get this question a lot, so there obviously is a demand for it.

    I would have to wait 3+ more years for the next Visual Studio release, to harvest the benefit of all my code summaries... '-(

    I actually found this other bug trying to get this thing above to work, and at least that is getting some attention. So before you start playing with JString Intellisense in beta2, don't put your classes inside namespaces.

    Tools I use for JavaScript and AJAX development

    Below is a list of some of my most used features in various web developer tools. The tools can do so much more than I described here. Many of the features are somewhat hidden, so perhaps there’s a few things you might find useful too.

    Feel free to share any of your favorite features in a JS and AJAX tool in the comment section below.

    Microsoft’s Visual Studio.NET

    The tool I use by far the most is Microsoft’s Visual Studio.NET 2005. Its script debugging features far surpasses anything I’ve seen in any other tool. The downside is that this only works for Internet Explorer. What I wouldn’t give for this to work with FireFox too.

    The debugging experience is as good as the debugging in a .NET application. You get breakpoints, watches, object inspection and manipulation, step-into/over and so on.

    This feature is somewhat hidden, because you need to go through a few hidden steps to enable it (this will change with VS2008).

    First you need to enable script debugging in Internet Explorer. Go to internet options, and uncheck “Disable script debugging (Internet Explorer)”.

    Then go to “View – Script Debugger – Open” and select a running instance of Visual Studio .NET.

    In Visual Studio, go to “Debug – Windows – Script Explorer”. This will bring up the window with the loaded page and scripts. Double-click any of the files in the script explorer to open it and set breakpoints, create watches, inspect objects etc. Open the “Immediate window” to execute any JavaScript you enter. Note that these features only are available while you are at a breakpoint.

    A little quirk compared to debugging a .NET application is that you can only hover the mouse on the root object, and not on its sub properties. The workaround is to select the object to get its value, as shown above. The good thing is that this even works on methods, so if you select an object, its method and the ending enclosing parentheses, the tooltip will show you the returned value from that method.

    If you are developing a web application in VS.NET and run it in debug more, VS.NET will automatically attach to the browser process if you have enabled script debugging.

    FireBug

    My favorite tool for debugging JavaScript in FireFox is FireBug. It’s the Swiss army knife of web development in FF. One of the cool features that a colleague of mine brought to my attention was a neat little feature for tracking all events that happen on a selected DOM element. This is great for analyzing which events are available for listen for, see the order that events are fired etc.

    To use this feature, choose the HTML tab and browser to the element you want to track. Right-click it and select “Log events”.

    Switch to the Console tab and try moving the mouse over the element and you will see a continuous output of all events occurring on the element:

    You can also inspect the properties of each event by clicking them:

    Nikhil’s Web Development Helper

    Nikhil Kotari has created a great little plug-in for Internet Explorer to assist primarily AJAX development. The most used features it the request logger, that logs all HTTP requests and provides you with some serializers for interpreting the responses. Deserializers included by default are Text, Hex, Image, Microsoft AJAX Partial Postbacks and JSON. The JSON and Partial postback deserializers gives you a nice little tree-view for inspecting the AJAX responses.

    The newest release also features a neat JavaScript object class browser. It interprets JavaScript objects in memory and shows them in a familiar Visual Studio/C# like object browser.

    IE developer toolbar

    IE developer toolbar is a useful tool for DOM inspection and manipulation. My favorite feature here is that it enables me to select any element and modify the DOM and CSS properties on the fly. This gives you a quick trial-and-error approach to getting your CSS to do what you want without the need for modifying HTML and refreshing the page.

    It also gives you quick access to clearing the cache, generating image reports, save out the loaded and the generated HTML, a measure tool, and a bunch of other useful tools for inspecting the page.

    Fiddler Tool

    Fiddler tool inspects all http request and responses from all running applications. I use this for optimizing responses by checking that gzip encoding is used and pages that should be cached is cached (inspect cache header and result code):

    This tool is VERY powerful and also includes scripting, altering request/responses etc, but that is a whole other story.

    Fiddler Tool works with any browser that respects Windows’ proxy settings (for instance Safari 3b doesn’t, but IE and FireFox do).

    Profanity usage

    Inspired by xkcd, here's my take on it as a javascript developer:

    My Profanity Usage by Browser

    To be fair to the numbers above, I first of all base my JavaScript on the Microsoft AJAX client library, so usually this works pretty well with IE7. I start out with making stuff work in IE7 and then adjust it to work in FireFox, IE6, Safari etc. This is probably why I spend more time fixing quirks in FireFox than in IE7. I'm currently doing some testing against Safari 3.0beta, and some of the issues I'm having were often resolved by making some subtle (but illogical) changes in the JavaScript, but these changes were often something I've stumbled upon by sheer luck (hence the profanities). It might just as well be because this is a beta browser. Surprisingly I do find myself spending more time working around issues and bugs in FireFox than in IE, but in the end I'm usually able to come up with a script that works in all major browsers and only have very few tweaks that tests against which browser I'm using (thank God for JS base API's that does most of that work).

    IE6 wins as the browser that required the most extra code needed, just because of one thing: PNG Transparency. I need objects that need to know whether its using images that are PNG or not, so I can apply the transparency workaround (but at least this is a well-known workaround). It just complicates the JS API, requiring developers to deal with more properties to ensure it works in IE6. I can't wait till the day where we can sign of that browser version.

    So why do I primarily develop in IE7, and not FireFox which seems to be the case for a lot of developers? Many reasons:

    • The debug integration with Visual Studio.NET is lightyears ahead of FireBug and all the other JS debug tools in FireFox (and is the JS console really all I get in Safari 3.0 on Windows?).
    • There are some great tools to browse and modify the DOM, see requests etc. My favorites are "Web Development Helper" which even have JSON and Microsoft AJAX Partial Postback deserializers to help you easier analyze the server responses, and IE Developer Toolbar for viewing the DOM and modifying it on the fly (priceless when you are tweaking your CSS styles).
    • It's the most used browser out there, so this is in my mind also the most important one. I'm not saying the others aren't important, but this should ensure that the most used browser also gets the most preliminary testing.
    • I know all the non-ECMA-Script properties and methods that IE adds to the DOM, so I also know which properties and methods to avoid. I'm not that familiar with Mozilla's extensions and don't want to risk using methods that doesn't exist in other browsers (that just adds to the number of profanities :-).
    • This one is probably going to give me some flaming, but I do think IE7 is the best overall browser.

     

    Silverlight managed code vs. JavaScript

    I finally had a chance to play with Silverlight today. The managed code capabilities is very interesting, so I set out to create a simple performance tester.

    I created two basic managed methods in Silverlight. One that multiplies a number and returns a result, and another that does the same thing a specified number of times:

    [Scriptable]
    public double Multiply(double a, double b)
    {
       return a * b;
    }
    [Scriptable]
    public double MultiplyLoop(double a, double b, int count)
    {
       double result = 0;
       for (int i = 0; i < count; i++)
          result = a * b;
       return result;
    }

    This gives me 3 test-cases to compare:

    • Multiply two numbers n times in pure javascript.
    • Multiply two numbers n times, by calling Multiply(a,b) from JavaScript into managed code n times
    • Multiply two numbers n times, by calling MultiplyLoop(a,b,n) from Javascript into managed code one time.

    What I found was:

    • JavaScript is fairly slow to do this (345 ms for 10 millions calculations).
    • Calling a managed method millions of times is VERY slow (IE asked me several times whether I wanted to abort it before it finished)
    • Calling a managed method once and do the looping in managed code is VERY fast (0-2 ms).

    The conclusion here would be that you shouldn't have methods in managed code that you call a lot from javascript unless they are process-intensive. There seems to be a big overhead in calling into managed code, but as soon as you are in the managed process, its blazing fast.

    You can download my test sample here: SilverlightProject1.zip (18.35 KB)  (requires Orcas beta 1 and Silverlight add-on)

    Now on to move all my existing .NET libraries into a Silverlight app... :-)

    Notes on javascript performance

    Earlier today (some would say way too early after a long night at Pure) I attended the session "How to make AJAX Applications scream on the client". This turned out to be more about general patterns in Javascript and not so much about AJAX.

    Anyway here are my notes from that session:

    Avoid Eval(). Instead use parameterized code.

    'Switch' is costly for large sets and grows linearly. Instead use a hashtable and wrap in try/catch.

    Getters/setters are inefficient. Use direct access to the variables in an instance.

    DOM Instantiating and traversing is slow because it has to go from the JS layer to the DOM layer through COM. Use it as little as possible. Example:

       Bad: for(var i=0;i<100;i++) { document.getElementById('myDiv').innerHTML = i; }
       Better: var div = document.getElementById('myDiv'); for(var i=0;i<100;i++) { div.innerHTML = i; }

    Use speculative download. Try and anticipate what the user needs to download next. For instance, on the login page start loading icons that the users will need after logging in. The browser might as well spend the time he is spending on entering his password on downloading stuff. When he then logs in the browser will retrieve the images from the cache instead of having to download them from the server, making the page load much quicker. Try going to the login page of an Outlook Webaccess website and see what happens behind the scenes through the Fiddler tool.

    Enable GZIP encoding on the webserver. Most browsers supports it and will result in smaller downloads. Again Fiddler is great for experimenting with this.

    You can see the full session online here.

    Ajax View: Remotely Monitoring Web 2.0 Applications

    Today Microsoft demoed their AjaxView application in one of the Mix07 sessions. It acts as a proxy and monitors requests, as well as execution time for each javascript function that gets executed. This is really neat for tracking what methods are putting the most load on the client browser. Now all we need is some built-in tracking of memory leaks ;-)

    A tech preview will be available within the next 1-2 months.

    Update: You can now see the full session where this was demoed online here.