<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Piotr Grzywa</title>
    <description>The latest articles on Forem by Piotr Grzywa (@piotrgrzywa).</description>
    <link>https://forem.com/piotrgrzywa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F800323%2Fb068f76e-f535-4d94-a784-6298b104af55.jpg</url>
      <title>Forem: Piotr Grzywa</title>
      <link>https://forem.com/piotrgrzywa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/piotrgrzywa"/>
    <language>en</language>
    <item>
      <title>Why it's always worth to optimize website performance</title>
      <dc:creator>Piotr Grzywa</dc:creator>
      <pubDate>Wed, 21 Jun 2023 20:26:12 +0000</pubDate>
      <link>https://forem.com/piotrgrzywa/why-its-always-worth-to-optimize-website-performance-3blm</link>
      <guid>https://forem.com/piotrgrzywa/why-its-always-worth-to-optimize-website-performance-3blm</guid>
      <description>&lt;p&gt;On one of &lt;a href="https://crossweb.pl/en/event-series/meet-js/"&gt;meet.js Katowice (Poland)&lt;/a&gt; we had an interesting conversation about performance. &lt;/p&gt;

&lt;p&gt;One of the participants asked: &lt;br&gt;
&lt;strong&gt;"Should we always optimize the web performance of our websites?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;He stands for: not always, it depends on your target audience, their internet connection, and the devices that they use.&lt;br&gt;
If you are sure that your Customers/Visitors are eg. IT guys that always will go to your website from MacBook Pro with an extra super-fast fiber optic internet connection, you don't need to.&lt;/p&gt;

&lt;p&gt;As I can partially agree with this, there is always but :) &lt;/p&gt;

&lt;p&gt;Let's start with, why I can agree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6xx1uohp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xroqevdq34wroahaw741.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6xx1uohp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xroqevdq34wroahaw741.gif" alt="Agree GIF" width="480" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Optimizing web performance (especially &lt;a href="https://web.dev/optimize-long-tasks/"&gt;js long task&lt;/a&gt;, &lt;a href="https://web.dev/ttfb/"&gt;TTFB&lt;/a&gt;, &lt;a href="https://web.dev/fid/"&gt;FID&lt;/a&gt;, &lt;a href="https://web.dev/inp/"&gt;INP&lt;/a&gt;) can be tricky, that means it's also expensive, often you need to dig very deep into your application, exchange some libraries, rewrite functions, or even change framework you use. &lt;/p&gt;

&lt;p&gt;Sometimes business could not agree on spending time, resources, and money on optimizing things that will not bring profits (we are considering the situation from the example above, our target audience use fast internet + high-end devices and for this target, our website is loading super fast).&lt;/p&gt;

&lt;p&gt;But ...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IqZwyGzC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpsqu1he06oz0komflj5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IqZwyGzC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpsqu1he06oz0komflj5.gif" alt="But GIF" width="400" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even in this case, we should care about stuff that is relatively easy to optimize, eg. don't load big images/movies or don't fetch unnecessary data (if you need 2 items from API and inside you need only 2 properties, don't fetch 100 items with all 300 properties that you will never use).&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cost optimization&lt;br&gt;
As a company we are always happy when we can save some money, making our resources smaller will help us reduce the cost of storage. Also when we are using SSR (Server Side Rendering) js long tasks and memory leaks can lead to high memory and CPU consumption on the node server that is responsible for rendering our website and this also can generate high costs (especially if need to deal with a lot of traffic). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ecology&lt;br&gt;
Every KB of data sent over the internet, each ms of CPU time, hosting all those not optimized images, etc., all this uses energy and affects the climate of our planet.&lt;br&gt;
You can check your website carbon footprint on WebPageTest website, more info can be found on their &lt;a href="https://blog.webpagetest.org/posts/carbon-control/"&gt;blog&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o0Wg3dx2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hv5wh4unroglfusf1ajx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o0Wg3dx2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hv5wh4unroglfusf1ajx.png" alt="Web Page Test Carbon Control" width="800" height="189"&gt;&lt;/a&gt; or on &lt;a href="https://www.websitecarbon.com/"&gt;https://www.websitecarbon.com/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Good practices &lt;br&gt;
It's always good to do things "in the right way", if you will learn web performance good practices, in your next project (or company) this could be a key to success. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let me know in the comments what is your opinion on this subject, always optimize, or maybe not?&lt;/p&gt;

