Category Archives: Debugging

Emulation Accuracy in Internet Explorer

Early preview versions of Internet Explorer 11 lacked Emulation features that we saw in Internet Explorer 9 and 10. When Windows 8.1 shipped, Internet Explorer 11 was found to have the Emulation features shipped with it. These tools are helpful, though they can be misleading at times.

My general workflow in the past when using these tools goes like this: A user reports an issue in Internet Explorer x. I instruct the latest version of Internet Explorer to emulate the reported version. If I encounter the same issue, I can debug using the modern version of Internet Explorer. If emulation does not reveal the same issue, I need to load up a virtual machine, or use a service like BrowserStack.

The problem with these tools is that it’s not entirely clear where the line of reliability resides. To what degree this emulation replicates the native experience is unknown (to me, at least). Due to this, I’ve decided to do a deep dive into Emulation and see just how reliable it is, and in which areas.

Computed Styles

The first dive wasinto Computed Styles. Does Internet Explorer generate the same computed styles as IE10 and IE9 when it is emulating those versions? Surprisingly, yes. Granted, I’m running instances of IE10 and IE9 in a Virtual Machine (compliments of modern.ie), so that should be considered. Also other important thing to note is that this pass-through assumes Standards Mode.

The comparison tables are being maintained in a Google Docs spreadsheet. Click the preview below for the full view.

comparison.table

Window Object

My next focus was on cycling over enumerable properties on the window object and laying those out for comparison. A cursory glance of this next table will reveal that Internet Explorer 11 emulates the window object from IE9 and IE10 very well. Granted, there are some very clear examples of where it brought along a couple extra methods and properties.

comparison.table.window

It’s worth noting that this particular table had to be done a couple of times. Some of these members don’t attach themselves to the window object until certain actions are performed. For instance, this table is front-loaded with a bunch of BROWSERTOOLS members that are pushed onto the window object when various portions of the developer tools are opened. Other members, such as $0, don’t exist until you perform an action like selecting an element in the DOM Explorer.

More on GIFs and Painting in Internet Explorer

About a week ago I wrote a post demonstrating the use of UI Responsiveness functionality in Internet Explorer 11 to determine how the browser handles animated GIFs in various states. This post was a fairly well-received so I wanted to expand a bit more upon it and cover a few more scenarios.

For the most recent round of testing, I setup a simple interval to change the className of the body element every few seconds. This, in turn, affects the placement and layout of a single image element within the document.

(function () {

  "use strict";

  var states = ["", "opacity", "visibility", "offscreen", "perpendicular"],
      container  = document.body,
      cycles = 0,
      nextState;

  function advanceState () {
    // Advance to next array index, or return to start
    nextState = states[++cycles % states.length];
    // Indicate a new performance mark in our developer tools
    performance.mark(nextState ? "Starting " + nextState : "Restarting");
    // Update the body class to affect rendering of image
    container.className = nextState;
  }

  setInterval(advanceState, 3000);

}());

I used the performance.mark method to add my own indicators in the performance graphs to help me identify when the demo was transitioning into a new state. These performance marks are represented in Internet Explorer by small upside-down orange triangles.

performance.ticks

Let’s walk through each of these triangles left to right, discussing the state they represent.

GIF Untouched

This state is represented by all activity to the left of the first performance mark. Not much needs to be said – Internet Explorer continued to paint the GIF as it sat animated on the screen.

performance.ticks.0

Setting GIF Opacity

This step is represented by all activity between the first and second performance marks. In this step, the image element has its opacity property set to 0. Even though the image is no longer visible, the browser continued repainting the region occupied by the image element.

performance.ticks.1

Setting GIF Visibility

This step is represented by all activity between the second and third performance marks. In this step, the image element has its visibility property set to hidden. Once the visibility property was set to hidden, the browser made one final repaint (presumably to hide the element) and no further paint events took place during the duration of this state.

Of relevance here is that the hidden attribute on the image itself has the same effect. When this attribute is present on the element, Internet Explorer will cease to repaint that elements occupied region.

performance.ticks.2

Setting GIF Outside of View

This step is represented by all activity between the third and fourth performance marks. In this step, the image element is positioned absolutely at top -100% left -100%. In spite of the fact the element is positioned outside of the viewport itself, the browser continued to run paint cycles.

