Source placeholder for lazy loading images - javascript

I'm using a lazyload mechanism that only loads the relevant images once they're in the users viewport.
For this I've defined a data-src attribute which links to the original image and a base64 encoded placeholder image as src attribute to make the HTML valid.
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-src="/path/to/image.png" alt="some text">
I noticed that chrome caches the base64 string but the string is quite long and bloats my HTML (I have a lot of images on a page).
So my question is if it's better to use a small base64 encoded or a 1px x 1px placeholder image?
Note:
For SEO purposes the element must be an img. Also my HTML must be valid, so a src attribute is required.

You can use this shorter (but valid!) image in the src tag (1x1 pixel GIF):
data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=
Note that if you gzip your HTML (which you should), the length of the string won't be that important because repetitive strings compress well.
Depending on your needs you might want to use a color for the 1x1 pixel (results in shorter gif files). One way to do this is using Photoshop or a similar tool to create the 1x1 pixel GIF in the right color, and then using a tool like ImageOptim to find the best compression. There's various online tools to convert the resulting file to a data URL.

I'd use the placeholder in your situation.
Using the base64 encoded image kind of defeats the purpose of lazy loading since you're still having to send some image data to the browser. If anything this could be detrimental to performance since the image is downloaded as part of the original HTTP request, rather than via a separate request as a browser might make with an image tag and URL.
Ideally if it's just a 'loading' placeholder or something similar I'd create this in CSS and then replace it with the loaded image when the user scrolls down sufficiently as to invoke the loading of that particular image.

I noticed that chrome caches the base64 string but the string is quite long and bloats my HTML (I have a lot of images on a page).
If that is the case, consider placing a 'real' src attribute pointing to always the same placeholder. You do need an extra HTTP request, but:
it will be almost certainly pipelined and take little time.
it will trigger the image caching mechanism, which base64 does not do, so that the image will actually be only decoded once. Not a great issue given today's CPUs and GPUs, but anyway.
it will also be cached as a resource, and with the correct headers, it will stay a long time, giving zero load time in all subsequent page hits from the same client.
If the number of images on a page is significant, you might easily be better off with a "real" image.
I'd go as far as to venture that it will be more compatible with browsers, spiders and what not -- base64 encoding is widely supported, but plain images are even more so.
Even compared with the smallest images you can get in base64, 26 bytes become this
src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
while you can go from
src="/img/p.png"
all the way to
src="p.png"
which looks quite unbloaty - if such a word even exists.
Test
I have ran a very basic test
<html>
<body>
<?php
switch($_GET['t']) {
case 'base64':
$src = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
break;
case 'gif':
$src = 'p.gif';
break;
}
print str_repeat("<img src=\"{$src}\"/>", $_GET['n']);
?>
</body>
</html>
and I got:
images mode DOMContentLoaded Load Result
200 base64 202ms 310ms base64 is best
200 gif 348ms 437ms
1000 base64 559ms 622ms base64 is best
1000 gif 513ms 632ms
2000 base64 986ms 1033ms gif is best
2000 gif 811ms 947ms
So, at least on my machine, it would seem I'm giving you a bad advice, since you see no advantages in page load time until you have almost two thousand images.
However:
this heavily depends on server and network setup, and even more on actual DOM layout.
I only ran one test for each set, which is bad statistics, using Firebug, which is bad methodology - if you want to have solid data, run several dozen page loads in either mode using some Web performance monitoring tool and a clone of your real page.
(what about using PNG instead of gif?)

I've experienced good results with inline SVG for responsive image placeholders as described here.
Basically, you put something like
data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 500 500'%3e%3c/svg%3e
in your <img>'s src attribute. Beware to keep viewBox values aspect ratio on par with your real image dimensions. This way your layout won't jump around causing unnecessary repaints.

Related

Is it possible to interlace every image on my website?

