The following is a guest post by Mat Marquis. Mat has a important PSA for us regarding responsive images.
I don’t want to bury the lede: if you’re using a version of Picturefill from prior to 2.3.1, please update right away—update your /lib
files, file an issue on your project, or run a quick npm update picturefill
and let your mind be set at ease. There haven’t been any breaking changes in any version of Picturefill 2, so you shouldn’t run into any issues updating.
Nothing is on fire, here. Picturefill can’t have any critical security issues; nobody is going to cybercrack your megahertz as a result of a Picturefill bug, or however it is hacking works on television. What this issue could mean for your project is broken images, and what it could mean for web standards—well, that has the potential to be a bigger issue.
The Issue
Using older versions of Picturefill, you may get broken images in both the WebKit Nightly and the Microsoft Edge preview. This is what we in the responsive images industry call “having a bad problem.”
A small but important part of the responsive images specification is the addition of a currentSrc
property on img
, allowing us to get the currently displayed source via JavaScript. With the plain ol’ img
of years past, we could always assume that the value of an src
attribute was the source being shown—it was the only option for an image source, after all. Now that we have tons of new options for serving images in more responsible and context-appropriate ways, that src
attribute may not contain the source currently being shown to the user—hence currentSrc
.
Picturefill polyfills this by writing the current source to a custom currentSrc
property, and browsers without native responsive image support won’t mind this. However, the native currentSrc
implementation in browsers is read-only. The crux of the problem is that Picturefill makes use of the JavaScript use strict
declaration, which means that Picturefill is highly vocal about potential errors. The last things we want when we’re trying to create a 100% spec-compliant polyfill that works everywhere are silent errors. When Picturefill tries to do something browsers don’t want it to, we don’t want the browser to make an exception for us. We want to know about the issue—and fix it—right away. In this case the browser objected to Picturefill attempting to write to a read-only property.
Picturefill relied on a test for picture
element support to decide whether it should run at all—a holdover from its very first versions. When the WebKit and Edge previews rolled out support for srcset
and sizes
without picture
, Picturefill’s test for the picture
element failed, so it attempted to polyfill natively supported features. This included attempting to write to currentSrc
, which resulted in a strict mode
exception. Exceptions cause JavaScript to stop running, so Picturefill stopped—as a result, no images using srcset
were displayed.
Our mistake—my mistake, honestly—was getting spoiled by being so tuned-in to native implementations. For a long time we had the luxury of a clear split in terms of responsive image support: either a browser only supported basic srcset
(only the 1x
, 2x
“device pixel ratio” syntax) or it supported picture
, full srcset
, sizes
, the whole works. Because there was such a predictable divide in browser support, this had always worked fine—and when things work fine, you don’t think much about them. Nobody notices when hinges don’t squeak.
The Bigger Issue
That’s bad, but easy enough to fix code-wise. It’s software; these things happen. That doesn’t mean these kinds of issues are anything resembling “okay,” but bugs do happen. The bigger problem is the potential scope of the issue.
Picturefill came along before picture
, srcset
, or sizes
were a collective twinkle in a browser developer’s eye, and we used it as a prototype to inform the responsive images specification since the very first rough draft. After becoming one of the first real polyfills for all these syntaxes, Picturefill caught on in a huge way—a massive number of websites are using it. That makes this a serious issue, and not just in terms of missing images: if this issue should make it into stable browsers instead of just nightlies and preview builds, it would impact a huge number of websites.
For that reason, Microsoft Edge has temporarily removed currentSrc
support; the first stable version will ship srcset
and sizes
without currentSrc
. WebKit may well do the same. If the issue persists, though, we can’t know when that very necessary feature will be turned back on—if at all. Vendors can’t risk having hundreds—thousands—of websites breaking in their browsers. Until we update Picturefill, we can’t use currentSrc
in WebKit or Edge—and if they scrap it entirely, the other browsers may do the same.
Seriously, Please Update Picturefill
Responsive images came about because of all of us. Not the RICG, not any one person, not any “core” group of influential web standards decision-makers—these are a feature that we designers and developers fought for, paid for, and made real.
The end-game for a new web standard is long, though. Now that we’ve started getting the responsive images we’ve been after for so long, it’s on us to keep it all moving in the right direction—and in this case, that means we need to do a little maintenance. That might be as easy as typing npm update picturefill
or as complex as copying-and-pasting the contents of a file—but it’s a few minutes of work in either case. All of Team Responsive Images is here to help out if any problems should arise, too—you can bet we’re keeping a very close eye out for issues related to updating to 2.3.1, because all of our work depends on Picturefill staying out of the native implementations’ way. If you do run into any problems updating—though I don’t imagine you will—don’t hesitate to email me directly. The Picturefill team—and the entire RICG, if that’s what it takes—will help you get it solved.
Author’s Note: Thanks to Alex Jegtnes and Sarah Forst for editing.
I never thought I’d see a link to xkcd on css-tricks. Maybe I haven’t been looking hard enough until now. Great article, too.
Most projects seem to still be using Picturefill 1.x due to 2.x still failing to display any image if JS is disabled. Does this effect 1.x?
Not an issue in 1.X, no, as that doesn’t polyfill native features.
I’m curious: we’ve seen a lot more Picturefill 2.X activity, but only anecdotally—nothing I could easily site. Have you seen/crunched some numbers around usage by version?
Alternative to picturefill is respimage.
Check it out here – https://github.com/aFarkas/respimage
afarkas is on the Picturefill team, in fact! We’ve shared a lot of ideas and code between the two projects, and he’s taking point on development of the Picturefill 3 Alpha.
Loved the intro :-)
After that, you kinda made a point for not using
use strict
in production code …I’ve definitely heard that point made in the past, and I could be convinced myself. For Picturefill, though, we’d rather see a big bold error early enough that we can patch it up before it hits a stable browser (case in point) than risk a silent mystery error somewhere down the road.