performance.ticks.3

Setting GIF Orientation Perpendicular to Viewport

This step is represented by all activity between the fourth and fifth performance marks (the fifth mark is the ‘Restarting’ mark). In this step, the image is rotated using the transform property so as to set it at a right angle to the viewport, effectively hiding its content from the viewer. This orientation did not affect the browser paint cycle, and Internet Explorer continued repainting the region occupied by the image element.

performance.ticks.4

Conclusion

As a general rule, it appears Internet Explorer will run paint cycles for every animated GIF in the document, unless that element has its visibility property set to hidden. This is fairly reasonable, since setting visibility to hidden is the only explicit way to tell the browser not to render the element. Keep this in mind when performance is of key importance.

After running through and investigating this further I was curious what the same test would reveal in Chrome. I was pleased to see that Chrome would cease to paint for the opacity, visibility, and offscreen configurations. No performance marks are revealed in Chrome’s developer tools, but you can identify the timer functions by the presence of a small orange mark.

performance.ticks.chrome

Tracking GIF Repaints with UI Responsiveness

I recently came across Paul Lewis’ article Avoiding Unnecessary Paints: Animated GIF Edition on HTML5 Rocks and wanted to contribute a bit to the message. If you aren’t a regular reader or HTML5 Rocks I would definitely encourage you to visit often.

The summary of Lewis’ post is that animated GIFs can cause repaints even when obscured by other elements. So even though you may not see the GIF, the browser may continue to repaint every frame of it.

As far as browsers go, Lewis shared with us the “Show paint rectangles” feature in Chrome. When enabled, this feature will visually outline regions that are being repainted. This obviously makes it very easy to determine whether paints are happening on obscured elements. Chrome, Safari, and Opera all repaint. Firefox does not.

In his discussion of various browsers, Lewis calls Internet Explorer 11 a “black box,” suggesting it gives “no indication whether repaints are happening or not.” As a result, no statement was made speculating whether Internet Explorer was in the camp of Chrome, Safari, and Opera, or Firefox.

I quickly did a scan of the comments to see if anybody addressed these words regarding Internet Explorer, but at the time nobody had. I saw this as a great opportunity to introduce my friends to the new UI Responsiveness tool in Internet Explorer 11.

The UI Responsiveness tool in Internet Explorer’s Developer Tools will actually give us pretty granular information about frame-rates, script timing, styling changes, rendering, and even repaints. Given the novelty of this feature in Internet Explorer, I felt it would be good to provide a quick example of how Internet Explorer 11 can indeed tell you whether obscured GIFs cause repaints or not.

A Single Visible GIF

My first experiment consisted of nothing more than a single GIF in the body of my document. By profiling the page for a few seconds I could see that there was constant repainting. This was expected of course, after all there’s a GIF on my screen spinning.

Below is one second of activity. As you can see, constant repainting.

gif.1

Toggling Visibility of a Single GIF

Next up, toggle the visibility of the GIF by way of its display property. I setup a interval to flip the visibility every second. The results were also as expected. For roughly one second, we had constant repainting. Following this we saw a set style event, followed by a single repaint (to hide the element). At this point, it was silence for a second before the element became visible again, and thus began causing additional repaints.

gif.2

Routinely Obscuring a Single GIF

The last experiment was to add another element, a div with a solid background-color in this case, and obscure the animated GIF on an interval. This was done by positioning both the div and the image absolutely within the body, and giving the div a higher z-index.

As can be seen in the image below, repainting did not cease even when the layout was adjusted every second. This demonstrates that when obscured, animated GIFs will continue to cause repaints in Internet Explorer 11. Whether this will be the case for future versions of Internet Explorer remains to be seen.

gif.3

Conclusion

So as we can see in these examples above, Internet Explorer 11 is capable of sharing vital information about costly repaints. Additionally, IE falls into the Chrome, Safari, and Opera camp. It sure would be nice if all browsers followed Firefox’s lead here and stopped repaints on obscured GIFs, but perhaps there is a good reason they haven’t, who knows.

I hope you can see the enormous value the UI Responsiveness panel in Internet Explorer 11’s Developer Tools brings to the debugging experience and use it to make your projects more responsive and performant in the future. The team behind Internet Explorer really have been doing amazing work lately, and the UI Responsiveness functionality is but one example of this.