I am creating a website which contains posts. Every post has an image. Feed page of the website is slow because every image takes a lot of time to be downloaded and while it is downloading it is a blank space and it does not look nice. Images are uploaded by users and are of different formats. Is it possible to somehow make it so that images first appear blurry and then they start becoming less and less blurry as they load (I’ve read it is called interlacing)?
I have tried searching on the internet but didn’t find anything on the topic but the usage of .jpeg format which does not seem to work because even the .jpegs I have as post images are not loading interlaced and I cannot exactly force people to use only that format.
Images take time to load because they are relatively large files and the data in them has to be transferred over the network.
Interlacing is a a feature of the JPEG format that gives visible process as the image loads by reordering the image data so it doesn't run sequentially (Wikipedia has diagrams and animations which might be helpful in understanding that.)
If you want interlacing in the image then you need to make sure it is in the image. You can't really change that outside the image.
While it is impractical to ask users to upload images encoded that way, you can write server side code to convert images to meet you standards. When converting them you could also perform other optimisations (such as reducing the dimensions or increasing the compression level) that would speed up the load time. Of course, this will have an impact on image quality which might not be desirable. (Consider Flickr, for example, which provides a degraded image (with smaller file size) by default but allows switching to higher quality or original images on demand).
You could also consider displaying placeholder images while the full version loads. These could also be generated server side from the upload images and have extremely high levels of compression and resizing so you just display a small number of large pixels that give a vague impressions of the average colour over large chunks of the image until the real image is available to the browser.

Lazy loading images with accessibility and printer support

