Scott Hanselman

Updating jQuery-based Lazy Image Loading to IntersectionObserver

April 11, '18 Comments [4] Posted in ASP.NET | HTML5 | Javascript
Sponsored By

The Hanselminutes Tech PodcastFive years ago I implemented "lazy loading" of the 600+ images on my podcast's archives page (I don't like paging, as a rule) over here https://www.hanselminutes.com/episodes. I did it with jQuery and a jQuery Plugin. It was kind of messy and gross from a purist's perspective, but it totally worked and has easily saved me (and you) hundreds of dollars in bandwidth over the years. The page is like 9 or 10 megs if you load 600 images, not to mention you're loading 600 freaking images.

Fast-forward to 2018, and there's the "Intersection Observer API" that's supported everywhere but Safari and IE, well, because, Safari and IE, sigh. We will return to that issue in a moment.

Following Dean Hume's blog post on the topic, I start with my images like this. I don't populate src="", but instead hold the Image URL in the HTML5 data- bucket of data-src. For src, I can use the nothing grey.gif or just style and color the image grey.

<a href="/626/christine-spangs-open-source-journey-from-teen-oss-contributor-to-cto-of-nylas" class="showCard">
    <img data-src="https://images.hanselminutes.com/images/626.jpg" 
         class="lazy" src="/images/grey.gif" width="212" height="212" alt="Christine Spang&#x27;s Open Source Journey from Teen OSS Contributor to CTO of Nylas" />
    <span class="shownumber">626</span>                
    <div class="overlay title">Christine Spang&#x27;s Open Source Journey from Teen OSS Contributor to CTO of Nylas</div>
</a>
<a href="/625/a-new-sega-megadrivegenesis-game-in-2018-with-1995-tools-with-tanglewoods-matt-phillips" class="showCard">
    <img data-src="https://images.hanselminutes.com/images/625.jpg" 
         class="lazy" src="/images/grey.gif" width="212" height="212" alt="A new Sega Megadrive/Genesis Game in 2018 with 1995 Tools with Tanglewood&#x27;s Matt Phillips" />
    <span class="shownumber">625</span>                
    <div class="overlay title">A new Sega Megadrive/Genesis Game in 2018 with 1995 Tools with Tanglewood&#x27;s Matt Phillips</div>
</a>

Then, if the images get within 50px intersecting the viewPort (I'm scrolling down) then I load them:

// Get images of class lazy
const images = document.querySelectorAll('.lazy');
const config = {
  // If image gets within 50px go get it
  rootMargin: '50px 0px',
  threshold: 0.01
};

let observer = new IntersectionObserver(onIntersection, config);
  images.forEach(image => {
    observer.observe(image);
  });

Now that we are watching it, we need to do something when it's observed.

function onIntersection(entries) {
  // Loop through the entries
  entries.forEach(entry => {
    // Are we in viewport?
    if (entry.intersectionRatio > 0) {

      // Stop watching and load the image
      observer.unobserve(entry.target);
      preloadImage(entry.target);
    }
  });
}

If the browser (IE, Safari, Mobile Safari) doesn't support IntersectionObserver, we can do a few things. I *could* fall back to my old jQuery technique, although it would involve loading a bunch of extra scripts for those browsers, or I could just load all the images in a loop, regardless, like:

if (!('IntersectionObserver' in window)) {
    loadImagesImmediately(images);
} else {...}

Dean's examples are all "Vanilla JS" and require no jQuery, no plugins, no polyfills WITH browser support. There are also some IntersectionObserver helper libraries out there like Cory Dowdy's IOLazy. Cory's is a nice simple wrapper and is super easy to implement. Given I want to support iOS Safari as well, I am using a polyfill to get the support I want from browsers that don't have it natively.

<!-- intersection observer polyfill -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>

Polyfill.io is a lovely site that gives you just the fills you need (or those you need AND request) tailored to your browser. Try GETting the URL above in Chrome. You'll see it's basically empty as you don't need it. Then hit it in IE, and you'll get the polyfill. The official IntersectionObserver polyfill is at the w3c.

At this point I've removed jQuery entirely from my site and I'm just using an optional polyfill plus browser support that didn't exist when I started my podcast site. Fewer moving parts means a cleaner, leaner, simpler site!

Go subscribe to the Hanselminutes Podcast today! We're on iTunes, Spotify, Google Play, and even Twitter!


Sponsor: Announcing Raygun APM! Now you can monitor your entire application stack, with your whole team, all in one place. Learn more!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

I was annoyed by the web font issues at Upworthy...you won't believe what I did next!

August 16, '14 Comments [11] Posted in HTML5
Sponsored By

Sorry about the title, I had to. ;)

