Images are an integral part of the visual language of our websites. Images can be endemic, created by the app developers, or user content. And images weigh more than words. In KBs.
66% of the total size of a web page is images!
This graph shows that the number of image requests is constant while image size is increasing
(View this slide in presentation mode, Steve jobs is hiding a comparative table)
5K and 8K displays have at least 5 times more pixels
Apple’s 2004 announcement of the Cinema HD display - https://www.youtube.com/watch?v=dPCNUExWR6I Cinema HD stats - https://en.wikipedia.org/wiki/Apple_Cinema_Display iPhone stats - http://dpi.lv/ Steve jobs pics - http://img.staticmacg.com/2013/12/macgpic-1387754886-25997049324890-op.jpg http://www.iostipsandtricks.biz/images/201506/20150630202316_k4mrmffpkbj.jpg
Devices with different screen densities require images with different minimal resolutions. Thus, the higher the pixel density, the more pixels an image needs to have to look good
In 2009 half of all screens were 1024x768 or 1280x800. 7 years later the screen widths are much more diverse
The <img> element can only provide single source to everybody, no matter where they fall on this wide spectrum ⇒ “One size fits all”
So we render our images as big as the BIGGEST screen that we want to worry about and scale it to fit with max-width: 100%
Roughly 800KBs of wasted data for the average web page.
Remember that first statistic - that 66% of the average web page is images. if we can cut percentages like these, out of a percentage like that, we can save people enormous amounts of both time and money.
We can’t include a single image resource that’ll work for everybody. We need something else… Delivering alternate image data based on device capabilities to prevent wasted bandwidth and optimize display
RICG (Responsive Images Community Group) proposed solutions - http://usecases.responsiveimages.org/#proposed-solutions
On October 2014, HTML5 was released as a stable W3C Recommendation, bringing the specification process to completion. Client hints are an experimental draft
== Burden on the developer - needs to prepare “transformations” in advance - same image in different sizes
Srcset is a list of one or more strings separated by commas indicating a set of possible image sources for the user agent to use. Each string is composed of: a URL to an image, optionally, whitespace followed by one of: a width descriptor, or a positive integer directly followed by 'w'. The width descriptor is divided by the source size given in the sizes attribute to calculate the effective pixel density. a pixel density descriptor, which is a positive floating point number directly followed by 'x'. If no descriptor is specified, the source is assigned the default descriptor: 1x.
Sizes tells the browser what size the image will be in relation to the size of the viewport. And we can tell the browser how that relationship changes as the size of the viewport changes.
The browser can take into account additional considerations such as network type, latency
Same support matrix as srcset
Unlike srcset and sizes, when you use the media attribute, you are dictating to the browser which source should be used.
Regarding srcset and sizes - if I have `small.jpg 100w, large.jpg 500w` a lot of devs will expect that as soon as the image grows to be 101px wide, we load large.jpg Chrome does that at 1x. But at higher DPIs, it says, hey, a little upscaling won’t hurt, and uses geometric mean… so only switches to large.jpg at sqrt(100*500)=224px
The browser will pick the first source where the declared image type is one that it supports
Browsers know more about the user and their context & needs at load time, than you do when you’re writing the code.
The “Width” request header field is a number that indicates the desired resource width in physical px (i.e. intrinsic size of an image)
DPR - a number that indicates the client’s current Device Pixel Ratio (DPR), which is the ratio of physical pixels over CSS px Viewport-Width - a number that indicates the layout viewport width in CSS px Width - a number that indicates the desired resource width in physical px (i.e. intrinsic size of an image) Downlink - a number that indicates the client’s maximum downlink speed in megabits per second (Mbps) Save-Data - indicates client’s preference for reduced data usage, due to high transfer costs, slow connection speeds, or other reasons.
Client hints are a set of HTTP headers that allow browsers to indicate a list of device and agent specific preferences. Servers can then use these "client hints" to assist in content negotiation, ideally resulting in content being served that best matches the environmental conditions of the client for the resource being requested. You need backend logic for this type of content negotiation
These solutions also require the developer to create the image files in advance for each variant (size / file type / art direction)
We’ve seen the existing solutions, now let’s see how Cloudinary helps with their implementation
Responsive breakpoints generator should be used for generating file-sized based breakpoints - http://www.responsivebreakpoints.com/
We are using the branch “angular_next” since we already had a “cloudinary_angular” repo, and couldn’t come up with a proper name for a new one. Once Angular will gain enough traction it will replace master branch, and we will move AngularJS into a dedicated branch.
The new Angular branch contains 4 samples in the Github repository: Angular CLI Webpack + ng2-file-upload SystemJS + jQuery file upload Angular AOT + Rollup
An img is worth a thousand words
An <img> is worth a 1000
Srcset & sizes
The srcset attribute provides a list of possible image sources and the width
or pixel density of each image file.
The sizes attribute specify the intended display size of the image.
Srcset & sizes
<img sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
Image file width in pixels
Size allocated for the image per viewport
Fallback for older browsers
Choosing the right image
The browser chooses the image to render!
if a supporting browser with a viewport width of 480px loads the page, the
(max-width: 480px) media condition will be true, therefore the 440px slot
will be chosen, so the medium-res.jpg will be loaded, as its inherent width
(480w) is the closest to 440px.
The <picture> element is a container used to specify multiple <source>
elements for a specific <img> contained in it.
It provides fine-grained control through media queries for choosing the
applicable source or the image type to use.
<picture> & media
<source srcset="cloudinary-logo-wide.png" media="(min-width: 600px)">
<img src="cloudinary-logo-narrow.png" alt="Cloudinary">
Media attribute is a directive, not a suggestion
<picture> & type
<source srcset="cloudinary-logo.svg" type="image/svg+xml">
<source srcset="cloudinary-logo.svg" type="image/webp">
<img src="cloudinary-logo.png" alt="Cloudinary">
The type attribute allows you to declare different image types that the browser
can choose from.
Cloudinary offers an end-to-end solution for all your image and video needs,
including upload, storage, administration, manipulation and delivery.
Let’s focus on how it helps with responsive images
Cloudinary Angular SDK
Blog - https://goo.gl/oQFwua
Github - https://github.com/cloudinary/cloudinary_angular/tree/angular_next
● Use srcset and sizes attributes for responsive images
○ Let the browser do the heavy lifting
○ Breakpoint by file size
● Use <picture> for art-direction
● An image service can take away the pain