{"id":31737,"date":"2023-11-06T15:00:00","date_gmt":"2023-11-06T22:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=31737"},"modified":"2025-01-23T18:18:57","modified_gmt":"2025-01-24T02:18:57","slug":"boost-svelte-performance-optimized-images","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images","title":{"rendered":"Boost Svelte Performance With Optimized Images"},"content":{"rendered":"\n<p>Serving optimized images is a vital part of building a performant website. If we serve our users images that are unnecessarily large, we waste their bandwidth and time. We also increase our own costs, since serving enormous images isn\u2019t cheap!<\/p>\n\n\n\n<p>For the median webpage, 40% of the <a href=\"https:\/\/httparchive.org\/reports\/page-weight\">page weight<\/a> is made up of images. Optimizing how we serve our images can have a big impact on our website\u2019s load time and performance.&nbsp;<\/p>\n\n\n\n<p>If you\u2019re using Svelte, you don\u2019t have a built-in way to optimize images. Cloudinary\u2019s svelte-cloudinary package is a great way to start serving optimized images quickly \u2014 let\u2019s dive in.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The CldImage Component<\/h2>\n\n\n\n<p>Normally, you interact with Cloudinary by uploading images and requesting them via certain URL formats. The CldImage component abstracts the URL construction part away from you, so that you can interact with Cloudinary through passing props to a component instead.<\/p>\n\n\n\n<p>Here\u2019s what that might look like:<\/p>\n\n\n<pre class=\"wp-block-code\" 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\">```svelte\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span>\n\n<span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">{840}<\/span>\n\n<span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{700}<\/span>\n\n<span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"orange-cat\"<\/span>\n\n<span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"An orange cat with its head leaning to one side, looking quizzically at the camera\"<\/span>\n\n\/&gt;<\/span>\n\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\n\n<p>You provide the component with the width and height of the images and the ID in Cloudinary, and you\u2019ll get back an optimized image matching the specifications. Some of the optimizations Cloudinary applies include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Resizing and compressing the image from its original size, so that it looks good at the specified dimensions while minimizing the file size.<\/li>\n\n\n\n<li>Converting the image to a modern format (like <a href=\"https:\/\/cloudinary.com\/tools\/compress-avif\">AVIF<\/a> or WebP) that can reduce the file size further. Cloudinary will serve different formats depending on the browser, since image format support can vary.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>In addition, these optimizations happen <em>at request time<\/em> so you don\u2019t have to slow down your build to process images.<\/p>\n\n\n\n<p>There are many other ways Cloudinary can transform your images, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/cloudinary.com\/blog\/introducing_smart_cropping_intelligent_quality_selection_and_automated_responsive_images\">Dynamic cropping<\/a>.<\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/blog\/how_to_automatically_and_professionally_remove_photo_backgrounds\">Background removal<\/a>.<\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/blog\/generative-fill-ai-powered-outpainting\" target=\"_blank\" rel=\"noreferrer noopener\">Generative fill<\/a> with AI.<\/li>\n\n\n\n<li>Overlaying text or other images.<\/li>\n\n\n\n<li><a href=\"https:\/\/svelte.cloudinary.dev\/cldimage\/examples\/\">And more!<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Tutorial<\/h2>\n\n\n\n<p>Let\u2019s see how to use this in a Svelte project. We\u2019ll build a card displaying an animal that\u2019s up for adoption.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/Wwf9Gbrdt1aAyJIrAKMwL6KW-BE-Ym0539CXqlY8gLgw3PseUkJhfVBkRCfPAqPt-cdUOMbRCdt5FgnWbqkx6cBqLTp6jWDfDw08trE7MpNS-BD60C63ufrxmN9Nzd9fHDt7gQKC3MJZGYaJWc02XjM\" alt=\"\"\/><\/figure>\n\n\n\n<p>First, you\u2019ll need an image to work with. I downloaded this <a href=\"https:\/\/unsplash.com\/photos\/75715CVEJhI\" target=\"_blank\" rel=\"noreferrer noopener\">image of an orange cat<\/a> from Unsplash, but feel free to bring your own image if you want. Take note of how large the image you downloaded is \u2014 mine was 8MB! With Cloudinary\u2019s APIs, we\u2019ll be able to serve a much smaller, more optimized image: it will be resized, compressed, and in a modern image format. This will also reduce our total page weight, which means the page will load faster and use less of our users\u2019 bandwidth.<\/p>\n\n\n\n<p>Once you have your image, upload it to your Media Library in the <a href=\"https:\/\/console.cloudinary.com\">Cloudinary Console<\/a> and get the Public ID of the item.<\/p>\n\n\n\n<p>Now we can set up our Svelte project. Scaffold a new project by running <code>npm create svelte@latest<\/code> in a terminal. Choose the \u201cSkeleton project\u201d app template, and whatever you like from the other options. They shouldn\u2019t matter much for this demo.<\/p>\n\n\n\n<p>To set up <code>svelte-cloudinary<\/code>, install the library with:<\/p>\n\n\n\n<p><code>npm install svelte-cloudinary<\/code><\/p>\n\n\n\n<p>Create a <code>.env<\/code> file in the root of your project and add your <a href=\"https:\/\/www.youtube.com\/watch?v=1SIp9VL5TMo\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary cloud name<\/a>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">```\n\nVITE_PUBLIC_CLOUDINARY_CLOUD_NAME=\"CLOUD_NAME_GOES_HERE\"\n\n```\n\nThat should be all you need to start using the component. Let\u2019s try it out \u2013 replace the contents of\u00a0 `src\/routes\/+page.svelte` with the Cloudinary image component.\n\n```svelte\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"javascript\">\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">import<\/span> { CldImage } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'svelte-cloudinary'<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> src = <span class=\"hljs-string\">'orange-cat'<\/span>;\u00a0\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> alt = <span class=\"hljs-string\">'An orange cat with its head leaning to one side, looking quizzically at the camera'<\/span>;\n\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">{840}<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{700}<\/span> {<span class=\"hljs-attr\">src<\/span>} {<span class=\"hljs-attr\">alt<\/span>} \/&gt;<\/span>\n\n```<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><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\n\n<p>We&#8217;ll pass the following props to the <code>CldImage<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>width<\/code> and <code>height<\/code> are the width and height of the image. This doesn\u2019t have to be the same as the width and height of the image you uploaded. Cloudinary will automatically resize the image to match the dimensions you request.<\/li>\n\n\n\n<li><code>src<\/code> is the Cloudinary Public ID of the image you uploaded at the beginning.<\/li>\n\n\n\n<li><code>alt<\/code> is a description of the image. This will be used to describe the image when users browse with assistive technology like a screen reader, or if the image fails to load.<\/li>\n<\/ul>\n\n\n\n<p>Run the dev server with <code>npm run dev<\/code> and navigate to the site. You should see the image on the page. Take a look at the network tab to see how big the image is now after being optimized by Cloudinary. Mine went from 8MB to 34KB \u2014 less than 1% of the size of the original image! While some of this decrease was accomplished by resizing and compressing the image, Cloudinary also converts the image to a more efficient file format like .avif to increase the cost savings even further.<\/p>\n\n\n\n<p>If you take a peek at the HTML generated by the component, you\u2019ll notice some additional attributes were added to make the image more performant by default.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code><strong>loading=\u201dlazy\u201d<\/strong><\/code>. This delay loading the image until it is in the user\u2019s viewport (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/HTMLImageElement\/loading\">MDN<\/a>).<\/li>\n\n\n\n<li><code><strong>decoding=\u201dasync\u201d<\/strong><\/code>. If the image data takes a long time to decode, the browser will display the rest of the page content right away instead of waiting for decoding to finish (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/HTMLImageElement\/decoding\">MDN<\/a>).<\/li>\n<\/ul>\n\n\n\n<p>Let\u2019s take the image component a bit further. To display the image in a responsive card with some text added, you can add the following styles and markup.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">```svelte\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"javascript\">\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">import<\/span> { CldImage } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'svelte-cloudinary'<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> src = <span class=\"hljs-string\">'orange-cat'<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> alt = <span class=\"hljs-string\">'An orange cat with its head leaning to one side, looking quizzically at the camera'<\/span>;\n\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"card\"<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">{840}<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{700}<\/span> {<span class=\"hljs-attr\">src<\/span>} {<span class=\"hljs-attr\">alt<\/span>} <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"big-image\"<\/span> \/&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"content\"<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"title\"<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">{200}<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{200}<\/span> {<span class=\"hljs-attr\">src<\/span>} {<span class=\"hljs-attr\">alt<\/span>} <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"small-image\"<\/span> <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">\"thumb\"<\/span> \/&gt;<\/span>\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Sunny<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><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\n\n<p>Meet our charming orange tabby cat! This delightful feline, with its vibrant orange coat and captivating eyes, is sure to steal your heart. Known for its playful and affectionate nature, this cat is the perfect companion for both families and individuals. Whether it&#8217;s curling up on your lap for a cozy evening or entertaining you with its playful antics, this cat is full of personality. We&#8217;ve affectionately nicknamed them &#8220;Sunny,&#8221; but you can choose from a range of names like &#8220;Amber,&#8221; &#8220;Marmalade,&#8221; or &#8220;Leo&#8221; to suit their sunny disposition. Don&#8217;t miss out on the chance to bring a ray of sunshine into your life \u2013 adopt this orange beauty today!<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" 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\">p<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">style<\/span>&gt;<\/span><span class=\"css\">\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-selector-class\">.card<\/span> {\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">font-family<\/span>: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans,\n\n\u00a0\u00a0\u00a0 sans-serif;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">display<\/span>: grid;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">grid-template-columns<\/span>: <span class=\"hljs-number\">1<\/span>fr;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">border<\/span>: <span class=\"hljs-number\">1px<\/span> solid lightgrey;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">overflow<\/span>: hidden;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">max-width<\/span>: <span class=\"hljs-number\">800px<\/span>;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span> auto;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">align-items<\/span>: center;\n\n\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-selector-class\">.content<\/span> {\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">line-height<\/span>: <span class=\"hljs-number\">1.4<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-selector-class\">.card<\/span> <span class=\"hljs-selector-pseudo\">:global(.big-image)<\/span> {\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">display<\/span>: none;\n\n\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-selector-class\">.card<\/span> <span class=\"hljs-selector-pseudo\">:global(.small-image)<\/span> {\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">100%<\/span>;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">flex-basis<\/span>: <span class=\"hljs-number\">125px<\/span>;\n\n\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-selector-class\">.title<\/span> {\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">display<\/span>: flex;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">gap<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">align-items<\/span>: center;\n\n\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">@media<\/span> (<span class=\"hljs-attribute\">min-width:<\/span> <span class=\"hljs-number\">600px<\/span>) {\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-selector-class\">.card<\/span> {\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">grid-template-columns<\/span>: <span class=\"hljs-number\">300px<\/span> <span class=\"hljs-number\">1<\/span>fr;\n\n\u00a0\u00a0\u00a0 }\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-selector-class\">.card<\/span> <span class=\"hljs-selector-pseudo\">:global(.big-image)<\/span> {\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">display<\/span>: block;\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">align-self<\/span>: stretch;\n\n\u00a0\u00a0\u00a0 }\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-selector-class\">.card<\/span> <span class=\"hljs-selector-pseudo\">:global(.small-image)<\/span> {\n\n\u00a0\u00a0\u00a0 <span class=\"hljs-attribute\">display<\/span>: none;\n\n\u00a0\u00a0\u00a0 }\n\n\u00a0\u00a0\u00a0\u00a0}\n\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">style<\/span>&gt;<\/span>\n\n```<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><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\n\n<p>To target the underlying <code>&lt;img&gt;<\/code> rendered by the <code>CldImage<\/code> component, we pass a <code>class<\/code> as a prop to the component. Since the <code>&lt;img class=\u201dbig-image\u201d&gt;<\/code> is outside of the component we\u2019re writing our styles in, we need to use <code>:global(.big-image)<\/code> modifier to style it from inside <a href=\"https:\/\/svelte.dev\/docs\/svelte-components#style\" target=\"_blank\" rel=\"noreferrer noopener\">Svelte\u2019s <code>&lt;style&gt;<\/code> block<\/a>. If you like, you can also style the <code>CldImage<\/code> with inline styles via the <code>style<\/code> prop.<\/p>\n\n\n\n<p>In this version, we\u2019re including two <code>CldImage<\/code> components. Only one will be shown at a time, depending on the device\u2019s screen size. The first is the same as the image component we started with, and it will show on screens 600px and up. Here\u2019s what the card looks like at larger screen widths.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/Wwf9Gbrdt1aAyJIrAKMwL6KW-BE-Ym0539CXqlY8gLgw3PseUkJhfVBkRCfPAqPt-cdUOMbRCdt5FgnWbqkx6cBqLTp6jWDfDw08trE7MpNS-BD60C63ufrxmN9Nzd9fHDt7gQKC3MJZGYaJWc02XjM\" alt=\"\"\/><\/figure>\n\n\n\n<p>The second is a \u201cthumbnail\u201d version that we display for small screens. With these parameters, Cloudinary will generate a second optimized image that is 200&#215;200 and ~6KB. By default, Cloudinary will intelligently crop the image so the important part of the image is still in view. You can read more about Cloudinary\u2019s extensive resizing and cropping options <a href=\"https:\/\/cloudinary.com\/documentation\/resizing_and_cropping\" target=\"_blank\" rel=\"noreferrer noopener\">in the documentation<\/a>.<\/p>\n\n\n\n<p>It\u2019s worth highlighting that both versions of the image use the same source. We don\u2019t have to manage two images \u2013 we only upload a single source image and Cloudinary transforms it based on our request.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/DAf7d8JMSJvUW_YecMCHSw77Wuyf8l0HU-CtEWcjc9MOzpDcrhzW1Ep__HSUOhjVccYO2YWGowO2gX3_dAhXfRkFyk-XiqnOX78g28lxa_zdT8g0vw1MhYttQC7AwPpAfJDRM-X5BhLtm_OQMYPvfcQ\" alt=\"\"\/><\/figure>\n\n\n\n<p>You can find the completed demo code <a href=\"https:\/\/github.com\/geoffrich\/svelte-cloudinary-demo\" target=\"_blank\" rel=\"noreferrer noopener\">on GitHub<\/a> and view the <a href=\"https:\/\/svelte-cloudinary-demo.vercel.app\/\" target=\"_blank\" rel=\"noreferrer noopener\">live version<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Where to Go From Here<\/h2>\n\n\n\n<p>This only scratched the surface of the possibilities with the Cloudinary Image component \u2013 see the <a href=\"https:\/\/svelte.cloudinary.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">documentation<\/a> for more and <a href=\"https:\/\/cloudinary.com\/users\/register_free\">sign up<\/a> for a free account today.<\/p>\n\n\n\n<p>In addition to <code>CldImage<\/code>, Svelte Cloudinary includes several other components you can use in your Svelte app:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A <code>CldOgImage<\/code> component to generate social card images.<\/li>\n\n\n\n<li><code>CldUploadButton<\/code> and <code>CldUploadWidget<\/code> components to easily upload media to Cloudinary.<\/li>\n\n\n\n<li>A <code>CldVideoPlayer<\/code> component to embed Cloudinary videos.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Serving optimized images is a vital part of building a performant website. If we serve our users images that are unnecessarily large, we waste their bandwidth and time. We also increase our own costs, since serving enormous images isn\u2019t cheap! For the median webpage, 40% of the page weight is made up of images. Optimizing [&hellip;]<\/p>\n","protected":false},"author":87,"featured_media":31738,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,370,388,376],"class_list":["post-31737","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-optimize","tag-svelte"],"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>Boost Svelte Performance With Optimized Images<\/title>\n<meta name=\"description\" content=\"Serving optimized images is a vital part of building a performant website. If we serve our users images that are unnecessarily large, we waste their\" \/>\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\/boost-svelte-performance-optimized-images\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Boost Svelte Performance With Optimized Images\" \/>\n<meta property=\"og:description\" content=\"Serving optimized images is a vital part of building a performant website. If we serve our users images that are unnecessarily large, we waste their\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-11-06T22:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-01-24T02:18:57+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"melindapham\" \/>\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\/boost-svelte-performance-optimized-images#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"Boost Svelte Performance With Optimized Images\",\"datePublished\":\"2023-11-06T22:00:00+00:00\",\"dateModified\":\"2025-01-24T02:18:57+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images\"},\"wordCount\":1185,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"Optimize\",\"Svelte\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2023\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images\",\"url\":\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images\",\"name\":\"Boost Svelte Performance With Optimized Images\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog.jpg?_i=AA\",\"datePublished\":\"2023-11-06T22:00:00+00:00\",\"dateModified\":\"2025-01-24T02:18:57+00:00\",\"description\":\"Serving optimized images is a vital part of building a performant website. If we serve our users images that are unnecessarily large, we waste their\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Boost Svelte Performance With Optimized Images\"}]},{\"@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\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\",\"name\":\"melindapham\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"caption\":\"melindapham\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Boost Svelte Performance With Optimized Images","description":"Serving optimized images is a vital part of building a performant website. If we serve our users images that are unnecessarily large, we waste their","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\/boost-svelte-performance-optimized-images","og_locale":"en_US","og_type":"article","og_title":"Boost Svelte Performance With Optimized Images","og_description":"Serving optimized images is a vital part of building a performant website. If we serve our users images that are unnecessarily large, we waste their","og_url":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images","og_site_name":"Cloudinary Blog","article_published_time":"2023-11-06T22:00:00+00:00","article_modified_time":"2025-01-24T02:18:57+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog-jpg?_i=AA","type":"image\/jpeg"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"Boost Svelte Performance With Optimized Images","datePublished":"2023-11-06T22:00:00+00:00","dateModified":"2025-01-24T02:18:57+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images"},"wordCount":1185,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog.jpg?_i=AA","keywords":["Guest Post","Image","Optimize","Svelte"],"inLanguage":"en-US","copyrightYear":"2023","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images","url":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images","name":"Boost Svelte Performance With Optimized Images","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog.jpg?_i=AA","datePublished":"2023-11-06T22:00:00+00:00","dateModified":"2025-01-24T02:18:57+00:00","description":"Serving optimized images is a vital part of building a performant website. If we serve our users images that are unnecessarily large, we waste their","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/boost-svelte-performance-optimized-images#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Boost Svelte Performance With Optimized Images"}]},{"@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":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9","name":"melindapham","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","caption":"melindapham"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1699291206\/Svelte_Performance_Optimized_Images-Blog\/Svelte_Performance_Optimized_Images-Blog.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/31737","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\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=31737"}],"version-history":[{"count":7,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/31737\/revisions"}],"predecessor-version":[{"id":36608,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/31737\/revisions\/36608"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/31738"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=31737"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=31737"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=31737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}