I was running Windows and Google Chrome and I clicked on a link to an Upworthy.com video. When I go to Upworthy recently (don't judge me) I've been seeing this weird font for the last few months. It's obnoxious, and I was surprised they'd let this fly.

Upworthy has weird fonts

Later, though, I looked in another browser, and it looked fine.

Upworthy rendered in IE

Ok, time to F12. According to IE's Developer Tools there are three webfonts coming down and they each are downloading completely.

IE dev tools say the WOFF file is fine

Interestingly Chrome says the same thing:

Chrome agrees

What's the DOM expecting the font to be? Well, basically all of them. ;)

That's a long font-family

Seriously, though, IMHO pick a font or font family and move on. There's really no need to make a list of 11 font types in the order you'd prefer them. Either your web font works or it's Helvetica time.

Gill Sans? I don't see a Gill Sans available here. Gill Sans is a Mac OS X system font, but it seems that Google Chrome on Windows REALLY don't like being asked for it. ;)

I took each of the downloaded WOFF files and tried to open them at http://www.pkmurphy.com.au/glyphviewer/ to see if one was Gill Sans. Of course, none contained any of the first their fonts they're asking for. Unless you explicitly download a web font, a list of fonts like these are a just a designer's wish list.

Web Designers: Design for the web, not the cool fonts you have on your machine.

On 99% of Windows machines you're going to end up with Segoe UI with this CSS font-family as most folks won't have those first three fonts. It seems that Chrome gives up (?) after a few tries (not sure?) but if I remove Gill Sans as the first item it renders fine.

image

The font is correct with a smaller font-family

I tried to find a bug on this in the Chromium bug database...I'm not sure if it might be this one?

I hope a CSS person at Upworthy sees this and solves the mystery! What are your thoughts, Dear Reader?


Sponsor: And a big thanks to Raygun for sponsoring the feed this week! I love Raygun and use it on all my apps. Get notified of your software’s bugs as they happen! Raygun.io has error tracking solutions for every major programming language and platform - Start a free trial in under a minute!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Fallback HTML5 audio tags for a simple MP3 podcast are harder than you'd think

March 26, '13 Comments [33] Posted in HTML5 | Javascript
Sponsored By

I've been spending the evenings and weekends lately redesigning the blog and the Hanselminutes podcast site. I hadn't realized how cheesy looking the podcast site was all these years. I'd like to get the show expanded to a wider audience as I feel that listenership has kind of flattened lately. I am in the process of adding faces for ALL 360+ shows going back 6 years.

A big thanks to Lynsey Smith from Portland Girl Geek Dinners, by the way, for her hard work in finding pics for me!

I also wanted a nicer in-browser audio experience so I assumed I'd just drop in the audio tag and be done, right?

The HTML5 Audio tag is wonderful, right? Just works. This is the dream:

<audio id="audioplayer" preload="metadata" type="audio/mp3" >
<source src="http://s3.amazonaws.com/hanselminutes/hanselminutes_0363.mp3" type="audio/mp3"/>
Your browser doesn't support the HTML audio tag. Be sad.
</audio>

You can try that live at http://jsfiddle.net/CdxbX/ if you like.

Except it's not nearly that easy.

Here's what you'll see on IE9+:

image

Here's Chrome:

image

Here's Firefox, version 19:

Ya, Firefox currently doesn't support MP3 audio so it just flashes once then disappears. Firefox will support MP3s in audio soon though by using the underlying operating system to play the stream rather than its own embedded code.

In Firefox 20 (the beta channel) on Windows 7 and above, you can test MP3 Audio support by turning on the preference media.windows-media-foundation.enabled in about:config.

The part I was disappointed in was more of an HTML5 specification issue. Notice that while I have fallback text present, I don't see it in Firefox. That's because fallback elements are only used if your browser doesn't support the audio tag at all.

It doesn't do what I would expect at all. What I want is "Can you support any of these audio sources? No? Fallback." This seems intuitive to me.

I talked to Chris Double via Christian Heilmann at Mozilla and he said "You'd need to raise the issue with WHATWG/W3C. It's been debated before in the past. " Indeed it has. From Oct 2009, more people saying that it's not intuitive to fall back in this way:

I expected (incorrectly, in this case) that if I only produced one source element (an MP4), Firefox would drop down to use the fallback content, as it does if I include an object element for a format not supported (for example, if I include a QuickTime object and QT is not installed, the user sees fallback content). As far as I can see, the only option in this situation is to rely on Javascript and the video element's canPlayType() function. - Kit Grose

This lack of an intuitive fallback means that I can't make an audio player that works everywhere using just HTML. I have to use JavaScript, which is a bummer for such a fundamental scenario.

Getting HTML5 audio to fall back correctly in all browsers

Instead you have to make an audio tag dynamically, then interrogate the tag. This applies to both audio and video tags. I ended up using some code from my friend Matt Coneybeare.

