12 ms·
Using SVG as image placeholders
- fenwick67 9y agoThis is the kind of thing that seems really neat (I love computer generated art) but ultimately the user experience isn't any better than just a solid rectangle, and you're sending like 1kb more per image to show the placeholder.
- AnkhMorporkian 9y agoI disagree. If you have a user on a very slow connection on an image heavy site, the user experience will be enhanced significantly. Depending on how you implement it, you might even save them bandwidth. No interesting content for them in the current viewport and they scroll past the placeholders/go to the next page? Cancel the XHR requests you made for the full-size thumbnails/images and start anew.
- ino 9y agoDownside: if it's an image that for some reason doesn't load, the user is confused because it doesn't match the caption. I've had this happen with blurred images on some websites.
- rocky1138 9y agoI agree with GP. Personally, I hate websites that show a blurry version of an image before the final one loads. It plays with my eyes. I have to look away and peek to see if it's done before I can read on. I wish there was a way to disable this functionality.
- AnkhMorporkian 9y agoI didn't mean to refer to blurred images, but the unblurred outline SVGs in this article. I think the blurred ones are somewhat pointless too. The unblurred versions give you actual information as to what the image is. For instance, the sneakers image; if I didn't care about sneakers, I'd be likely to just scroll past it. In the blurred version, I might not be able to tell that they're sneakers.
- deleted 9y ago[deleted]
- jmmcd 9y agoInteresting: I didn't see any images of sneakers. I saw the Golden Gate bridge, and a vague shot of a woman. Are they serving a different set of images (and example js) to different readers?
- AnkhMorporkian 9y agoIt was in the GIF of the Gatsby 3 implementation in the embedded tweet. Here's a direct link to the tweet to save you some time: https://twitter.com/nystudio107/status/920673966091534338?ref_src=twsrc%5Etfw&ref_url=https%3A%2F%2Fmedium.freecodecamp.org%2Fmedia%2F1773750892f5339bc189f993979325e4%3FpostId%3Dbed1b810ab2c https://twitter.com/nystudio107/status/920673966091534338?re... Edit: Maybe they're not sneakers, but they're shoes. I just wear loafers, I really have no idea what any shoe types are called.
- chrismorgan 9y agoDitto. It’s even worse when combined with lazy scroll-based loading: now you’re guaranteeing that I’ll see the unpleasant version briefly (especially in Australia, I imagine, where there’s generally higher latency on such requests than in the USA—but I haven’t tried Medium or similar sites from the USA, so I’m not sure if it’s as unpleasant there). It’s worst of all when combined with lazy scroll-based loading and an unreliable internet connection: I load pages in places where I know I have an internet connection, and then read them in places where an internet connection is unavailable. With lazy loading of these things, I can no longer be confident that it’s actually loaded everything I need. Same deal with Medium’s blocked iframes for things like CodePen—that just means that the iframe is not loaded when I need it to be. I want less magic, not more, because we’ve proven as an industry that we’re not responsible with magic, and always manage to make a mess with it.
- lewisl9029 9y agoYep, the main use case I imagine for something like this would be to show a blurred/tastefully-rendered <10 KB SVG _instead_ of a multi-megabyte hero JPG that still ends up looking horrible on 4K screens.
- untog 9y agoI'm more concerned about CPU time on mobile devices - rendering SVGs then blurring them is surely more intensive than other options. Not saying it isn't worth it, but AFAIK no-one has profiled this.
- nightcracker 9y agoA while back I made something similar, using Voronoi diagrams to approximate an image: https://codegolf.stackexchange.com/a/50345/4162 https://codegolf.stackexchange.com/a/50345/4162 Although that was just for fun, not to create image previews or anything of the sort.
- teej 9y agoWhat went into your decision making process for using Poisson disc sampling? Did you try other sampling methods? I'd love to know anything else you can share about how the preprocessing works.
- nightcracker 9y agoHonestly, I was just messing around, tried this, and it worked. I used an ad-hoc modification of Poisson disc sampling I thought of myself to make certain areas denser / less dense. The preprocessing is also really ad-hoc, just by looking through functions found in scikit-image to form a heuristic that seemed appropriate.
- dlbucci 9y agoReally cool use of SVG. I think the 10 shapes method sans the blur would produce the coolest placeholder images. There's also a pretty impressive level of detail in the 100 shape images. I might have to look into adding something like this into one of my own sites!
- WorldMaker 9y agoYeah, I like the impressionist feel of the low shapes. To me I like that it gives just enough of an impression of the image that is loading that you aren't too worried if an image is slow to load or fails to load that the gist still comes across, but is also still rough enough that it gives the indication that something may still be loading.
- minimaxir 9y agoAnother fun thing to do with using SVG-as-images in the browser is easy animation of the SVG, using Primitive (for example) as noted in the article to convert an image into SVG shapes, plus a tool like Vivus (https://maxwellito.github.io/vivus/ https://maxwellito.github.io/vivus/) or Snap.svg (http://snapsvg.io http://snapsvg.io) to animate each shape of the SVG. Here’s a demo I made using Primitive + Vivus: http://minimaxir.com/2016/12/primitive/ http://minimaxir.com/2016/12/primitive/
- baybal2 9y agoSVG animation is amazing, but as a person who made work with in-browser animation and visualization my breadwinner, I can say that usage of JS for that is a huuuuuge downside Effectively, you have to rewrite a big part of actionscript functionality into your browser to do really simple things It is greatly regrettable than browsermakers have thrown out all declarative animation features, and never thought of improving on them.
- derefr 9y agoIs “declarative SVG animation scripting” really a primitive API you need the browser to support directly? “Rewriting a big part of Actionscript functionality” seems like the job of a JS animation framework, not the browser. Like the ones that animation tools that previously compiled to Flash (e.g. Adobe Animate itself) use.
- baybal2 9y agoJS animations that can approach flash level quality are hard to do. It is like saying that you don't need native video support, but you use JS to interpolate initial image.
- derefr 9y agoThe latter is false because the APIs for image manipulation don't give you features like hardware video-compression-codec decoding, and so you just can't really drive a <canvas> fast enough using JS to draw video on it. The JS graphics+SVG APIs, however, do have all the right primitives exposed to let you do flash-level animation. It's not a matter of incapability; it's just a matter of nobody having coded the right framework, or the right framework (i.e. the one Animate uses) being proprietary and without an open-source attempt to clone it. That doesn't suggest browser vendors should step in and put the capability into the browser, any more than the inability to do realtime 3D without a framework like three.js or a game engine like Unity's HTML5+WebAssembly engine, suggests that browsers should create a common, native game-engine-like API.
- nathan_long 9y agoClever, but I'd love to see browser support for FLIF make this kind of thing irrelevant. > FLIF is lossless, but can still be used in low-bandwidth situations, since only the first part of a file is needed for a reasonable preview of the image. > A FLIF image can be loaded in different ‘variations’ from the same source file, by loading the file only partially. This makes it a very appropriate file format for responsive web design. The loading video on http://flif.info/index.html http://flif.info/index.html makes this clear.
- baybal2 9y ago>Clever, but I'd love to see browser support for FLIF make this kind of thing irrelevant. No, it will not make much difference. You rarely need lossless for anything but stuff like UI elements, which to begin with should not be drawn as PNGs if they are simple graphics that can be drawn as SVG
- nathan_long 9y agoHow will FLIF "not make much difference" here? Suppose we're talking about a profile image. The full, lossless file is 40KB. The video on the FLIF site (http://flif.info/index.html http://flif.info/index.html) shows a blurry-but-useful preview being displayed with the first 0.25% loaded (and possibly before). In this case, that's 100 bytes, which is a fraction of a single TCP packet. Don't need the full resolution of the 40KB lossless file? OK, sure, stop loading after 20KB, or 10KB, or 1KB, or whatever seems like enough. Yes, SVG is still better for things like icons, because you get clear, resizable images with a tiny data transfer. But for previewing a photograph, FLIF seems ideal, and doesn't require any additional tools.
- baybal2 9y agoMaybe, people usually just recode avatars to low-res JPGs
- nathan_long 9y agoFLIF makes re-encoding unnecessary. http://flif.info/responsive.html http://flif.info/responsive.html > for every image, only one file is required, ever. The optimization can happen entirely on the client side. > A FLIF image can be loaded in different ‘variations’ from the same source file, by loading the file only partially. This makes it a very appropriate file format for responsive web design. Since there is only one file, the browser can start downloading the beginning of that file immediately, even before it knows exactly how much detail will be needed. The download or file read operations can be stopped as soon as sufficient detail is available, and if needed, it can be resumed when for whatever reason more detail is needed — e.g. the user zooms in or decides to print the page.
- fogleman 9y ago(Developer of Primitive here.) Love seeing people use my software in different ways! If this looks interesting to you, try it out: https://primitive.lol/ https://primitive.lol/ https://github.com/fogleman/primitive https://github.com/fogleman/primitive Also, I made a Twitter bot that posts samples every 30 minutes based on "interesting" Flickr photos using randomized Primitive settings: https://twitter.com/PrimitivePic https://twitter.com/PrimitivePic
- dmitriid 9y agoYour twitter bot sometimes produces images that look like unintentional art. Awesome job!
- baddox 9y agoThis looks great! I would definitely pay the $10 for an iOS version. I can see myself playing around with this on an iPad Pro for hours, especially with drawing mode.
- xster 9y agoDon't really know how it works, though I wonder if some of the filters in Prisma are implemented in similar ways.
- quakeguy 9y agoWell, this is awesome!
- stuaxo 9y agoI'm definitely a fan of this, though I wonder how small 1 bit gifs or pngs would be for these placeholder silhouette images would be? There are probably more efficient ways of storing the vectors than SVG too, which would help the compression - it would be interesting to see how small these could get.
- abritinthebay 9y agoThere are none that display cross browser however. Which is an issue.
- vardump 9y agoWhich current browsers you have in mind that don't support GIFs or Javascript + SVG (or canvas)?
- abritinthebay 9y agoGifs don’t support vectors and the comment was talking about a more efficient format than SVG. So what on earth are you talking about?
- baybal2 9y agoA real game changing technique! Why? To use progressive JPG, you have to pre-recode (if you don't have money to dish out for FPGA to recode on the fly) and store recoded images. With this, you don't have to alter the original image. My favorite method was to use img tag with blur, you programmatically add image, then you wait when, say 10% of this it is loaded, and abort the request. It will stay that way. When you need to fully load it, you start loading, look for progress events, and set blur accordingly.
- vortico 9y agoI'm not sure why preprocessing progressive JPEGs is an advantage of using this method instead, since you have to process the images to generate the SVG files in the article.
- romaniv 9y ago>To use progressive JPG, you have to pre-recode (if you don't have money to dish out for FPGA to recode on the fly) and store recoded images. Not sure why progressive JPG isn't the default. It's not any larger.
- DamonHD 9y agoThe rules of thumb seem to be that (a) for JPEGs under 10kB progressive may actually be larger and (b) for mobile devices the extra effort (CPU, memory) of progressive decode may be significant eg in taking time away from other parts of page rendering.
- revmoo 9y agoWhy do I have to re-add the header and footer to my adblocker EVERY time a Medium article is posted? How are they evading it?
- rcarmo 9y agoI love the visual effect, but I have to wonder how much CPU/GPU is entailed in rendering 10-50 triangles, blurring them and rendering the result to the page canvas vs. loading a pre-blurred image (that might be a "tiny" progressive JPEG), so I'd probably try to do this server-side first (edit for clarity: my site currently generates <12Kb blurred placeholders from high-def photos and only loads visible images to be more mobile-friendly, and I worry about client-side rendering impacting battery life).
- pbhjpbhj 9y agoJPEG has a thumbnail facility built-in I think, did you try using a pre-created thumbnail scaled up? Or just progressive images?
- rcarmo 9y agoI generate blurred thumbnails from my photos, and then output progressive JPEGs at 80% quality (which is low enough for my purposes and provides a smooth output) Code is here: https://github.com/rcarmo/sushy/blob/master/sushy/utils.hy#L179 https://github.com/rcarmo/sushy/blob/master/sushy/utils.hy#L... The thumbnails you refer to are part of EXIF data, partially designed to allow digital cameras to render previews inside the camera itself in more resource-constrained times.
- baybal2 9y agoI wonder, how many users here know about progressive jpeg, and about the trick with partially loading progressive jpeg file?
- vortico 9y agoThe animation is really fun. Maybe I am unusual, but I have never in my life been annoyed at image load time, even in the dial-up days. I just simply open a new tab or window and continue reading an article or writing code if loading takes too long. But when websites start adding "progressive" placeholders that don't decrease the load time but increase the CPU, that's what annoys me since they prevent multitasked work from being done. If I don't care about the images on the page, I'll continue scrolling, but when my scrolling becomes laggy while an image placeholder is being rendered, it's just unnecessary. So think carefully if you want to take over the resources of your users' computers, which trades visuals for feel. "Feeling" your website (interacting with it) is more important than its appearance at all points in the loading sequence.
- dwb 9y agoHow have people come to the conclusion that displaying a low-information version of the image to be loaded as a placeholder results in a quicker perceived load? To me all these effects just look rubbish and distracting, with no benefit at all – certainly not the perception of speed. It's not like I can ever understand what the image really is before it's fully loaded anyway, with our without fancy placeholder.
- spurgu 9y agoThen use it only for images below the fold?
- hawski 9y agoLoading images as soon as they are within viewport is already too late. You want to load them before user gets there. So you could just not mess up with native browser loading in the first place. Because all those requests and client side calculations will add up. When you have image heavy content please load an image when I'm one or two page heights before the image. This way when I get there it will already be there. You could then just use regular single background placeholders, because I (and I would believe that you also) never intend to see them in the first place.
- ww520 9y agoI think the silhouette version is the best in transitioning from the summary to the full detail.
- frandroid 9y agoThis is an interesting technique for stills; I'd be curious to see it applied to video...
- fogleman 9y agoIt's been done! This one gets progressively more detailed: https://www.youtube.com/watch?v=PyAkgS6Xl1Q https://www.youtube.com/watch?v=PyAkgS6Xl1Q Here's one someone else did: https://vimeo.com/210854333 https://vimeo.com/210854333
- deleted 9y ago[deleted]
- robbrown451 9y agoI'd like to see some analysis of the psychological side of this. I'm not convinced these sorts of previews/placeholders are a positive thing, I find most of them rather distracting. The SVG approach is fine as a novelty, but to assume that this is the best approach from a user point of view is quite a big assumption. My intuition is that the hard edges of SVG are more distracting (attracting your eyes to something that isn't going to give them meaningful information), but that a blurred image messes with your eyes a bit more. I wouldn't really like either of them to be used on the majority of sites. I prefer something very subtle to show that there is an image that is supposed to be there. If it is going to show a single color rectangle, I prefer it be translucent so as to attract even less attention.
- askafriend 9y agoAnecdata: In a newsfeed-type product at our company, we implemented content placeholders that communicate loading state instead of a traditional loading spinner. This reduced user drop off significantly, and bought us some time to work on the real problem under the hood which was latency. Aside from my anecdote, there are many blog posts and experiment results out there that suggests that this works, and it works well.
- robbrown451 9y agoWhat kind of placeholders were they? Also I have suspicions about what you are measuring being 100% correlated with "better user experience." Lack of user drop off CAN indicate a better user experience, but the concept of "click bait" illustrates that you can gain short term increases in attention in ways that both decrease user experience and can contribute to driving away users in the long term. I'm not saying this sort of thing is the same as click bait, but still. I'm sure that in theory, you could put lots of things in those placeholder spots that will increase the number of people that wait for the page to load, but may drive away users in the long term. (e.g. blurry nudes)
- cabalamat 9y agoAm I the only person who finds it ironic that a web page about keeping web pages small comes with multiple megabytes of Javascript? It doesn't need it, folks. It's a static blog page.
- metalliqaz 9y agogotta data mine the pleebs
- limeblack 9y agoI'm on mobile right now and therefore it is difficult to look at source but wouldn't the JavaScript be cached in most scenarios while the images would be unique per page? On a side note I have no JavaScripts on my own blogs.
- lllr_finger 9y agoBesides uncached views (I'm guessing a decent amount of the traffic from HN for this submission would be) you also have to consider parse/eval time. Look at the flame charts in Chrome Dev tools for some of your favorite sites and probably see a few that take almost a second to parse/eval cached JavaScript. It will be even slower for mobile users. Just because it can be cached doesn't mean it's free or even necessary.
- andreareina 9y agoI wouldn't count on anything being in the cache, especially on mobile. Even on desktop, I've just checked my cache and any Medium resource shows exactly 1 hit. With ~350 MB in my cache (default value), it's not going to stay long before being evicted.
- wmeredith 9y agoIt's a Medium article. The author didn't write the platform.
- erikig 9y agoThe faustian bargain that writers of web performance articles make: use a minimal static platform that's fast and get minimal coverage and analytics or use a slower fully fledged platform that offers a built-in audience, analytics and features.
- IshKebab 9y agoAre those SVGs actually smaller than JPEGs included using data URLs?
- dmitriid 9y ago> Actually, the code for the SVG with 10 shapes is really small, around 1030 bytes, which goes down to ~640 bytes when passing the output through SVGO. > The images generated with 100 shapes are larger, as expected, weighting ~5kB after SVGO (8kB before). Looking at images that randomly appear on my hard drive: - 1KB PNG image is a tiny image, 45x30 pixels. Just the Base64 part of it's data uri version is 1476 characters in length - A two-color 152x30px PNG image containing simple text and a logo is already 3KB. It's base64 is 3344 characters in length I don't have any small JPEGs though. The smallest I have is a selfie, 960x960 pixels. It's 79KB in size. My guess is that you probably can produce a tiny JPEG/PNG that would beat SVG, but you'd have to play around with a lot of settings for it: reduce quality etc.
- loopdoend 9y agoThe only savings you get from data URLs are from less HTTP/whatever overhead. It’s like embedding the image in the source so everything gets loaded in one request. Base64 is not compression.
- kylemathews 9y agoIf you want to see this in action in Gatsby, checkout https://using-gatsby-image.gatsbyjs.org/traced-svg/ https://using-gatsby-image.gatsbyjs.org/traced-svg/ It's super easy to integrate this into your site w/ our Image component & GraphQL fragment. See the source code for the page: https://github.com/gatsbyjs/gatsby/blob/master/examples/using-gatsby-image/src/pages/traced-svg.js https://github.com/gatsbyjs/gatsby/blob/master/examples/usin... And component documentation https://www.gatsbyjs.org/packages/gatsby-image/ https://www.gatsbyjs.org/packages/gatsby-image/
- antod 9y agoReminds me of that old mid 90s fractal image format that never took off. When you zoomed in, the photos started turning into shapes of colour blocks rather than raster pixels.
- hasenj 9y agoAm I the only one who found the thing awkward and offputting?
- lifthrasiir 9y agoOnce upon a time Facebook had a similar idea for their app [1] (similar to the OP's use case, because the preview photo was to be included to the initial response). It makes use of the stock JPEG decoder but with the fixed Huffman tree and size to meet the 200-byte size limit. A careful implementation may also work in the Web even without JavaScript. [1] https://code.facebook.com/posts/991252547593574/the-technology-behind-preview-photos/ https://code.facebook.com/posts/991252547593574/the-technolo...
- deleted 9y ago[deleted]
- jankovicsandras 9y agoThis looks interesting. Here's a shameless plug if somebody needs tracing: ImageTracer is a simple raster image tracer and vectorizer that outputs SVG, 100% free, Public Domain. Available in JavaScript (works both in the browser and with Node.js), "desktop" Java and "Android" Java: https://github.com/jankovicsandras/imagetracerjs https://github.com/jankovicsandras/imagetracerjs https://github.com/jankovicsandras/imagetracerjava https://github.com/jankovicsandras/imagetracerjava https://github.com/jankovicsandras/imagetracerandroid https://github.com/jankovicsandras/imagetracerandroid
- rubberduckllc 9y agoLooks interesting. Any interest in building a SaaS model on top of this?
- peteretep 9y agoReading through the comments I'm clearly in the minority, but: For many of these I like the SVG as much as the full image, and start to wonder if the preview/placeholder makes having the actual image irrelevant.
- Tolika 9y agoAs stated in the article, generating the SVG to use as a placeholder can be very expensive. I, myself fiddled with the idea in one of my side-projects and ended up using the technique where I save the dominant colors from an image, which I’m using to create a CSS gradient as the placeholder. The effect can be seen on https://epicpxls.com https://epicpxls.com
- pastelsky 9y agoIs it just me or does anyone else think LQIP on medium are annoying? They become sharp after waiting for a long time and at times never load at all.
- mncolinlee 9y agoFor small icons and images, this is fine and actually pretty cool. However, the rasterization cost of SVG into large images can be significant on mobile device CPUs. It won't speed things up much if the device is rasterizing a lot. That should be taken into account if you're mobile first or building a mobile app.