I am looking for a proper way to implement lazy loading of images without harming printability and accessibility, and without introducing layout shift (content jump), preferrably using native loading=lazy and a fallback for older browsers. Answers to the question How lazy loading images using JavaScript works?
included various solutions none of which completely satisfy all of these requirements.
An elegant solution should be based on valid and complete html markup, i.e. using <img src, srcset, sizes, width, height, and loading attributes instead of putting the data into data- attributes, like the popular javascript libraries lazysizes and vanilla-lazyload do. There should be no need to use <noscript> elements either.
Due to a bug in chrome, the first browser to support native lazyloading, images that have not yet been loaded will be missing in the printed page.
Both javascript libraries mentioned above, require either invalid markup without any src attribute at all, or an empty or low quality placeholder (LQIP), while the src data is put into data-src instead, and srcset data put into data-srcset, all of which only works with javascript. Is this considered an acceptable or even best practice in 2020, and does this neither harm the site accessibility, cross-device compatibility, nor search engine optimization?
Update:
I tried a workaround for the printing bug using only HTML and CSS #media print background images in this codepen . Even if this worked as intended, there would be a necessary css directive for each and every image, which is neither elegant nor generic. Unfortunately there is no way to use media queries inside the <picture> element either.
There is another workaround by Houssein Djirdeh at at lazy-load-with-print-ctl1l4wu1.now.sh using javascript to change loading=lazy to loading=eager when a "print" button is clicked. The same function could also be used onbeforeprint.
I made a codepen using lazysizes.
I made another codepen using vanilla-lazyload .
I thought about forking a javascript solution to make it work using src and srcset, but this must probably have been tried before, the tradeoff would be that once the lazyloading script starts to act on the image elements, the browser might have already started downloading the source files.
Just show me your hideous code, I don't want to read!
If you don't want to read my ramblings the final section "Demo" contains a fiddle you can investigate (commented reasonably well in the code) with instructions.
Or there is a link to the demo on a domain I control here that is easier to test against if you want to use that.
There is also a version that nearly works in IE here, for some reason the "preparing for print" screen doesn't disappear before printing but all other functionality works (surprisingly)!
Things to try:
Try it at different browser sizes to see the dynamic image requesting
try it on a slower connection and check the network tab to see the lazy loading in action and the dynamic change in how lazy loading works depending on connection speed.
try pressing CTRL + P when the network connection is slow (without scrolling the page) to see how we load in images not yet in the DOM before printing
try loading the page with a slow network connection and then using FILE > PRINT to see how we handle images that have not yet loaded in that scenario.
Version 0.1, proof of concept
So there is still a long way to go, but I thought I would share my solution so far.
It is complex (and flawed) but it is about 90% of what you asked for and potentially a better solution than current image lazy loading.
Also as I am awful at writing clean JS when prototyping an idea. I can only apologise to any of you brave enough to try and understand my code at this stage!
only tested in chrome - so as you can imagine it might not work in other browsers, especially as grabbing the content of a <noscript> tag is notoriously inconsistent. However eventually I hope this will be a production ready solution.
Finally it was too much work to build an API at this stage, so for the image resizing I utilised https://placehold.it - so there are a few lines of redundant code to be removed there.
Key features / Benefits
No wasted image bytes
This solution calculates the actual size of the image to be requested. So instead of adding breakpoints in something like a <picture> element we actually say we want an image that is 427px wide (for example).
This obviously requires a server-side image resizing solution (which is beyond the scope of a stack overflow answer) but the benefits are massive.
First of all if you change all of your breakpoints on the site it doesn't matter, so no updating picture elements everywhere.
Secondly the difference between a 320px and 400px wide image in terms of kb is over 40% so picking a "similarly sized" image is not ideal (which is basically what the <picture> element does).
Thirdly if people (like me) have massive 4K monitors and a decent connection speed then you can actually serve them a 4K image (although connection speed detection is an improvement I need to make in version 0.2).
Fourthly, what if an image is 50% width of it's parent container at one screen size, 25% width of it's parent container at another, but the container is 60% screen width at one screen size and 80% screen width at another.
Trying to get this right in a <picture> element can be frustrating at best. It is even worse if you then decide to change the layout as you have to recalculate all of the width percentages etc.
Finally this saves time when crafting pages / would work well with a CMS as you don't need to teach someone how to set breakpoints on an image (as I have yet to see a CMS handle this better than just setting the breakpoints as if every image is full width on the screen).
Minimal Markup (and semantically correct markup)
Although you wanted to not use <noscript> and avoid data attributes I needed to use both.
However the markup you write / generate is literally an <img> element written how you normally would wrapped in a <noscript> tag.
Once an image has fully loaded all clutter is removed so your DOM is left with just an <img> element.
If you ever want to replace the solution (if browser technology improves etc.) then a simple replace on the <noscripts> would get you to a standard HTML markup ready for improving.
WebP
Of course this solution requests WebP images if supported (its all about performance!). On the server side you would need to process these accordingly (for example if an image is a PNG with transparency you send that back even if a WebP image is requested).
Printing
Oh this was a fun one!
There is nothing we can do if we send a document to print and an image has not loaded yet, I tried all sorts of hacks (such as setting background images) but it just isn't possible (or I am not clever enough to work it out....more likely!)
So what I have done is think of real world scenarios and cover them as gracefully as possible.
If the user is on a fast connection we lazy load the images, but we don't wait for scroll to do this. This could mean a bit more load on our servers but I am acting like printing is highly important (second only to speed).
If the user is on a slow connection then we use traditional lazy loading.
If they press CTRL + P we intercept the print command and display a message while the images are loading. This concept is taken from the example OP gave by Houssein Djirdeh but using our lazy loading mechanism.
If a user prints using FILE > PRINT then we instead display a placeholder for images that have not yet loaded explaining that they need to scroll the page to display the image. (the placeholders are approximately the same size as the image will be).
This is the best compromise I could think of for now.
No layout shifts (assuming content to be lazy loaded is off-screen on page load).
Not a 100% perfect solution for this but as "above the fold" content shouldn't be lazy loaded and 95% of page visits start at the top of the page it is a reasonable compromise.
We use a blank SVG (created at the correct proportions "on the fly") using a data URI as a placeholder for the image and then swap the src when we need to load an image. This avoids network requests and ensures that when the image loads there is no Layout Shift.
This also means the page is semantically correct at all times, no empty hrefs etc.
The layout shifts occur if a user has already scrolled the page and then reloads. This is because the <img> elements are created via JavaScript (unless JavaScript is disabled in which case the image displays from the <noscript> version of the image). So they don't exist in the DOM as it is parsed.
This is avoidable but requires compromises elsewhere so I have taken this as an acceptable hit for now.
Works without JavaScript and clean markup
The original markup is simply an image inside a <noscript> tag. No custom markup or data-attributes etc.
The markup I have gone with is:
<noscript class="lazy">
<img src="https://placehold.it/1500x500" alt="an image" width="1500px" height="500px"/>
</noscript>
It doesn't get much more standard and clean as that, it doesn't even need the class="lazy" if you don't use <noscript> tags elsewhere, it is purely for collisions.
You could even omit the width and height attributes if you didn't care about Layout Shift but as Cumulative Layout Shift (CLS) is a Core Web Vital I wouldn't recommend it.
Accessibility
The images are just standard images and alt attributes are carried over.
I even added an additional check that if alt attributes are empty / missing a big red border is added to the image via a CSS class.
Issues / compromises
Layout Shift if page already scrolled
As mentioned previously if a page is already scrolled then there will be massive layout shifts similar to if a standard image was added to a page without width and height attributes.
Accessibility
Although the image solution itself is accessible the screen that appears when pressing CTRL + P is not. This is pure laziness on my part and easy to resolve once a more final solution exists.
The lack of Internet Explorer support (see below) however is a big accessibility issue.
IE
UPDATE
There is a version that nearly works in IE11 here. I am investigating if I can get this to work all the way back to IE9.
Also tested in Firefox, Edge and Safari (mobile), seems to work there.
ORIGINAL
Although this isn't tested in Firefox, Safari etc. it is easy enough to get to work there if there are issues.
However accessing the content of <noscript> tags is notoriously difficult (and impossible in some versions) in IE and other older browsers and as such this solution will probably never work in IE.
This is important when it comes to accessibility as a lot of screen reader users rely on IE as it works well with JAWS.
The solution I have in mind is to use User Agent sniffing on the server and serve different markup and JavaScript, but that is complex and very niche so I am not going to do that within this answer.
Checking Latency
I am using a rather crude way of checking latency (to try and guess if someone is on a 3G / 4G connection) of downloading a tiny image twice and measuring the load time.
2 unneeded network requests is not ideal when trying to go for maximum performance (not due to the 100bytes I download, but due to the delay on high latency connections before initialising things).
This needs a complete rethink but it will do for now while I work on other bits.
Demo
Couldn't use an inline fiddle due to character count limitation of 30,000 characters!
So here is the current JS Fiddle - https://jsfiddle.net/9d5qs6ba/.
Alternatively as mentioned previously the demo can be viewed and tested more easily on a domain I control at https://inhu.co/so/image-concept.php.
I know it isn't the "done thing" linking to your own domains but it is difficult to test printing on a jsfiddle etc.
The proper solution for printable lazy loading in 2022 is using the native loading attribute.
<img loading=lazy>
The recommendation to use a custom print button has been obsoleted as chromium issue 875403 got fixed.
Prior recommendations included adding a custom print button (which did not fix the problem when using the native browser print functionality) or using JavaScript to load images onBeforePrint the latter not being considered a good solution, as loading=lazy, as a "DOM-only" solution, must not rely on JavaScript.
Beware that, even after the bug fix, some of your users might still visit your site with a buggy browser version.
#Ingo Steinke Before one dwells into answers for the concerns that you have raised, one has to go back and think about why lazy loading came about and for what detriment it solved on initiation as framework of thought. Keyword framework of thought... it is not a solution and I would go on a leaf to say it has never been a solution but framework of thought.
Why we wanted it:
Minimise unnecessary file fetching from server - this is bandwidth critical if one is running a large user base. So it was the internet version of just in time as in industrial production.
Legacy browser versions and before async and defer were popularised in JS/HTML, interactivity with the browser window remained hampered until all content was loaded.
Now broad band as we know it has only been around since the last 6-7 years in real sense of manner and penetration. We wanted it because we didn't want to encounter no.2 on low bandwidth. To be honest, there was and still is a growing concern and ideology of minifying and zipping JS and CSS files - all because that round trip to server and back should be minimised so that next item in the list could be fetched. Do keep in mind browsers tend to limit simultaneous downloading connections to around 6 at a time per window or active window. There is reasons why Google popularised the 3 second rule. If above were to let run on as it than 3 second rule will fall on its head as if it did not have legs.
So came along thought frameworks.
Image as CSS background: This came as it did not mess up the visual aspect of the page. Everything remained as it is in its place and then suddenly became colourful. It was time when web pages seemed to have elastic fit i.e. it was that bag which once filled with air suddenly poped-transformed into jumping castle. This was increasingly become bad idea as front end developer. So fixing height and with of the container then run images as background helped and HTML5 background alignment properties upgraded them self accordingly. There was even variant and still used as in use multiple backgrounds one being loading spiril or low end blured image version on top of which actual intended image was fetched. Since level down bacground would be fetched and populated everywhere in single instance of downloading it created a more pleasing visual and user knew what to expect. worked in printing as well even if intended image did not download.
Then came JS version of it by hijacking DOM either through data-src, invalid image tags removing src, and what not. only trigger the change when content is scrolled to. Obviously there would be lag but that was either countered through CSS approach implemented in JS or calculating scroll points and triggering event couple of pixel ahead. They all still work on the same premise.
There is one question that begs to be asked and you have touched it in your pretext .... none of it controls or alters browser native functionality. Browser might as will go fetch the item even before your script had anything to do with any thing.
This is the main issue here. BOM does not care and even want to care about what your script is asking to do all it knows if there is a src property fetch the content. None of the solutions have changed that. If we could change that functionality then thought framework would become solution.
I still believe browsers should not change that just for the sake of it and thus never gained tracking in debates. What browsers have done is pre-fetching known as speculative or look-ahead pre-parser, It is the single biggest improvement in browsers that deserves it credit. Just as we type url in address bar on every chnage of string browser is pre-fetching the content even though I had not typed the whole url. I had specially developed a programme where I grabbed anything that was received at server from these look-ahead pre-parsers. It takes less than second to get response at most times and browsers begin to process it all including images and JS. This was counter the jerky delayed elastic prone display as discussed in No.1 and No.2. It did not reduce the server hit however. The reason why we are doing lazy loading any ways. But some JS workaround gained traction as there was no src property so pre-parser did not fetch the image and was only done so when user actually sent to the page and events were triggered. Some browser have toyed with the idea of lazy loading them self but let go if it as it did not assume universal consistency in standard.
Universal Standard is simple if there is src property browser will fetch the item no if and buts. Imagine if that was not the case OMG hell would break loose on poor front-end developer.
So deep down what you are raising in debate is the question regarding BOM functionality as I have discussed above. There is no work around for it. In your case both for screen and print version of display. How to make sure images are loaded when print command is sent. Answer is simple for BOM print is after the fact. Fact ebing screen display and before the fact being everything before that at BOM/DOM propagation level. Again you cannot change that.
So you have to make trade off. Trade off would come in the form of another thought framework. rather than assuming everything is print ready make it print ready on user command. There is div that pops up and shows printed version of document and then print from there on. UI could be anything it would only take second or so as majority of the content would be loaded any ways and rest will take short amount of time. CSS rules for print could mighty handy in this respect. You can almost see it in action in may places on the internet.
conclusion as we stand today where we are with BOM functionality bundling the screen display and print display with lazy load is not what lazy lading was intended for thus does not provide any better solution then mere hacks. So you have to create your UI based on your context separating the two, to make it work properly.