UPDATE: More on GIFs and Painting in Internet Explorer

Browsers – Broken By Design

I set out a few hours ago to write about a problem I had experienced in Safari, Chrome, Firefox, and Internet Explorer. Opera worked as I expected, which had me convinced the other vendors merely dropped the ball, and shipped partial implementations for the :visited and :link pseudo-classes.

My CSS was very simple:

:link {
    color: white;
    background: red;
}

:link::before {
    content: "Pseudo: ";
}

A color set for unvisited links, followed by some content in the ::before pseudo element on all unvisited links. So when I dropped in two links (one visited, one not) I expected to see the following:

image00 copy

Instead, what I saw was a litter of inconsistent results between Chrome, Safari, Internet Explorer, Firefox, and Opera. The above image came from Opera. It performed exactly as I suspected. The others, not so much.

Chrome and Firefox gave similar results; both set “Pseudo” as a virtual first-child of both anchors (though I only asked to have it on unvisited links), and leaked the background color from :link into :visited.

Internet Explorer did better than Chrome and Firefox; it preserved the “pseudo” text, but left the background of the visited link untouched. I was still very perplexed as to why it was spilling values from :link over into :visited.

You can observe something interesting in Internet Explorer – :visited links start visually identical to :link links, but are transitioned into their :visited state immediately thereafter. Setting a transition on all links reveals the change when the document loads:

a {
    transition: background 10s;
}

You’ll see the :link links remain unchanged but :visited links slowly adopt their end style. This is not the case for Chrome, Firefox, Opera, or Safari.

Safari appeared to be the most broken of them all. It duplicated everything. Further, I attempted to set additional styles to :visited, and it completely ignored them.

Discovering History

I found it incredible that all of these browsers, with the exception of Opera, would get this so wrong. So like any good developer I took to the web to see who else might be complaining about this, which is when I came across a Stack Overflow post suggesting this was somehow related to security concerns.

This offered another search vector; security issues. That was the needed catalyst for opening up a fascinating story about yet another creative attempt by developers to put their nose where it may not belong – in the client browser’s history.

Browsers typically style links with a default color to indicate whether it is a visited link or not. We’ve all seen those blue and purple links before – they’ve become quite at home on the web. Somebody got the (seriously) brilliant idea to create anchors ad hoc, and use getComputedStyle to see if the links represented visited or unvisited locations.

Mozilla reports that you could test more than 200,000 urls every minute with this approach. As such, you could – with a great deal of accuracy – fingerprint the user visiting your site based on the other urls they have visited; and browser history runs deep.

Scorched Earth Solution

The solution implemented by Firefox (and apparently others) was to greatly reduce the presence of visited links. They started by instructing functions like getComputedStyle and querySelectorAll to lie (their words, not mine) about their results. Sure enough, a simple check confirms that though my :visited links have a different font color than :link links, getComputedStyle says they’re the same rgb value.

Mozilla’s Christopher Blizzard continues with a very key point (emphasis added):

You will still be able to visually style visited links, but you’re severely limited in what you can use. We’re limiting the CSS properties that can be used to style visited links to color, background-color, border-*-color, and outline-color and the color parts of the fill and stroke properties. For any other parts of the style for visited links, the style for unvisited links is used instead. In addition, for the list of properties you can change above, you won’t be able to set rgba() or hsla() colors or transparent on them.

And there it was, the explanation that tied all of the seemingly broken pieces together. The browser would instruct :visited to share property values with :link. The browsers aren’t broken; they were designed to fail.

Test Confirmations

I wanted to explore the now-understood implementation a bit further, so I tried a few things. Querying the DOM for :visited links (expecting 1 of 2) was my first decision. I also queried the DOM for :link as well – expecting 2 due to the new security:

Browser Number of :visited Number of :link
Chrome 0 2
Firefox 0 2
Internet Explorer 0 2
Safari 0 2
Opera 1 2

Nearly all of the browsers report no :visited link, with the exception of Opera. All browsers report a total of 2 links when querying :link.