</description>
      <category>webperf</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Optimizing images with nuxt-image, StorefrontUI, and Vue Storefront</title>
      <dc:creator>Piotr Grzywa</dc:creator>
      <pubDate>Tue, 22 Mar 2022 08:52:04 +0000</pubDate>
      <link>https://forem.com/vue-storefront/optimizing-images-with-nuxt-image-storefrontui-and-vue-storefront-1h1d</link>
      <guid>https://forem.com/vue-storefront/optimizing-images-with-nuxt-image-storefrontui-and-vue-storefront-1h1d</guid>
      <description>&lt;h2&gt;
  
  
  Why you should optimize images?
&lt;/h2&gt;

&lt;p&gt;Image optimization is very important for web performance. You need to have optimized images - small, compressed and served in modern formats to have a fast website.&lt;/p&gt;

&lt;p&gt;It also directly impacts your server/cloud transfer size - if you have bigger images, it generates higher costs.&lt;/p&gt;

&lt;p&gt;For an eCommerce website, often it’s hard to achieve proper image optimization easily.&lt;/p&gt;

&lt;p&gt;If you have only static images, you can compress them by yourself and upload to the server, but when you have dynamic ones (e.g. from CMS or eCommerce backend) you are limited to what your integration is capable of.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is nuxt-image?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;“Nuxt-image is a plug-and-play image optimization for Nuxt apps.&lt;br&gt;
You can easily resize and transform your images in your code using built-in optimizer or your favorite images CDN.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With nuxt-image you can compress, resize and crop images on the fly, which means even if your CMS or eCommerce backend serves big images, user will still get an optimized version.&lt;/p&gt;

&lt;p&gt;And all this is done automatically!&lt;/p&gt;

&lt;p&gt;This process looks something like this:&lt;br&gt;
User loads the product page, there is product_image_1.jpg (that has 2Mb), nuxt-image sends this image to the chosen provider and converts it on the fly with given configuration.&lt;/p&gt;

&lt;p&gt;Provider generates proper image (eg product_image_1.webp (60 Kb)) and serves it back to the User. So users don’t get the original image but the optimized one.&lt;/p&gt;

&lt;p&gt;Converting a 2Mb image to 60Kb webp can be time and resource-consuming, but only for the first time, every next user requesting the same image gets it from the cache.&lt;/p&gt;

&lt;p&gt;Nuxt-image handles many providers, but for this tutorial, we will go with Cloudinary.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Cloudinary
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Developers and marketers use Cloudinary to quickly and easily create, manage and deliver their digital experiences across any browser, device, and bandwidth.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We will use &lt;a href="https://cloudinary.com/products/programmable_media" rel="noopener noreferrer"&gt;Programmable Media&lt;/a&gt; in this tutorial because it’s easiest to set up.&lt;/p&gt;

&lt;p&gt;For test purposes we will create &lt;a href="https://cloudinary.com/pricing" rel="noopener noreferrer"&gt;free Cloudinary account&lt;/a&gt; that is limited to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;25K transformations or&lt;/li&gt;
&lt;li&gt;25 GB of managed storage&lt;/li&gt;
&lt;li&gt;25 GB of net viewing bandwidth&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Using Cloudinary with VSUI, Vue Storefront and nuxt-image
&lt;/h2&gt;

&lt;p&gt;Before we start using Cloudinary with our project, we have to do one more step (apart from creating an account), set up an “Allowed fetch domain” that matches your website address.&lt;br&gt;
Log in to Cloudinary with your credentials, go to settings and find “Allowed fetch domains.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp59p4xxsi6hxckw4yesc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp59p4xxsi6hxckw4yesc.png" alt="Cloudinary configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter your domain names and click save.&lt;/p&gt;

&lt;p&gt;We are using the Cloudinary fetch option for this tutorial, as it’s the easiest one to configure.&lt;/p&gt;

&lt;p&gt;More information about the fetch method can be found &lt;a href="https://cloudinary.com/documentation/fetch_remote_images#remote_image_fetch_url" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Now we can start to code
&lt;/h2&gt;