Showing a page content at once

I have a website which contains some images in index.php
The problem I am facing is the whole page is not loading at once, I think images are taking some time to load
So what I have done is, I am showing an loading image at first and then after some time I am showing the page, that resolves the problem. But I am curious to know is there any other better way to do this?
I prefer to optimise the hell out of my images.
PNG images
You can use pngcrush to optimise your PNG files for you, but personally I find that once I'm done with it pngcrush only succeeds in making it bigger.
Use Indexed-PNG wherever possible. This will limit you to 256 colours, and most graphics editors won't allow partial transparency in Indexed-PNG (but it is possible - you just need the right editor. I use a custom PHP script with the GD image library) but you can expect to drop file size down to just a tiny fraction of what it was.
Reduce the amount of colours overall. PNG compression works best with blocks of the same colour, so reducing the number of colours improves compression.
GIF images
Especially for animations, there's a lot of things you can do.
Reduce the number of frames. Avoid duplicate frames at all costs, and just set the previous frame to have a longer display time.
Use combine rather than replace if possible. You will again have problems with transparent areas, but by using combine you can have each subsequent frame only change the stuff that... changes. This avoids the redundancy of re-writing the entire image if only a small part changes. GIMP has a useful filter "Animation > Optimize for GIF" which will do this for you.
Reduce colours as much as possible. GIF is limited to 256 colours, but if you can limit yourself to 32 or so, you'll get a much smaller file.
Using the above techniques, I once managed to shove 8MB of raw image data into a 125kb animated GIF.
JPG images
JPG is great for photos, but cameras have a tendency to write MASSIVE files.
Play around with the compression factor. Start at around 40%, and slowly bring it up until it looks acceptable. GIMP will show you a preview and the resulting filesize, so make use of that to find an acceptable compromise.
Scale the image down. You don't need 9 megapixels or however massive resolution cameras take now...
The above should help you reduce the amount of size taken by your images. Obviously, you should also cache images appropriately, so they only need to be retrieved once. Also make sure that you specify width and height on image elements so that the browser can reserve the space for them and avoid jumping around as they load...
And you should be pretty good.
It's hard to say what other options are available without knowing what the page looks like, but one option is to reserve space for the images so that the page text renders quickly in the correct position, and the images then load later.