So it seems like you can still get a list of visited sites in Opera. Internet Explorer, Firefox, Chrome, and Safari all prevented the exploit from being carried out. But one thing about Internet Explorer intrigued me; remember the transitioning I spoke of earlier?

Internet Explorer Still Vulnerable?

I noticed that if I set transition: background 10s on anchors in Internet Explorer you would slowly see all visited links slowly tween into their end state. Transitions fire the transitionend event when they complete, so could we still get the user’s visited links in Internet Explorer?

The CSS to test this is very simple:

a { transition: background .01s }
:link { background: red }

And the following JavaScript:

/* Anchor var, fragment, and array of guesses */
var anchor;
var fragment = document.createDocumentFragment();
var websites = [
    'http://bing.com',
    'http://google.com',
    'http://jquery.com',
    'http://appendto.com',
    'http://stackoverflow.com'
];

/* Listen for completed transitions */
document.addEventListener("transitionend", function (event){
    console.log(event.target.href);
}, false);

/* Create a link for each url */
websites.forEach(function(url){
    anchor = document.createElement("a");
    anchor.setAttribute("href", url);
    anchor.innerHTML = url;
    fragment.appendChild( anchor );
});

/* Add our document fragment to our DOM */
document.body.appendChild(fragment);

Immediately upon being added to the DOM our :visited anchors will start to transition away from looking like a :link anchor. Once that transition is complete, we learn what the URL is, and confirm that the user has visited that site.

Closing Thoughts

I was reminded today just how exciting our industry is. People are constantly experimenting, learning new things, and sharing that knowledge. Industry experts, developers, designers, and browser vendors are always working to shift and adjust in light of the ever-evolving web.

Although the CSS2.1 Specification says something, that doesn’t make it so – even if the feature is 15 years old. If the ends justify the means, browser vendors will (and did) fire-bomb their own code-base to protect the end user.

Finally, we’re all in this together; we ought to work together. Microsoft launched the @IEDevChat twitter account not too long ago to assist developer’s who are attempting to follow web-standards. Then even organized a group of developers who wanted to volunteer and help build a better web; you can find (and join) it online at http://useragents.ie.

I’m sure there’s more history here that I’ve yet to discover, but what I have seen is enough to pique my interest. If you have anything else to share, or can contribute to the vulnerability test approach above, please leave a comment below. I may swing back around and check out the other browsers later on.

IE10 Gotcha: Optgroup Indexes and the Required Attribute

I came across a rather interesting gotcha in Internet Explorer 10.0.9200.16519 this evening (via @dstorey, who showed me this question). Setting the required attribute on a select element that has various optgroup elements within may result in unexpected warnings upon form submission.


The above form will be “invalid” if the index of the selected option among its siblings matches the index of its parent optgroup among its siblings. So the first optgroup and the first option will trigger the unexpected results when the parent select has the required attribute.

This pattern is consistent with the second, third, and fourth optgroup elements. Selecting the second option in the second optgroup, or the third option in the third optgroup, will cause form submission to fail.

Workarounds

Update: As Claude pointed out in the comments below, adding a non-empty value attribute to the optgroup elements will resolve the issue.

I have found only one way around this, but it may not work in most situations. Adding the multiple attribute to the same select will prevent the confusing behavior, but at the cost of affecting the presentation and behavior of your element. The size attribute could remedy this to some degree, but is not favorable.

Sometimes Chrome is the broken browser (Or, How Chrome failed me twice in one night)

For several years it’s been generally accepted by the web-development community that Internet Explorer is nothing more than a means by which developers are subjected a great deal of emotional and mental trauma. Well, that has changed in the last couple of versions, but most developers are still licking their slow-healing wounds.

One thing that bothers me though is how so many automatically feel as though these types of issues only exist with Internet Explorer, generally touting Google Chrome as the full-featured flawless alternative. Granted, Google has done an outstanding job with the Chrome browser, and I personally use it for most of my work, but Chrome is in no way special. It too is capable of causing a lot of upset – such was the case this evening for me.

I worked on a couple of marquee demos over the last few days which gave me another idea. I wanted to cover an element with its ::after pseudo-element, apply a transparent-to-black background on the pseudo-element, and then animate it off to the right using @keyframes. I didn’t want this to be visible as it moved off to the right, so I applied a parent element of the same dimensions, and set its overflow to hidden. Queue the tears.