<audio id="audioplayer" preload controls loop>
<source src="audio.mp3">
</audio>
<script type="text/javascript">
var audioTag = document.createElement('audio');
if (!(!!(audioTag.canPlayType) && ("no" != audioTag.canPlayType("audio/mpeg")) && ("" != audioTag.canPlayType("audio/mpeg")))) {
AudioPlayer.embed("audioplayer", {soundFile: "audio.mp3"});
}
</script>

The AudioPlayer.embed at the end there is the WordPress AudioPlayer in standalone form. This way on Firefox I get the flash player since it answered false to canPlayType.

Flash audio player in Firefox

A Responsive and Touch-Friendly Audio Player in HTML5

However, the default audio player made by the <audio> tag is kind of lame, and I'd like it to better support touch, look great on tablets, etc. For this, I'll turn to Osvaldas Valutis's AudioPlayer. It's a nice little jQuery plugin that replaces the <audio> element with a lovely chunk of HTML. Since you can't actually style the HTML5 <audio> element, people just hide it, recreate it, then broker calls over to the hidden-but-still-working audio element.

This plugin, along with a little CSS styling of its default colors gives me a nice audio player that looks the same and works everywhere. Except Firefox 19/20 until the next version Firefox answers true to "canPlayType" and then it should just start working! Until then, it's the Flash fallback player, which works nicely as well.

image

The other problem is the QuickTime plugin that most Firefox users have installed. When styling with the Osvaldas' AudioPlayer, the JavaScript interrogation would cause Firefox will prompt folks to install it in some cases if it's not there, and it still doesn't work if it is installed.

I ended up modifying Matt's detection a little to work with this Osvaldas' styling. I realize the code could be more dynamic with less elements, but this was easier for me to read.

  • First, try the audio tag. Works? Great, style it with audioPlayer();
  • Can't do MP3 audio? Dynamically make a Flash player with that P. Hide the audio player (likely not needed.)

Unfortunately for readability, there's the ".audioPlayer" jQuery plugin that styles the HTML and there's the "AudioPlayer" flash embed. They are different but named the same. I didn't change them. ;)

<audio id="audioplayer" preload="auto" controls style="width:100%;" >
<source src="your.mp3" type="audio/mp3">
Your browser doesn't support the HTML audio tag. You can still download the show, though!
</audio>
<p id="audioplayer_1"></p>
<script type="text/javascript">
var audioTag = document.createElement('audio');
/* Do we not support MP3 audio? If not, dynamically made a Flash SWF player. */
if (!(!!(audioTag.canPlayType) && ("no" != audioTag.canPlayType("audio/mpeg")) && ("" != audioTag.canPlayType("audio/mpeg")))) {
AudioPlayer.embed("audioplayer_1", {soundFile: "your.mp3", transparentpagebg: "yes"});
$( '#audioplayer').hide();
}
else /* Ok, we do support MP3 audio, style the audio tag into a touch-friendly player */
{
/* If we didn't do the "if mp3 supported" check above, this call would prompt Firefox install quicktime! */
$( '#audioplayer' ).audioPlayer();
}
</script>

All in all, it works pretty well so far.

ODD BUG: Chrome does seem to have some kind of hang where this audio player is getting blocked while the comments load on my site. Any JavaScript experts want to weight in? If you load a page - like this one - and hit play before the page is loaded, the audio doesn't play. This only happens in Chrome. Thoughts?

While you're here, check out the new http://hanselminutes.com and consider subscribing! It's "Fresh Air for Developers."

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Our first year. A new web conference - <anglebrackets>

March 8, '13 Comments [22] Posted in HTML5 | Programming | Speaking | Web Services
Sponsored By

anglebrackets conferenceThere's a new web conference happening in Vegas next month and you should join us. John Papa, myself and our friends pulled in the speakers from a combination of invitations and submitted talks. It's called anglebrackets.org and I hope to see you there.

My friends and I miss the old Mix conference and the great fun of web conferences in Vegas generally. So we talked to Richard Campbell and some friends and made our own show. (This is not a Microsoft show, to be clear)

This is the first year of anglebrackets and it's going to be a small conference and we have no money. Because of this, we are co-located with a larger conference* and attendees can move between the two conferences.

You'll be able to enjoy web-focused, back-end non-specific web sessions from amazing web people like:

  • Lea Verou - Developer Relations at the @W3C
  • Christian Heilmann - Mozilla
  • Jonathan Snook - SMACSS.com Author
  • Elijah Manor - jQuery expert
  • Jim Cowart - appendTo()
  • Denise Jacobs - Creativity Evangelist
  • Phil Haack - GitHub
  • Scott Hanselman (me) - Web guy
  • and more!