&lt;p&gt;First, you need to install nuxt-image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add --dev @nuxt/image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, configure it in nuxt.config.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;modules: [
    '@nuxt/image',
    …
],
image: {
    // Using the default provider, you can also optimize external URLs. 
    // For this, you need to add them to the domains option.
    domains: ['https://exteranl-domain-from-where-we-get-our-images.com'],

    // here we are configuring our provider
    provider: 'cloudinary',

    // here we provide configuration specific to selected provider
    cloudinary: {
        baseURL: 'https://res.cloudinary.com/&amp;lt;your-cloud-name&amp;gt;/image/fetch/'
    }
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We set up Cloudinary, but of course, you can use any other &lt;a href="https://image.nuxtjs.org/providers/cloudinary/" rel="noopener noreferrer"&gt;supported provider&lt;/a&gt; or even create &lt;a href="https://image.nuxtjs.org/advanced/custom-provider/" rel="noopener noreferrer"&gt;your own integration&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can use it in the standard way (it’s described very well in the official &lt;a href="https://image.nuxtjs.org/getting-started/" rel="noopener noreferrer"&gt;nuxt-image documentation&lt;/a&gt;) using &lt;a href="https://image.nuxtjs.org/components/nuxt-img/" rel="noopener noreferrer"&gt;&lt;/a&gt;, &lt;a href="https://image.nuxtjs.org/components/nuxt-picture/" rel="noopener noreferrer"&gt;&lt;/a&gt; or with our SFUI components.&lt;/p&gt;

&lt;p&gt;If you want to use nuxt-image with SFUI you need to migrate to &lt;a href="https://docs.storefrontui.io/?path=/story/releases-v0-12-x-latest-v0-12-0-change-log--page" rel="noopener noreferrer"&gt;version 0.12.0&lt;/a&gt; (&lt;a href="https://docs.storefrontui.io/?path=/docs/releases-v0-12-x-v0-12-0-migration-guide--page" rel="noopener noreferrer"&gt;here you can find information on how to do it&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;There is also an option to directly use a generated image URL with applied transformations.&lt;br&gt;
Information on how to do it can be found in &lt;a href="https://image.nuxtjs.org/api/$img/#usage" rel="noopener noreferrer"&gt;nux-image docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  SFUI with nuxt-image
&lt;/h2&gt;

&lt;p&gt;One of our base components that works with nuxt-image is &lt;/p&gt;

&lt;p&gt;In order to use optimization, you need to add image-tag property with chosen value - ”nuxt-img” or “nuxt-picture”.  To specify output image use nuxtImgConfig object like in the example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;SfImage
  src="static/my-image.jpg"
  image-tag="nuxt-img"
  :nuxtImgConfig="{
    format: 'webp',
    fit: 'fill',
    provider: 'cloudinary'
  }"
  alt="Our test image"
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can configure &lt;a href="https://image.nuxtjs.org/components/nuxt-img/#format" rel="noopener noreferrer"&gt;format to which image will be converted&lt;/a&gt;, &lt;a href="https://image.nuxtjs.org/components/nuxt-img/#fit" rel="noopener noreferrer"&gt;fit type&lt;/a&gt;, &lt;a href="https://image.nuxtjs.org/components/nuxt-img/#provider" rel="noopener noreferrer"&gt;provider&lt;/a&gt; and other options specified in nuxt-image documentation such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://image.nuxtjs.org/components/nuxt-img/#quality" rel="noopener noreferrer"&gt;quality&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://image.nuxtjs.org/components/nuxt-img/#preset" rel="noopener noreferrer"&gt;preset&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://image.nuxtjs.org/components/nuxt-img/#sizes" rel="noopener noreferrer"&gt;sizes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://image.nuxtjs.org/components/nuxt-img/#width--height" rel="noopener noreferrer"&gt;width/height&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;..or additional ones allowed by the provider which can be passed in modifiers property also in nuxtImgConfig. &lt;/p&gt;

&lt;h2&gt;
  
  
  And that’s it !
&lt;/h2&gt;

&lt;p&gt;Images will be optimized automatically and served from cache.&lt;/p&gt;

&lt;p&gt;List of SFUI components that work with nuxt-img can be found in &lt;a href="https://docs.storefrontui.io/?path=/docs/releases-v0-12-x-v0-12-0-migration-guide--page" rel="noopener noreferrer"&gt;our migration guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can find more information about working with nuxt-image and Cloudinary in &lt;a href="https://image.nuxtjs.org/providers/cloudinary/" rel="noopener noreferrer"&gt;nuxt-image official documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webperf</category>
      <category>cloudinary</category>
      <category>nuxt</category>
      <category>vuestorefront</category>
    </item>
  </channel>
</rss>