Chrome 24, wouldn’t respond. It just sat there, frozen. I could have sworn I did something wrong, but the demo was so simple in its construction. Where was I going wrong? I ended up testing the same demo in Internet Explorer 10, and found it it immediately kicked off without any problems. So, back to Chrome – it turns out there was a question on Stack Overflow asked some time back regarding this very issue, which led me to news that Chrome had apparently fixed this in version 26 (unstable at the time of this writing).

Opening up Canary, I was pleased to see that my pseudo-elements were indeed being animated. Nice work Chrome! This was the first issue tonight where Internet Explorer 10 was working as expected, and Chrome was not. Next I noticed the pseudo-element bleeding out over the rounded edges of the parent; that’s not supposed to happen when you’ve got overflow:hidden set – right?

Back to Internet Explorer 10, I confirm that overflow:hidden does as it advertises, and the pseudo-element is not visible outside of its parents rounded corners – way to go Internet Explorer 10! But I still needed an unequivocal demonstration of this bug to confirm if Chrome was indeed busted, and misbehaving. That demo is now available online. As of today (January 20, 2013), this demo is broken in all versions of Chrome, but working in Internet Explorer 10 and Firefox.

So what’s the story here? The take-away is that Internet Explorer is no longer the browser it used to be. It’s a fully-qualified modern browser capable of some really killer things. It is well-built, and carries as much respect for standards as its competition. Chrome, on the other hand, did not come down to us from the gods of Mount Chrominus. It too is flawed in some ways, while brilliant in others.

Jumping on the one-browser-to-rule-them-all bandwagon doesn’t help the developer’s plight, it worsens it. Advocate standards, not browsers. Get behind good practices such as progressive-enhancement, feature-detection, and when necessary polyfills. Don’t champion a browser, champion the web.

Sometimes Chrome is the broken browser – it happens.

CHROME, Y U NO ANIMATE PSEUDO-ELEMENTS LIKE IE10?

Active-Filtering of the Session List in Fiddler2

I use Fiddler2 daily – it’s one of the greatest debugging tools I’ve ever come across. You can hammer into the traffic coming and going across the tubes and tamper with the data as you like. You can substitute alternative local data in the place of remote server responses. You can modify headers on the fly. And this doesn’t even begin to scratch the surface of all you can do.

One of the problems I have is that, like many of you I’m sure, my browser is hardly ever doing one thing. Although I may be trying to debug a web-app, I may also be tied into my GMail inbox, streaming some music over Turntable, or watching the flow of tweets glide across @jonathansampson. All of these items cause sessions to be logged in Fiddler, adding a whole lot of noise to what I’m trying to work on.

So what do you do when you have specific hosts that you want to track? You make use of the Filters tab.

This highly-customizable tab will provide active filtering of the sessions coming across your screen. You can instruct it to show only intranet traffic, or only internet traffic. You can explicitly ignore particular hosts, or you can ignore everything but a select few. As my earlier summary of Fiddler didn’t begin to scratch the surface, neither does my explanation of this panel begin to touch on all that the Filter feature is capable of.

Have a look.

What I’ll be looking at here is the first part, the hosts section.

For starters, we need to click the “Use Filters” check-box to enable this feature. Now in my particular situtation all I want to see is anything that comes from a particular domain, such as microsoft.com. This would include any subdomains as well.

The first thing I will do is select “Show only Internet Hosts” from the first dropdown. From the second dropdown, I’ll select “Show only the following Hosts”. This enables the textarea below, which will take a series of expressions or explicit domains to watch for.

Insert *microsoft.com and you should see the textarea turn yellow, informing us that “Changes not yet saved.” At this point, click the Actions button to the top-right, and select “Run Filterset now”. If you already had sessions from your target domain in your session list, those should be all you see in there at this point.

From this you can infer how to go about blocking only particular domains, and various other things. You might even dare to venture into the rest of the filter options, creating a highly-customized instruction set. If you do, be sure to save your filter from the same Actions button we used to run the filterset.

I find this to be an enormously helpful feature, and I’m sure you will as well. Now if you’ll excuse me, I’ve got some work to do and very little noise preventing me from getting it done, thanks to Fiddler.