Load images before loading any html element

I would like to have my background images ready before the HTML loads.
But, what is happening is some of my HTML elements like input elements are being loaded before the image is loaded in the background.
I have looked at lot of questions where they show how to preload the image. But, that some how doesn't solve my issue.
This is not what you want to do.
For the user this will result in decreased usability and a lack of responsiveness. You'll lose visitors very quickly making them wait for something. Take it the opposite direction and fill in the empty spot with a color while the image loads in the background.
However, if you really want to do this, there is a way to line them all up and load at the same time. You can convert your images to Base64 encoding and paste the code directly into the HTML or CSS.
Here is a very good article on Base64 encoding images and including them inline. Essentially what you'll be doing is turning a picture into text, pasting that text directly in your HTML, JS and/or CSS and then the browser turns it back into an image.
Use your favorite image editor and get your images down to < 32KB, then upload them to this page that will convert it into a long string of characters. If they are larger than 32KB you'll notice browser performance issues as well as incompatibility with Internet Explorer.
You'll take that string of characters and paste it directly where you would normally put the image URL. So if it's in HTML as a standalone image, you would say:
<img src="data:image/png;base64,iVBORw0KGgoAAAA... etc" />
For a CSS image (background-image, for example) it would follow this format:
background-image: url(data:image/png;base64,iVBORw0KGgoAAAA... etc);
Now, depending on how many you include in each file and how large they are, your site will not be very fast to download at first but after caching it won't be a noticeable issue.
You have to delay the loading of the html part. Use any javascript image preloading technique, like this one:
var x=new Image();
x.src="whatever.jpg";
...and then, use $.load(...) to load any further html into a div that's initially empty.