We've got killer sessions like:

  • The Vanilla Web Diet
  • Modern JavaScript Development
  • Hands On Responsive Design with Twitter Bootstrap
  • Rich Data HTML Apps with Breeze
  • Getting Started with Require.js
  • TML5 Canvas and Kinetic.js
  • Eventing and Messaging in JavaScript
  • plus talks on SignalR, ASP.NET, PHP, Backbone, CSS, JavaScript Patterns, Gamifying your work, and lots more.

AUqYiSFK3v_1_1303867939All this and a special keynote from Mozilla Web Guy Christian Heilmann!

This conference will be a great way for you to get up to date on the modern web but also check out some of the DevIntersection talks on ASP.NET, Architecture, Elastic Scale in the cloud and more.

We're lean and mean and independent and we hope you join our first year.

If you register for the show package or complete package you'll also get your choice of a Google Nexus 7 or a Microsoft Surface RT.

There's also some excellent pre- and post-conference workshops you should consider enrolling in:

  • April 8th
    • Day of Single Page Applications - John Papa, SPA and JavaScript expert
    • On the Metal: Essential HTML5, CSS3 and JavaScript for All Developers (Bring your laptop!) - Todd Anglin, Telerik
    • Hacking the Creative Brain: Work Better, Produce More - Denise Jacobs, a TEDx speaker, Creativity Evangelist, and author of CSS Detective
    • Nimble and fast web apps for the mobile web - Christian Heilmann, Mozilla
  • April 12th
    • Building Applications with ASP.NET MVC 4 - K. Scott Allen, Author, Trainer and Consultant
    • User Experience Design for Non-Designers: An Interactive, Immersive Workshop - Billy Hollis, UX and App expert

The Complete Package includes TWO workshops plus the tablet, and the Show Package includes one workshop and the tablet, or just come to the main conference itself.

See you there!

* Yes, we took a little artistic license with the <tag/>, or <tag />, or <tag> if you are super pedantic. It is valid syntax although HTML5's opinion is different than XHTML's. The fact that you even noticed and want to argue is proof you should come to this conference. See what I did there?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

RELEASED - Download Internet Explorer 10 for Windows 7

February 26, '13 Comments [58] Posted in ASP.NET | HTML5 | Win7
Sponsored By

IE10 for Windows 7Just about a month ago the IEBlog published a post to allow business to manage the update schedule for Internet Explorer 10. It says "this approach lets organizations control when they are ready to deploy IE10 to their Windows 7 users." I took from this that IE10 on Windows 7 was imminent.

Today it's out. You can download IE10 for Windows 7 now. The details are over at the IE blog.

In the next few weeks and months Windows 7 machines will get automatically upgraded to IE10. For Web Developers like me, that means that between Windows 8 which already has IE10 and all these Windows 7 users who will now have IE10, that more people will have a modern browser than ever before.

IE10 was faster on my machine than IE9, and they say it is smarter about battery life. It also has IE10's upgraded JavaScript engine and includes spell check with auto-correct (finally!). Benchmarks are benchmarks but SunSpider implies about 40% faster than IE9, while PeaceKeeper looks like 25%. The V8 benchmark looks more like 100% faster. Point is, it's faster. How much faster? Depends on who you ask. Your mileage and machines will vary.

Once you've upgraded to IE10, go check out some of these sites. Be sure to view the source!

  • http://ie10bethethief.com - Robert Kirkman from Image Comics (You know him from The Walking Dead) also has a great comic I get each month on Comixology called Thief of Thieves.
    • This new site for Thief of Thieves not only has some great art (lots of SVG!) but also is a good example of using touch and the W3C Pointer Events standard. According to the IE blog, it also uses:
      • CSS3 animations for some of the larger scene transitions on the site
      • MSGesture API for handling more advanced pointer interactions like the safe cracking exercise
      • pageVisibility API to detect when an open page isn’t being actively used so we can control audio appropriately
      • setImmediate API to improve performance and power consumption on tablet devices. SetImmediate, like setInterval and setTimeout, is a timing API and requests the CPU to process the instruction as soon as it’s possible to.
  • Atari Arcade - Lots of classic Atari games, remade using HTML5 and Touch on the web.
  • Pulse - Very cool news aggregator done entirely in HTML5 with support for swipes and multi-finger gestures. Also works nice on mobile phones with responsive design.
  • Contre Jour - The 2011 iPad game of the year is now written in HTML5/JavaScript and CSS3. It works really well on touch systems like my Ultrabook. This originally came out in October but they've just added 20 new levels and it's free!

Developers

Enjoy!


Sponsor: Free eBook - 50 ASP. NET & SQL Server performance tips from the dev community, to help you avoid, find, and fix performance issues in your ASP.NET app. Download it from http://red-gate.com/50ways

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb
Page 1 of 4 in the HTML5 category Next Page

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.