{"id":21844,"date":"2019-02-11T17:25:06","date_gmt":"2019-02-11T17:25:06","guid":{"rendered":"http:\/\/a_chaotic_good_guide_to_image_performance_part_2"},"modified":"2022-02-26T04:00:15","modified_gmt":"2022-02-26T04:00:15","slug":"a_chaotic_good_guide_to_image_performance_part_2","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2","title":{"rendered":"A Chaotic Good Guide to Image Performance, Part 2"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p><a href=\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_1\">Part 1<\/a> of this series delves into the background for this guide. Here in part 2 are the ins and outs.<\/p>\n<h3>\u201cJust get rid of some images.\u201d<\/h3>\n<p>Wait, hear me out. I know, we just talked about this: Nobody is sheepishly pleading you, \u201cPlease, might we have just <em>one more<\/em> image on the page?\u201d No, I\u2019m not telling you to pick that particular fight. Instead, use a little smoke and mirrors to avoid requests for images that your audience  needn\u2019t render right away and might never need at all while loading them asynchronously\u2014only as needed.<\/p>\n<p>Until a few years ago, nothing much had changed about <code>img<\/code> since its inception back in December 1992. For the most part, if your markup contained an image with  an <code>src<\/code> attribute, the browser wouldn\u2019t give you any choice: It would request and transfer that image  ASAP. To <a href=\"https:\/\/timkadlec.com\/2012\/04\/media-query-asset-downloading-results\/\">avoid or defer an image request the audience might not see in some contexts<\/a>, removing it from the page was your only option. Even during the earliest days of prototyping potential \u201cresponsive images\u201d solutions, it was clear that <code>img<\/code> would benefit from more flexibility because loading images asynchronously, that is, only when scrolled into view, was a convoluted process. Listening to scroll events is expensive, likewise for listening for the resizing of the browser window. Determining whether an image had scrolled into view would mean doing both while checking and rechecking the position of each image on the page. Such a task was labor-intensive, let alone that the results were always\u2014pardon my candor\u2014pretty janky.<\/p>\n<p>Fast forward to the present day, and we have the experimental <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Intersection_Observer_API\">Intersection Observer API<\/a>. As its name implies, <code>IntersectionObserver<\/code> enables us to efficiently observe if the elements visibly intersect with the browser viewport and, if so, are visible online. When applied to <code>img<\/code>, the API presents a simple, powerful, and largely seamless way to avoid unnecessary image requests.<\/p>\n<p>With only a few lines of code, we can put together a script that asynchronously requests images only when they intersect with the audience\u2019s viewport. No fuss, no muss, and hardly anything for us to manage:<\/p>\n<ul>\n<li>Source: <a href=\"https:\/\/github.com\/Wilto\/async-images\/blob\/master\/async.js\">https:\/\/github.com\/Wilto\/async-images\/blob\/master\/async.js<\/a>\n<\/li>\n<li>Demo: <a href=\"https:\/\/wilto.github.io\/async-images\/\">https:\/\/wilto.github.io\/async-images\/<\/a>\n<\/li>\n<\/ul>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span>\n  <span class=\"hljs-attr\">data-lazy<\/span>\n  <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\"<\/span>\n  <span class=\"hljs-attr\">data-src<\/span>=<span class=\"hljs-string\">\"\/img\/source-4.jpg\"<\/span>\n  <span class=\"hljs-attr\">sizes<\/span>=<span class=\"hljs-string\">\"(min-width: 1000px) 50vw, 95vw\"<\/span>\n  <span class=\"hljs-attr\">data-srcset<\/span>=<span class=\"hljs-string\">\"\n        \t\/img\/source-1.jpg 320w,\n        \t\/img\/source-2.jpg 450w,\n        \t\/img\/source-3.jpg 640w,\n        \t\/img\/source-4.jpg 820w,\n        \t\/img\/source-5.jpg 1024w\"<\/span>\n  <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"\u2026\"<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The above script does the following:<\/p>\n<p>Loops through every <code>img<\/code> on the page with the attribute <code>data-lazy<\/code>.\nSwaps the contents of the <code>data-<\/code> attributes with the corresponding <code>img<\/code> attributes. The source specified in <code>data-src<\/code> replaces the encoded placeholder in the original <code>src<\/code>. <code>data-srcset<\/code>, if present, becoming <code>srcset<\/code>.\nLeaves <code>sizes<\/code> as-is since it only describes how an image appears  on the page, initiating no requests at all.<\/p>\n<p>In browsers that support <code>IntersectionObserver<\/code>, the above logic applies only if some part of the image occupies the audience\u2019s viewport. In browsers that don\u2019t, all that swapping logic applies once <code>DOMContentLoaded<\/code> acts. After all, we don\u2019t want to leave anyone <em>without<\/em> those images.<\/p>\n<p>To revive a deeply nostalgic term, that encoded \u201c<a href=\"https:\/\/en.wikipedia.org\/wiki\/Spacer_GIF\">spacer GIF<\/a>\u201d is important. Omitting a <code>src<\/code> value altogether could display only a brief flash of a seemingly-broken image before the new source has finished rendering. Because the content of <code>src<\/code> is always requested before we have a chance to tinker with our markup, citing an external source there, no matter how small, would mean incurring the extra performance cost of a request to no real benefit. That tiny encoded GIF avoids both traps.<\/p>\n<p>If all that feels like something browsers could be handling for us, I completely agree, and we\u2019re not alone. A <code>lazyload<\/code> attribute is churning its way through the web-standards refinery as we speak. Granted, <code>lazyload<\/code> still has <a href=\"https:\/\/github.com\/whatwg\/html\/pull\/3752\">a long way to go before it\u2019s cast in concrete<\/a>, but you can try out an early version of <a href=\"https:\/\/docs.google.com\/document\/d\/1e8ZbVyUwgIkQMvJma3kKUDg8UUkLRRdANStqKuOIvHg\/edit#heading=h.fuqo94v1qejx\">the proposed behavior<\/a> by toggling the \u201cenable lazy image loading\u201d flag in Chrome Canary:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/wilto_lazy-image.jpg\" alt=\"Lazy Image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"473\"\/><\/p>\n<p>That browser flag applies the asynchronous loading approach to <em>all<\/em> images, which is a pattern the Chrome team has been experimenting with. Will that turn out to be somewhat aggressive in practice? That\u2019s hard to imagine but only time will tell.<\/p>\n<h3>Ask for forgiveness rather than permission for compression.<\/h3>\n<p>Let me paint a picture for you (no pun intended): You\u2019ve been trying to figure out the perfect level of lossy compression for the images on your site, i.e., a sensible default for  all uploaded images. For what feels like ages, you\u2019ve tinkered, uploaded, and reuploaded samples, and squinted at barely-visible compression artifacts. You\u2019ve finally, <em>finally<\/em>, figured out the perfect compromise between file size and image quality. Now that everything is perfect, increase the compression level and walk away. The thing is, you and I are lousy judges of image quality. We\u2019re too good at it.<\/p>\n<p>See, the magic of JPEG compression is that it was made to exploit flaws in <em>us<\/em>. We humans aren\u2019t great at processing high-frequency detail. We can recognize a tree, sure, and tell it apart from other trees; and even see a forest for those trees on a good day. But what we <em>can\u2019t<\/em> see\u2014or we do see, I suppose, but can\u2019t process very well\u2014are the positions of each of the leaves on the tree. At a quick glance, we don\u2019t capture the precise hue of each individual leaf in comparison to the one beside it, but we notice that some parts of the tree are darker than others. We can for sure <em>seek out<\/em> those high-frequency details by paying attention to them. However, in driving past a row of trees, we\u2019re not looking for each individual leaf in relation to those around them. It\u2019s too much information, none of which we really need in that context. To save mental bandwidth and keep the world from being any more overwhelming than it already is, our brains round down the images around us.<\/p>\n<p>JPEG compression works by discarding details that the audience isn\u2019t likely to notice anyway\u2014something that our brains are already doing with the world around us, all the time. For a photo of a tree, that might mean losing a little distinction between some of the leaves or a slightly-reduced color palette.<\/p>\n<p>You and I make particularly lousy accomplices in this trickery because we\u2019re in on the con. After all, we know what we\u2019re looking for when we choose a level of lossy compression, whether manually saving an image or choosing a \u201csensible default\u201d for a library of images. We see an artifact here and a tiny missing detail there. With the original right in front of us, we have a basis for comparison. Because we\u2019re looking for the individual leaves on the tree, so to speak, we can tell when they\u2019re a little out of place.<\/p>\n<p>Most users don\u2019t know the difference, though. They just see a tree, with no basis for careful comparison, and any faint artifacts blending in with the tiny details that their lossy psychovisual systems gloss over anyway. In fact, the odds are that, if we weren\u2019t looking for the details, we wouldn\u2019t notice them either even though we\u2019re wise to the trick JPEG tries to play on us.<\/p>\n<p>Don\u2019t believe me? Try this out: Tomorrow morning, take out a good old-fashioned pen and a piece of paper and set them aside. If, during the course of your daily web browsing, you notice an image with a high level of lossy compression, grab your pen and put a checkmark on the paper. At the end of the day, those marks will be few and far between.<\/p>\n<p>We designers and developers are poor judges of good lossy-compression levels because our eyes are too sharp. So, all told, it\u2019s almost always a safe bet to nudge JPEG compression a little higher than you think you can get away with. You might see an artifact or two when you\u2019re looking for them in the compression-options dialog, but if you weren\u2019t\u2014if you were the audience, that is\u2014you probably wouldn\u2019t see a thing.<\/p>\n<h3>Take credit for <em>not<\/em> writing code.<\/h3>\n<p>The RICG had a few goals, some shouted from the rooftops and some not. For example, the goal of finding efficient, preparser-friendly methods of tailoring image requests to browsing contexts was no secret. Paving a path for more designers and developers to become involved in the standards process\u2014we were pretty loud about that one, too. More subtle, however, was a goal many RICG members shared, me included: a day when we would hardly think about responsive images.<\/p>\n<p>It\u2019s no big secret that most responsive-image patterns are  <a href=\"https:\/\/dev.opera.com\/articles\/responsive-images\/\">information dense<\/a>. They are terse by necessity. Anything we might have done to make those syntaxes easier for us humans to parse could have made them more complex for a browser to parse. Adding complexity to a parser translates to more potential for bugs or for unintentional differences in behavior among browsers.<\/p>\n<p>But, as much as that density feels like a syntactical weakness when we\u2019re rooting through markups by hand, it\u2019s a strength in practice. Why? Because a syntax more easily read by machines is a syntax more easily written by them.<\/p>\n<p><code>srcset<\/code> and <code>sizes<\/code> have a remarkable amount of flexibility baked in. Together, they make up the markup pattern that solves the most common use case for responsive images: a big stretchy image in the strictest technical terms. In most cases, what we want from a responsive image is what we\u2019ve always wanted from any image in a responsive layout: one that stretches to fit a viewport of any size, the way an <code>img<\/code> element with a single, gigantic source would. We just want the image to be more performant.<\/p>\n<p><code>srcset<\/code> accords the browser a couple of potential sources. <code>sizes<\/code> passes along information on how to render the sources. Though they <em>seem<\/em> declarative, as most markups are, in practice, those attributes say, \u201cThese sources might be visually appropriate for these contexts,\u201cnot \u201cHere is the source to use in this specific context.\u201d The difference is slight in print but huge in implication: Nothing we include in <code>srcset<\/code> is a <em>command<\/em>, only a <em>candidate<\/em>. The spec itself leaves a step explicitly vague so that browsers can select any suitably-sized source based on any number of factors.<\/p>\n<p>When writing this syntax, we\u2019re really just setting the terms of the negotiations between a browser and a web server. Since it acts as a list of potential candidates, <code>srcset<\/code> enables browsers to introduce user settings like \u201cAlways give me low-res images\u201d\u2014something mobile Chrome\u2019s data-saver mode does today.  Browsers can make clever use of built-in caching. For example, if someone has already cached a large source, shrinking the browser viewport, Chrome and Firefox don\u2019t  request for smaller sources. After all, the greater serves the lesser. That practice even paves the way for future settings, such as \u201cGive me high-resolution images as bandwidth permits,\u201d with no input from us, which means no attributes to add, change, update or, in the worst-case scenario, accidentally omit.<\/p>\n<p>Again, those bandwidth-saving features require no development efforts. Ditto new advancements in the way images are requested and rendered. As soon as those two attributes are in place, we can walk away, mission accomplished.<\/p>\n<p>As a matter of fact, we don\u2019t necessarily have to do <em>that<\/em> much.<\/p>\n<p>The beauty of a syntax made to be easily read by machines is that it\u2019s a syntax more easily written by them. Most modern content management systems handle the basics of this markup right out of the box, omitting all the image sources, populating a <code>srcset<\/code> attribute with them, and generating an easily-customized <code>sizes<\/code> syntax to match. I can personally vouch for Cloudinary in this department, having handled a transition to it for a major publisher\u2019s responsive-image needs. Cloudinary generates all image sources and <code>srcset<\/code> values on the fly with no tinkering required. In addition, finely-tuned <code>sizes<\/code> attributes are generated by a <a href=\"https:\/\/github.com\/ausi\/respimagelint\">handy little bookmarklet<\/a>.<\/p>\n<p>Thus was the RICG\u2019s quietest goal finally fulfilled: hyper-optimized, responsive images through a markup that takes advantage of the latest\u2014and future\u2014browser features, sans manual additions of attributes. And, best of all, that same markup will benefit from countless new browser-level optimizations as time goes on, with no changes, no planning, and no extra programming efforts. As those new features roll out,  one thing will be certain: It all happened exactly the way you\u2019d planned it and you deserve credit for it.<\/p>\n<h3>Put the \u201cgood\u201d in \u201cchaotic good\u201d<\/h3>\n<p>How about stretching the rules somewhat to do the right thing? You\u2019d be in good company and are the sort of person who made the RICG a success. We\u2019re not flying in the face of convention just for kicks, and we\u2019re not neutral. Our methods might be a little \u201ccreative,\u201d but they are squarely focused on doing the right thing for those our work stands to affect the most\u2014the web audience who bears all the potential costs of our work. For their sake, I wouldn\u2019t mind getting myself into a <em>little<\/em> trouble but someone will have to catch me first.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":21845,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,227],"class_list":["post-21844","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-performance-optimization"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>A Guide to Website Image Optimization and Performance<\/title>\n<meta name=\"description\" content=\"Learn how to perform website image optimization through a markup that takes advantage of the latest and future browser features, sans manual additions of attributes.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Chaotic Good Guide to Image Performance, Part 2\" \/>\n<meta property=\"og:description\" content=\"Learn how to perform website image optimization through a markup that takes advantage of the latest and future browser features, sans manual additions of attributes.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-02-11T17:25:06+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-02-26T04:00:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1540\" \/>\n\t<meta property=\"og:image:height\" content=\"847\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"A Chaotic Good Guide to Image Performance, Part 2\",\"datePublished\":\"2019-02-11T17:25:06+00:00\",\"dateModified\":\"2022-02-26T04:00:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2\"},\"wordCount\":8,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Performance Optimization\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2019\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2\",\"url\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2\",\"name\":\"A Guide to Website Image Optimization and Performance\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA\",\"datePublished\":\"2019-02-11T17:25:06+00:00\",\"dateModified\":\"2022-02-26T04:00:15+00:00\",\"description\":\"Learn how to perform website image optimization through a markup that takes advantage of the latest and future browser features, sans manual additions of attributes.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA\",\"width\":1540,\"height\":847},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Chaotic Good Guide to Image Performance, Part 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"A Guide to Website Image Optimization and Performance","description":"Learn how to perform website image optimization through a markup that takes advantage of the latest and future browser features, sans manual additions of attributes.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2","og_locale":"en_US","og_type":"article","og_title":"A Chaotic Good Guide to Image Performance, Part 2","og_description":"Learn how to perform website image optimization through a markup that takes advantage of the latest and future browser features, sans manual additions of attributes.","og_url":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2","og_site_name":"Cloudinary Blog","article_published_time":"2019-02-11T17:25:06+00:00","article_modified_time":"2022-02-26T04:00:15+00:00","og_image":[{"width":1540,"height":847,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2"},"author":{"name":"","@id":""},"headline":"A Chaotic Good Guide to Image Performance, Part 2","datePublished":"2019-02-11T17:25:06+00:00","dateModified":"2022-02-26T04:00:15+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2"},"wordCount":8,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA","keywords":["Guest Post","Performance Optimization"],"inLanguage":"en-US","copyrightYear":"2019","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2","url":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2","name":"A Guide to Website Image Optimization and Performance","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA","datePublished":"2019-02-11T17:25:06+00:00","dateModified":"2022-02-26T04:00:15+00:00","description":"Learn how to perform website image optimization through a markup that takes advantage of the latest and future browser features, sans manual additions of attributes.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA","width":1540,"height":847},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/a_chaotic_good_guide_to_image_performance_part_2#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"A Chaotic Good Guide to Image Performance, Part 2"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721501\/Web_Assets\/blog\/Chaotic-Good-Image-Performance-Guide-Part-2\/Chaotic-Good-Image-Performance-Guide-Part-2.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21844","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=21844"}],"version-history":[{"count":5,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21844\/revisions"}],"predecessor-version":[{"id":23077,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21844\/revisions\/23077"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/21845"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=21844"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=21844"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=21844"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}