IE8 Memory Leaks

March 27, 2014

One of our clients wanted us to create a media gallery webpart for them. The webpart allows you to page through a folder structure/gallery of photos and videos.

Our webpart would create an image tag and then set the source each time a new image was to be displayed. This is pretty basic and it’s what you would expect. However, in IE8 this creates a memory leak, and the only way to release that memory was to close the browser. For some of the machines we tested on, after 30 images the browser would fail to load.

The DOM node types that leak in IE8 are form, button, input, select, textarea, a, img, and object.

So how do you make a media gallery webpart without image tags? After many different attempts to avoid the leak, css background-image property was the only thing that didn’t trigger it. However there was one issue, IE8 does not support re-sizing of background images.

The Fix:

As I mentioned earlier we cannot use image tags anymore as they leak. So instead we used a div tag.

var new_img = jQuery('
<div>').css({
    'background-size': '100% 100%',
    'background-repeat': 'no-repeat',
    'width': img_width + 'px',
    'height': img_height + 'px'
})

We then had to check if we were using IE8. If we are using IE8, we need to use this special filter property to be able to re-size a background image:

var IEBrowser =
{
  Version: function()
  {
    var version = 999;
    if (navigator.appVersion.indexOf("MSIE") != -1)
      version = parseFloat(navigator.appVersion.split("MSIE")[1]);
    return version;
  }
}

 if(IEBrowser.Version()<9)
 {
    new_img.css({ 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + cache_url + "',sizingMethod='scale')" })
 }
 else
 {
    new_img.css({ 'background-image': 'url("' + cache_url + '")' })
 }

And now we have a sudo image tag that avoids the leak!

A Day in the Life of a Front End Developer

March 14, 2014

Here’s a peek at an average day for a front end developer at RefineCo:

8:30am – Walk into the office and brew up a cup of coffee to get those synapses firing. Sit down at my computer to read and answer emails, and to check for any new tasks that may have been assigned to me and require my immediate attention.

8:45am – Check JIRA task board to see what outstanding tasks remain on the various projects I’m working on. This gives me a rough idea of what I should be allocating my time towards, and helps me prepare for…

9:00am – …our daily stand up. The developers and project managers gather round, and the devs discuss what we worked on the previous day, any problems we encountered, resolved, or are currently stuck on, and what we will be working on today.

9:15am – After stand up, it’s time to throw on the headphones, cue up some raging metal tunes, and get down and dirty with HTML/CSS/JavaScript.

A large portion of my time is spent taking static PhotoShop designs and using the aforementioned trifecta of HTML/CSS/Javascript to bring them to life as clean, fast, easy-to-use interfaces for client portals, intranets, and public websites. Because RefineCo is primarily focused on Enterprise Content Management (ECM) development, our interfaces need to be integrated and work well with Microsoft SharePoint, which requires working with ASP.NET.

12:30pm – Lunch time. It’s either leftovers from dinner the night before, or head out to one of the nearby food establishments. If I stick around the office I might do some coding tutorials, or catch up on the day’s news. On Friday’s most of the team will head out to lunch together. It’s a nice opportunity for us to all hang and become BFFs.

1:30pm – Back to work. In addition to building out interfaces, I spend my time:

  • fixing layout, design, and usability bugs;
  • ensuring that our solutions are cross-browser, and in some cases cross-platform compatible;
  • working with back end developers to help resolve any front end issues they may run into, and vice-versa;
  • providing proof-of-concepts for new technologies and interface ideas;
  • writing awesome blog posts;

5:00pm – It’s likely that throughout the day I have been committing code through Git, the version control system we use. At the very least you want to make sure you do it at the end of the day. You’ll be able to sleep easy knowing that your day’s work won’t be undone if your computer pulls a Chernobyl overnight.

5:30pm – Time to head home and spend some quality time with the family.

Video.js not falling back to Flash with MP4 videos in Firefox

March 11, 2014

Having videos in your intranet/portal is a great way to interact and deliver content to your users. For our video player webpart, we use Video.js – a cross-browser compatible HTML5 video player.  A feature of Video.js is its ability to gracefully fallback to Flash (or another video playback technology) whenever HTML5 video is not supported.  However, we were running into a problem in Firefox when an MP4/H.264 video file is the only source available.

<video width="1280" height="720" controls="controls">
    <source src="video.mp4" type="video/mp4" />
</video>

Whenever Video.js tried to play an MP4 video in Firefox, we were greeted with this error:

No video with supported format and MIME type found.

Firefox does not natively support MP4 videos (even IE9+ does!), which is why we see this error. In this situation, we would expect Video.js to fallback to Flash playback, but it does not. Video.js simply checks if the browser supports the HTML5 <video> tag.  If it does, then it tries to play the video with HTML5. If it does not, then it falls back to Flash. Firefox does support <video> so Video.js plays in HTML5 mode without knowing Firefox is unable to handle MP4 videos.

One solution to this is to add an additional video source in a format that is supported by Firefox, such as webm.

<video width="1280" height="720" controls>
    <source src="video.mp4" type="video/mp4">
    <source src="video.webm" type="video/webm">
</video>

This requires converting your videos and hosting multiple versions of them in different formats. Some of our clients have hundreds of videos, so this was not a viable solution. Instead, a workaround is possible using the Video.js API and adding a listener to the ‘error’ event.

videojs(id).ready(function() {
    videoPlayer = this;

    videoPlayer.on('error', function() { // error event listener
        // dispose the old player and its HTML
        videoPlayer.dispose();

        // re-add the <video> element to the container
        jQuery('.video-container').append('<video id="' + id + '" controls autoplay class="video-js vjs-default-skin" preload="auto" data-setup="{}">' +
            '<source src="video.mp4" type="video/mp4" /></video>');

        // force Flash as the only playback option
        videojs(id, {"techOrder": ["flash"]}).ready(function() {
            videoPlayer = this;
        });
    });
});

If an error is thrown in the original videojs object, we dispose it and create a new one where Flash is the only playback technology in the techOrder array, forcing it to only use Flash.

Hopefully MP4 video support will be added to Firefox soon. Until then, these are 2 possible solutions to get Video.js, Firefox, and MP4 videos to play nice.