Does using canvas result in a smaller HTTP request than using an image

I know converting any image format to SVG is not an easy task, and it is not something I am pursueing for complex images. Let me explain why I am asking this question. As a web designer, there are elements in a site that I will commonly use an image for. There include simple geometric shapes, fleur-de-lis, some simple logos etc. The cost of these HTTP requests is relatively small (we are talking KB's here).
However, I am interested if these requests could be even smaller by using svg or other canvas elements instead of an image format for simple images. Has there been any research or testing to compare SVG vs. an image? Is it possible that I can make HTTP requests even smaller by using canvas for simple elements on my page? If so it would be great news. I could even start creating libraries of canvas images to re-use and share with others.
For simple shapes gzipped SVG will be pretty small and in modern browsers it's quite usable.
However, for page loading performance number of requests is a very big factor, so you'll get significant performance boost if you use CSS sprite sheets regardless of the image format.
If by canvas you mean storing shapes as JavaScript drawing commands (or a library that issues them based on some JSON) then it's unlikely to be big bandwidth saving compared to gzipped SVG (SVG has quite efficient format for defining paths, and gzip removes overhead of XML quite well).
You will have to wait for JS to load and either insert several canvases all over the document or burn CPU on compressing generated images and building data: URLs, so I don't think it'd be faster overall than using SVG or optimized PNG.
I think this will depend on the case.
Sprites can help.. but what if your sprite contains some simple lines yet must be 500px * 500px... then a canvas (or even svg) will indeed be a lot smaller. On top of that, external javascripts usually are cached (even better than images). In that regard, they indeed help slim down the weight.
However, if you'd expect IE to also 'work', then you might need to start to provide some html5/canvas shims and yes that would increase the weight.
Edit:
Look at this jsfiddle example (I whipped up for this question) where a full-size 'granite' background is created with a radial gradient.
As you can see (in the source) this is a LOT less bytes then a separate image (and will alway's be pixel-perfect).
On the other hand, it also (depending on the complexity) take some calculation-time that regular images wouldn't take (after the necessary bytes are downloaded to the client).
Edit2:
I found a link where they did a little test.
In our sprite example, the raw SVG file was 2445 bytes. The PNG
version was only 1064 bytes, and the double-sized PNG for double-pixel
ratio devices was 1932 bytes. On first appearance, the vector file
loses on all accounts, but for larger images, the raster version more
quickly escalates in size.
SVG files are also human-readable due to being in XML format. They
generally comprise a very limited range of characters, which means
they can be heavily Gzip-compressed when sent over HTTP. This means
that the actual download size is many times smaller than the raw file
— easily beyond 30%, probably a lot more. Raster image formats such as
PNG and JPG are already compressed to their fullest extent.
However, note all this is still depending how complex the image is: as an extreme counter-example.. try to describe a full color photo of a forrest (leaves..) versus simply a jpg..
The size always depends on the specific images, sorry but you have to test it at your own. There is no way to compare this in general.

Categories