<?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>DEV Community: Silvestar Bistrović</title>
    <description>The latest articles on DEV Community by Silvestar Bistrović (@starbist).</description>
    <link>https://dev.to/starbist</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%2F30254%2Febd4adb3-eaeb-48a5-963b-ac1e528af02c.jpg</url>
      <title>DEV Community: Silvestar Bistrović</title>
      <link>https://dev.to/starbist</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/starbist"/>
    <language>en</language>
    <item>
      <title>Clamp it! VS Code extension</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Wed, 09 Oct 2024 12:14:00 +0000</pubDate>
      <link>https://dev.to/starbist/clamp-it-vs-code-extension-2h03</link>
      <guid>https://dev.to/starbist/clamp-it-vs-code-extension-2h03</guid>
      <description>&lt;p&gt;Today I published &lt;a href="https://marketplace.visualstudio.com/items?itemName=starbist.clamp-it" rel="noopener noreferrer"&gt;my first VS Code extension - Clamp it&lt;/a&gt;! This extension makes it easy to generate the clamped sizes for your CSS code.&lt;/p&gt;

&lt;p&gt;I made it because wanted to be more productive. My current process included going to an online clamp generator website, entering desired sizes, and then copy-paste it into my code.&lt;/p&gt;

&lt;p&gt;I made it with help from ChatGPT. 90% of the code is produced by ChatGPT. I had to tweak some things, and I came up with the idea, so I guess I deserve some credit.&lt;/p&gt;

&lt;p&gt;To start using it, first configure it by setting the following options in the global  &lt;code&gt;settings.json&lt;/code&gt; file  (Command palette: Preferences: Open User Settings  (JSON)) or your project  &lt;code&gt;settings.json&lt;/code&gt; file  (Command palette: Preferences: Open Workspace Settings  (JSON)):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"clampExtension.globalMinViewport"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"clampExtension.globalMaxViewport"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1440&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"clampExtension.baseFontSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, type minimum and maximum sizes  (in pixels), highlight the typed sizes, and then choose Clamp it! command from command palette:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fdo1arjk2tz161jhc4zkt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fdo1arjk2tz161jhc4zkt.gif" alt=" " width="760" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want, you can use the full definition, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;16, 20, 16, 600, 1200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the first parameter is the minimum size,&lt;/li&gt;
&lt;li&gt;the second parameter is the maximum size,&lt;/li&gt;
&lt;li&gt;the third parameter is the base font size,&lt;/li&gt;
&lt;li&gt;the fourth parameter is the minimum viewport size, and&lt;/li&gt;
&lt;li&gt;the fifth parameter is the maximum viewport size.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that the output is always in REM units:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;clamp&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;821&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;476&lt;/span&gt;&lt;span class="nt"&gt;vw&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;25&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! I hope this little extension will make you more productive as it made me.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>productivity</category>
      <category>css</category>
    </item>
    <item>
      <title>Fetch, process, output, style, listen</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Tue, 08 Oct 2024 10:12:00 +0000</pubDate>
      <link>https://dev.to/starbist/zero-accessibility-errors-5al</link>
      <guid>https://dev.to/starbist/zero-accessibility-errors-5al</guid>
      <description>&lt;p&gt;In a sea of various possibilities for how to build a website, here’s my preferred way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetch
&lt;/h2&gt;

&lt;p&gt;Since forever, there have been systems for managing content where users manage their content. It doesn’t matter if it is a cloud, a database, or a file. The data is stored somewhere, and we need to fetch it somehow. In most cases of static sites, it makes sense to fetch the data and let the website framework consume it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Process
&lt;/h2&gt;

&lt;p&gt;Sometimes, the fetched data isn’t in the most desirable format. It makes sense to apply some transformations to the data to display it most efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;

&lt;p&gt;The prepared data then needs to be displayed. Choosing a templating language is often a way to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Style
&lt;/h2&gt;

&lt;p&gt;Once the data is on the screen, it is time to style it. Choose what you’re most comfortable with, but consider maintainability and scalability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Listen
&lt;/h2&gt;

&lt;p&gt;Finally, adding scripts that respond to users’ actions enables users to interact with the site.&lt;/p&gt;

&lt;h2&gt;
  
  
  My favorites in 2024
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Contentful for storing the data&lt;/li&gt;
&lt;li&gt;Eleventy to fetch and process the data&lt;/li&gt;
&lt;li&gt;LiquidJS for templating&lt;/li&gt;
&lt;li&gt;Vanilla CSS for styling&lt;/li&gt;
&lt;li&gt;Vanilla JS for interactivity&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You can go far with simple solutions. Don’t overcomplicate, use proven solutions, and think long-term.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Reset with CSS unset</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Mon, 07 Oct 2024 08:10:00 +0000</pubDate>
      <link>https://dev.to/starbist/reset-with-css-unset-2970</link>
      <guid>https://dev.to/starbist/reset-with-css-unset-2970</guid>
      <description>&lt;p&gt;Over the past couple of years, I have frequently utilized the &lt;code&gt;unset&lt;/code&gt; keyword to reset the CSS properties. I noticed I'm using it intuitively to reset a property. But what is intuitive for me might not be intuitive for you. Let me clarify.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unsetting
&lt;/h3&gt;

&lt;p&gt;For example, I've used &lt;code&gt;border: none&lt;/code&gt; for ages to remove the border from elements. These days, I'm using &lt;code&gt;border: unset&lt;/code&gt;, and the borders are gone.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/CiTA/embed/XWGLYjN?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Borders are easy because they are non-inherited properties meaning the child element doesn't inherit the value from its parent elements.&lt;/p&gt;

&lt;p&gt;The same goes for margins and paddings, which I regularly need to reset.&lt;/p&gt;

&lt;p&gt;But what about inherited properties? In the example below, the last button will have a blue color. It is because the &lt;code&gt;unset&lt;/code&gt; property essentially means &lt;code&gt;inherit&lt;/code&gt; for the inherited property &lt;code&gt;color&lt;/code&gt;, which the button did and set the &lt;code&gt;color&lt;/code&gt; to &lt;code&gt;blue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/CiTA/embed/BabgVQE?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Inheritance vs. cascade
&lt;/h3&gt;

&lt;p&gt;These things make sense to me, an experienced CSS developer who knows about inheritance. But for a beginner, these concepts are not trivial. I would dare say most beginners didn't even hear about inherited and non-inherited properties or might forget about them. They might learn about the cascade, which is not the same.&lt;/p&gt;

&lt;p&gt;The final styling is based on cascade, specificity, inheritance, and more. MDN has a pretty solid article about understanding &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance" rel="noopener noreferrer"&gt;cascade, specificity, and inheritance&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Also significant here is the concept of inheritance, which means that some CSS properties by default inherit values set on the current element's parent element and some don't. This can also cause some behavior that you might not expect.&lt;/p&gt;

&lt;p&gt;— &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The last sentence seems scary, not knowing what to expect with inheritance. It might help if you remember which property will inherit value from its parents, but that comes with time. Finding that information could be tedious - going to the docs or searching for it in your notes. The important thing is knowing the inheritance exists and that it might cause issues, especially when using the &lt;code&gt;unset&lt;/code&gt; keyword.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unset these properties safely
&lt;/h3&gt;

&lt;p&gt;I figured it might be useful to list the properties I often &lt;code&gt;unset&lt;/code&gt; that are uninherited and, therefore, safe to &lt;code&gt;unset&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;background&lt;/code&gt; (and all its properties like &lt;code&gt;background-color&lt;/code&gt;, &lt;code&gt;background-image&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;border&lt;/code&gt; (and all its properties like &lt;code&gt;border-width&lt;/code&gt;, &lt;code&gt;border-style&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;border-radius&lt;/code&gt; (and all its properties like &lt;code&gt;border-top-left-radius&lt;/code&gt;, &lt;code&gt;border-start-start-radius&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;margin&lt;/code&gt; (and all its properties like &lt;code&gt;margin-top&lt;/code&gt;, &lt;code&gt;margin-block-start&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;padding&lt;/code&gt; (and all its properties like &lt;code&gt;padding-top&lt;/code&gt;, &lt;code&gt;padding-block-start&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;min-height&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;min-block-size&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;min-width&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;min-inline-size&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max-height&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max-block-size&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max-width&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max-inline-size&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;position&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;top&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bottom&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;left&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;right&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;inset&lt;/code&gt; (and all its properties like &lt;code&gt;inset-block&lt;/code&gt;, &lt;code&gt;inset-inline&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;grid&lt;/code&gt; (and all its properties like &lt;code&gt;grid-template-columns&lt;/code&gt;, &lt;code&gt;grid-column&lt;/code&gt;, &lt;code&gt;align-items&lt;/code&gt;, &lt;code&gt;row-gap&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;flex&lt;/code&gt; (and all its properties like &lt;code&gt;flex-basis&lt;/code&gt;, &lt;code&gt;flex-direction&lt;/code&gt;, &lt;code&gt;align-items&lt;/code&gt;, &lt;code&gt;row-gap&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;When it comes to resetting a CSS property, the &lt;code&gt;unset&lt;/code&gt; keyword can come in handy. However, it's important to consider the inheritance of the property you're working with.&lt;/p&gt;

&lt;p&gt;If you want to ensure maximum safety, unsetting the properties that are not inherited may be your best option. By doing this, you can eliminate any potential risks and have peace of mind knowing that your stylesheets are secure.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
    </item>
    <item>
      <title>2023 Lookback</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Fri, 26 Jan 2024 12:13:00 +0000</pubDate>
      <link>https://dev.to/starbist/2023-lookback-3gbj</link>
      <guid>https://dev.to/starbist/2023-lookback-3gbj</guid>
      <description>&lt;p&gt;Let me tell you about the most challenging year in my career, the year 2023.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bad half
&lt;/h2&gt;

&lt;p&gt;I started the year unemployed. In the first half of 2023, I could barely find any job. It was a real challenge with the global economic crisis and everything.&lt;/p&gt;

&lt;p&gt;During this period, I somehow managed to find a few shorter gigs. Two came from Toptal: one small HubSpot job (which reminded me to publish an article about its  &lt;a href="https://dev.to/starbist/nightmare-dx-developer-experience-hubspot-5el8"&gt;horrible developer experience&lt;/a&gt;) and one WordPress job. The other was a Shopify job, which I randomly found in one Slack community.&lt;/p&gt;

&lt;p&gt;I cannot say I enjoyed any of these jobs, but I wasn’t in a situation to complain.&lt;/p&gt;

&lt;p&gt;I spent the majority of my free time on finding a job. I discovered so many sites, so many platforms, and so many bullshit job ads that I started to feel that finding a job is impossible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Always have money in a piggy bank for at least 3 to 6 months if you are a freelancer. You never know when the next crisis will arrive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I knew I needed to keep myself busy, so I worked on my side projects. I polished my website and tried many new techniques and technologies. I wrote more than 20 articles in the first half of the year. I restarted and rebuilt &lt;a href="http://localhost:8080/side-projects/ui-dev-newsletter/archive/" rel="noopener noreferrer"&gt;my newsletter&lt;/a&gt;, which now has more than 600 subscribers (I even got a sponsor for a short time). I even tried a new approach where you rent my UI development services called &lt;a href="https://adedicated.dev/" rel="noopener noreferrer"&gt;A Dedicated Dev&lt;/a&gt;, but it has yet to catch up.&lt;/p&gt;

&lt;p&gt;The first part of the year was just horrible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The good half
&lt;/h2&gt;

&lt;p&gt;Then, in July, everything changed. I landed a few jobs simultaneously, and I couldn’t be happier. First, I worked on an interesting Shopify project. I had to build some new templates and update the existing navigation. The client was stunned when he discovered how optimized the new templates were compared to those from his generic theme.&lt;/p&gt;

&lt;p&gt;Then, I worked on a &lt;a href="https://www.rstudio.com/products/shiny/" rel="noopener noreferrer"&gt;Shiny&lt;/a&gt; project where I had to learn &lt;a href="https://rmarkdown.rstudio.com/" rel="noopener noreferrer"&gt;R Markdown&lt;/a&gt;. I was very excited about it because being paid to learn a new technology is something I have always preferred. I also worked with Highcharts graphs, which I didn’t do for years. It was also the first time I was being paid to design something. I didn’t enjoy that part as much as development, but I cannot say it was a bother either.&lt;/p&gt;

&lt;p&gt;Parallel to that, a manager I worked with before offered me a job as a frontend developer in the marketing team. They needed help with their site, which was built with Next.js, Strapi, and Tailwind. The site was overengineered and unoptimized, so I proposed to rewrite the website with Contentful, Eleventy, and vanilla CSS and JavaScript. Everyone agreed, and we managed to migrate the whole site within a few months.&lt;/p&gt;

&lt;p&gt;Last quarter, I helped an ongoing client build a new Careers page for a Hugo-based site. I also helped develop a Shopify theme for a food industry-related client. And for the first time ever, I developed a website for a client without writing a single line of JavaScript.&lt;/p&gt;

&lt;p&gt;So overall, the second part of the year was a great success.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As the year advanced, I feared I couldn’t pay my bills. But, fortunately, my luck has changed, and it didn’t happen.&lt;/p&gt;

&lt;p&gt;Once again, my advice that you always need money in a piggy bank for at least 3 to 6 months when going freelance came true. You never know when the next crisis will arrive.&lt;/p&gt;

&lt;p&gt;I hope this year will be the best one, not just for me but for everyone.&lt;/p&gt;

</description>
      <category>webdev</category>
    </item>
    <item>
      <title>Nightmare DX (Developer Experience): HubSpot</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Wed, 24 Jan 2024 13:14:00 +0000</pubDate>
      <link>https://dev.to/starbist/nightmare-dx-developer-experience-hubspot-5el8</link>
      <guid>https://dev.to/starbist/nightmare-dx-developer-experience-hubspot-5el8</guid>
      <description>&lt;p&gt;I meant to write about HubSpot’s terrible developer experience (DX) right after my first article about &lt;a href="https://dev.to/starbist/nightmare-dx-developer-experience-shopify-1l79"&gt;Shopify’s nightmare DX&lt;/a&gt; two years ago, but it wasn’t until recently that I had to work with HubSpot again. Although the project was short and sweet, it reminded me to write this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local development
&lt;/h2&gt;

&lt;p&gt;HubSpot, just like Shopify, has limited abilities for local development, and you cannot replicate the HubSpot environment on your computer. The only thing you could do is sync your theme using &lt;a href="https://www.npmjs.com/package/@hubspot/cms-cli" rel="noopener noreferrer"&gt;HubSpot CLI&lt;/a&gt;. And you know what that means? It means no browser sync or hot reloading. It means refreshing your page every few seconds manually.&lt;/p&gt;

&lt;p&gt;Working with HubSpot CLI has been a nightmare experience for me in several scenarios. For example, when developing a new HubSpot module, it is considered the best practice to use Design Tools inside the HubSpot dashboard. With Design Tools, you could configure input fields for your module and copy snippets and/or values. Then, to sync these changes locally, you should fetch your module from the server. No problem there, but on more than a few occasions, the fetch action didn’t override my local files, making me delete the local module and then repeat the fetch action. Talking about the waste of time.&lt;/p&gt;

&lt;p&gt;Then, when you are developing locally and want to add more input fields, you often go back to Design Tools and add these fields. The problem occurs when you forget to refresh the page, have an older version of your module, and then hit the “Publish changes” button, which overrides your local changes. Once you try to fetch the changes, it doesn’t work, so you delete your local module files and try to fetch files from the server again, and guess what? You lose your work because undo doesn’t work on deleted files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dashboard
&lt;/h2&gt;

&lt;p&gt;For an enterprise CMS like HubSpot, you would expect to have an organized dashboard, but HubSpot’s dashboard is everything but organized. For example, if you want to edit your blog listing page, you could navigate to Marketing &amp;gt; Website &amp;gt; Blog and switch from Blog posts to Blog listing pages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fu50i2l4r93sz1saa60mb.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fu50i2l4r93sz1saa60mb.jpeg" alt="Screenshot of the HubSpot dashboard showing how to navigate to blog listing pages." width="759" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you find your Blog listing page, if you want to rename it, you cannot do it here. You need to go to Settings &amp;gt; Tools &amp;gt; Website &amp;gt; Blog. If this makes sense to anyone, please explain how.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6hsp5mx6iez8foa1fxzf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6hsp5mx6iez8foa1fxzf.jpeg" alt="Screenshot of the HubSpot dashboard showing how to navigate to blog listing settings." width="759" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;Although HubSpot documentation is very comprehensive, it should’ve been more organized. The most important pages that help me with HubSpot development, like &lt;a href="https://developers.hubspot.com/docs/cms/hubl/filters" rel="noopener noreferrer"&gt;Hubl filters&lt;/a&gt; and &lt;a href="https://developers.hubspot.com/docs/cms/hubl/functions" rel="noopener noreferrer"&gt;functions&lt;/a&gt;, are so big and slow that it takes over a minute to load them completely. And I need it to load completely because I want to use search to find something on the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbll1vw99z745jqqubz3i.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbll1vw99z745jqqubz3i.jpeg" alt="Screenshot of DevTools showing it takes 1.3 minutes to load the Hubl functions page." width="759" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There are many other things to complain about, but there are the main pain points for me. I had some additional notes in my draft, but I no longer know what they mean. I also have the screenshot with the vague message about access issues, but I don’t know what it means.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjzq6u885tdla367m5fco.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjzq6u885tdla367m5fco.jpeg" alt="Screenshot of the HubSpot alert about access issues." width="759" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are building a webshop or website platform, try to make your tools more enjoyable. Invest more time to listen to what developers say and try to improve the overall developer experience. It would make this developer happier.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Save MBs by converting from GIFs to videos with Cloudinary</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Tue, 23 Jan 2024 10:11:00 +0000</pubDate>
      <link>https://dev.to/starbist/save-mbs-by-converting-from-gifs-to-videos-with-cloudinary-am</link>
      <guid>https://dev.to/starbist/save-mbs-by-converting-from-gifs-to-videos-with-cloudinary-am</guid>
      <description>&lt;p&gt;I switched from GIFs to videos recently. I’ve been using Cloudinary to host my images for years, but I didn’t realize I could use it to convert GIFs to videos automatically. In this post, learn how Cloudinary helped me save megabytes of data by automatically converting GIFs to videos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Converting animated GIFs into videos
&lt;/h2&gt;

&lt;p&gt;Like other transformations on Cloudinary, converting GIF to video could be done as easily as changing the extension of the file from &lt;code&gt;.gif&lt;/code&gt; to &lt;code&gt;.mp4&lt;/code&gt;, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://res.cloudinary.com/.../my-gfx.gif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://res.cloudinary.com/.../my-gfx.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read more about &lt;a href="https://cloudinary.com/documentation/animated_images#converting_an_animated_gif_to_video" rel="noopener noreferrer"&gt;converting an animated Gif to a video on the Cloudinary site&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eleventy shortcodes
&lt;/h2&gt;

&lt;p&gt;Since my site is powered by the awesome Eleventy, changing all GIFs to videos wasn’t too much of a task for me. I was using my custom Liquid shortcode for loading GIFs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;eleventyConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLiquidShortcode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;instant&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;img
      src="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"
      alt="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"
      width="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"
      height="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"
      &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt; &lt;span class="nx"&gt;instant&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; loading="lazy"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;`&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To load the GIF to my blog post, all I had to do was to call the shortcode like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="cp"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gif&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://res.cloudinary.com/starbist/image/upload/v1687771538/Large_GIF_1458x916_qd6iqv"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Demonstration how CSS View Transition works on my site."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;759&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;477&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will produce the following HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class= &lt;/span&gt;&lt;span class="s"&gt;"brad true"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;" https://res.cloudinary.com/starbist/image/upload/v1687771538/Large_GIF_1458x916_qd6iqv"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;" Demonstration how CSS View Transition works on my site."&lt;/span&gt; &lt;span class="na"&gt;width= &lt;/span&gt;&lt;span class="s"&gt;"759"&lt;/span&gt; &lt;span class="na"&gt;height= &lt;/span&gt;&lt;span class="s"&gt;"477"&lt;/span&gt; &lt;span class="na"&gt;loading= &lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To load videos instead GIFs, I introduced a new shortcode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;eleventyConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLiquidShortcode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;video&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;autoplay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;muted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gif&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;video
      width="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"
      height="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"
      controls
      playsinline
      &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;autoplay&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; autoplay&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; loop&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;muted&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; muted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
      poster="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.jpg"&amp;gt;
      &amp;lt;source type="video/mp4" src="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.mp4"&amp;gt;
      &amp;lt;source type="video/webm" src="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.webm"&amp;gt;
      &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;gif&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your browser does not support the HTML5 video tag. &amp;lt;a href="&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.gif"&amp;gt;Click here to view original GIF&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    &amp;lt;/video&amp;gt;`&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To simulate GIF behavior, we must autoplay the video, mute it, and play it in a loop. Here’s how to do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="cp"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;video&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;"https://res.cloudinary.com/.../my-gfx&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;759&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;477&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'autoplay'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'loop'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mute'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'gif'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first parameter is the link to the original GIF but without an extension. It is important to avoid adding extensions because the code will add the JPG extension for the video poster attribute and mp4 and webm extensions for different video formats. Finally, for browsers that don’t support video tags, it will add the text “Your browser does not support the HTML5 video tag. Click here to view original GIF.” with the link to the original GIF.&lt;/p&gt;

&lt;p&gt;Here’s the final HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;video&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"759"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"477"&lt;/span&gt; &lt;span class="na"&gt;controls&lt;/span&gt; &lt;span class="na"&gt;playsinline&lt;/span&gt; &lt;span class="na"&gt;autoplay&lt;/span&gt; &lt;span class="na"&gt;loop&lt;/span&gt; &lt;span class="na"&gt;muted&lt;/span&gt; &lt;span class="na"&gt;poster=&lt;/span&gt;&lt;span class="s"&gt;"https://res.cloudinary.com/.../my-gfx.jpg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"video/mp4"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://res.cloudinary.com/.../my-gfx.mp4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"video/webm"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://res.cloudinary.com/.../my-gfx.webm"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Your browser does not support HTML5 video tag. &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://res.cloudinary.com/.../my-gfx.gif"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click here to view original GIF&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;.
&lt;span class="nt"&gt;&amp;lt;/video&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The savings from switching from GIF to video are tremendous. For this particular video, it goes from 3 MB to less than 0.3 MB, with an additional .08MB for the poster image. That’s pretty awesome, if you ask me. From now on, I am using only videos on my site.&lt;/p&gt;

</description>
      <category>webdev</category>
    </item>
    <item>
      <title>Developer’s research process</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Mon, 22 Jan 2024 08:21:11 +0000</pubDate>
      <link>https://dev.to/starbist/developers-research-process-23mo</link>
      <guid>https://dev.to/starbist/developers-research-process-23mo</guid>
      <description>&lt;p&gt;When given a project or task you don’t know how to solve, you must research and find possible solutions to estimate the required effort. In this post, I will explain how I research before I start developing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hypothetical problem
&lt;/h2&gt;

&lt;p&gt;Let’s say you have to estimate a project where a few things are out of your comfort zone. You are still confident that you can execute the project. You just need to explore possible solutions so you can estimate them. Here’s how I do it (not necessarily in this order).&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 1: Searching
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Search engines
&lt;/h3&gt;

&lt;p&gt;When searching on search engines, I usually try a few different terms, depending on what I want to find. At first, I tried to find articles and tutorials related to the topic. Search results don’t have to be the perfect answer to my problem. I’m just looking for something that might fit my problem. What I’m after is inspiration, something good enough to start with.&lt;/p&gt;

&lt;p&gt;As an advanced search engine user, I am usually good at finding what I need, but that is only sometimes the case. Sometimes the solution is outdated. Sometimes the solution doesn’t have good browser support. Sometimes the solution has accessibility issues. In this case, I turn to some of my favorite websites.&lt;/p&gt;

&lt;h3&gt;
  
  
  Websites
&lt;/h3&gt;

&lt;p&gt;My favorite websites for researching are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MDN, and&lt;/li&gt;
&lt;li&gt;StackOverflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use MDN when I know what technology or feature, in particular, I’m going to use. I am pretty familiar with its navigation and structure, and I generally enjoy using it. Its content is up-to-date, with clear language that I can easily comprehend.&lt;/p&gt;

&lt;p&gt;StackOverflow is still on my research list. There are plenty of answers that are still relevant. I use it mostly to overcome some JavaScript challenges.&lt;/p&gt;

&lt;p&gt;When dealing with specific platforms or frameworks like Netlify, Shopify, Hugo, or Eleventy, I find most answers on their community or official support pages. I always try to find out if someone already asked a specific question before posting my own. These communities are very friendly, answers usually come quickly, and their support teams respond promptly.&lt;/p&gt;

&lt;p&gt;There are some other websites that I occasionally use. Here are honorable mentions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub&lt;/li&gt;
&lt;li&gt;CodePen&lt;/li&gt;
&lt;li&gt;The Practical Dev&lt;/li&gt;
&lt;li&gt;Codrops&lt;/li&gt;
&lt;li&gt;CanIUse&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Social platforms
&lt;/h3&gt;

&lt;p&gt;Sometimes I do my research on social platforms like Twitter and Mastodon. The search feature on both platforms could be more usable, but it helps if you know which person posted the solution. With a bit of scrolling and browsing, I usually find what I searched for.&lt;/p&gt;

&lt;h3&gt;
  
  
  Newsletters
&lt;/h3&gt;

&lt;p&gt;Occasionally, I search my email to find something related to the topic. Sometimes it is my newsletter, UI Dev Newsletter, and sometimes it is other newsletters that give me what I want. That is why I am still subscribed to several newsletters, although I consume most of the web dev content via Twitter or Mastodon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 2: testing
&lt;/h2&gt;

&lt;p&gt;Once I have all the material to solve my problem, I need to try it out to see how it works. Usually, I recreate the solution in the static environment using fundamental technologies - HTML, CSS, and JavaScript. I avoid spending too much time on demos. Instead, I try to figure out the core of the problem or solution.&lt;/p&gt;

&lt;p&gt;At this point, I usually finish my research. I communicate to the client (or the team) which solution or solutions we could use, the advantages or disadvantages, and how much time (or money) it will take.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Nobody knows everything, and some things need time to plan and explore. I learned that saying “I don’t know” is perfectly fine as long as it is followed by “but I’ll take a look at what’s possible.” Search engines, developer communities, social platforms, and newsletters are valuable sources of information that could save you time and help estimate project requirements more accurately.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Transition between pages smoothly with a single line of code</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Wed, 12 Jul 2023 11:49:48 +0000</pubDate>
      <link>https://dev.to/starbist/transition-between-pages-smoothly-with-a-single-line-of-code-3cea</link>
      <guid>https://dev.to/starbist/transition-between-pages-smoothly-with-a-single-line-of-code-3cea</guid>
      <description>&lt;p&gt;&lt;a href="https://developer.chrome.com/docs/web-platform/view-transitions/" rel="noopener noreferrer"&gt;CSS View Transitions&lt;/a&gt; is one of the latest additions to Chromium-based browsers, and I decided to try it.&lt;/p&gt;

&lt;p&gt;I was following &lt;a href="https://daverupert.com/2023/05/getting-started-view-transitions/" rel="noopener noreferrer"&gt;Dave's instructions&lt;/a&gt;, and I immediately noticed something that I liked a lot. As soon as I enabled the View Transitions in my browser (since it is still an experimental technology) and added &lt;code&gt;&amp;lt;meta name="view-transition" content="same-origin"&amp;gt;&lt;/code&gt; to every page of my site, I noticed the transition was already working.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fn2ups4jwc0rv8nuj2ymt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fn2ups4jwc0rv8nuj2ymt.gif" alt="CSS View Transitions in action on my site." width="720" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works in the most basic mode, fading out the current page and fading in the visited page, which is a thousand times better than the default behavior (in my humble opinion). And there you have it—fully functional transitions between your website pages with a single line of code.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>css</category>
    </item>
    <item>
      <title>Announcing A Dedicated Dev</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Tue, 13 Jun 2023 11:43:14 +0000</pubDate>
      <link>https://dev.to/starbist/announcing-a-dedicated-dev-nno</link>
      <guid>https://dev.to/starbist/announcing-a-dedicated-dev-nno</guid>
      <description>&lt;p&gt;Today I launched &lt;a href="https://www.producthunt.com/posts/a-dedicated-dev" rel="noopener noreferrer"&gt;A Dedicated Dev&lt;/a&gt; - a subscription-based web development service. If you need a trustworthy and reliable web developer, you can subscribe and get web development services when you need them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Instead of going through a hiring process for a web developer, all you need to do is subscribe to web development services. Once subscribed, you get a dedicated web developer to make your website the best possible.&lt;/p&gt;

&lt;p&gt;Subscriptions are based on 1, 3, and 6 months - a more extended subscription means a lower cost. With a 1-month subscription, you get the option to pause your subscription. The billing cycle lasts 31 days, and if you pause your subscription on day 14, you can use the remaining days in the later billing cycle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnsxwpt8vbdgs1olx66tz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnsxwpt8vbdgs1olx66tz.jpg" alt="Screenshot of plans section on A Dedicated Dev website." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once subscribed, you can access your Trello board, where you place your requests. No limit exists to how many people you invite to the Trello board or how many requests you submit. Every new request is converted into smaller tasks that are resolved one at a time. It takes a day or two to resolve a task. Remember that A Dedicated Dev is not about speed but about code quality.&lt;/p&gt;

&lt;p&gt;Bugs or breaking functionality takes precedence over regular tasks. A Dedicated Dev will eliminate these situations whenever possible.&lt;/p&gt;

&lt;p&gt;A Dedicated Dev supports web development on the following platforms: WordPress, HubSpot, Shopify, Jekyll, Hugo, Hexo, and Eleventy. If you have a project that uses another platform, contact me, and we can discuss what is possible.&lt;/p&gt;

&lt;p&gt;Most meetings, calls, and syncs are eliminated when working with &lt;a href="https://adedicated.dev/" rel="noopener noreferrer"&gt;A Dedicated Dev&lt;/a&gt;. Asynchronous communication is the key to successful collaboration - no time wasted on unimportant things. So, when making requests, provide as much information as possible, leaving A Dedicated Dev with as few questions as possible.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>If you would have told me…</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Thu, 01 Jun 2023 08:12:38 +0000</pubDate>
      <link>https://dev.to/starbist/if-you-would-have-told-me-35lj</link>
      <guid>https://dev.to/starbist/if-you-would-have-told-me-35lj</guid>
      <description>&lt;p&gt;If you had told me 12 years ago that I would be doing web development for a living, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 11 years ago that I would be doing frontend development for a living, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 10 years ago that I would be working mainly with HTML, CSS, and JavaScript for a living, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 9 years ago that I would be owning a company, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 8 years ago that I would be writing articles for prominent publications, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 7 years ago that I would be working internationally on high-profile projects, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 6 years ago that I would be working from my office downtown, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 5 years ago that I would live in my dream house, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 4 years ago that I would not use CSS or JavaScript frameworks in my everyday tasks, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 3 years ago that I would write my 102nd article, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 2 years ago that I would be working from my home office again, I would laugh at you.&lt;/p&gt;

&lt;p&gt;If you had told me 1 year ago that I would be without a job for 5 months, I wouldn’t laugh at you, but I wouldn’t believe you either.&lt;/p&gt;

&lt;p&gt;Believe in yourself, have dreams and goals, and be yourself. And be sure to have some savings.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
    </item>
    <item>
      <title>Dealing with constant rejection</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Thu, 01 Jun 2023 08:08:26 +0000</pubDate>
      <link>https://dev.to/starbist/dealing-with-constant-rejection-3b0h</link>
      <guid>https://dev.to/starbist/dealing-with-constant-rejection-3b0h</guid>
      <description>&lt;p&gt;Being rejected for any reason in any aspect of life is complicated. Being rejected constantly becomes a real pain. As I struggle to find projects and clients this year, I often have to deal with rejection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of rejection
&lt;/h2&gt;

&lt;p&gt;The first type of rejection is when I see myself taking a job or project, but then it appears I lack the skill for it. Let’s take the last rejection as an example. I was rejected because my “React and Gutenberg skillset doesn’t align with our project needs right now.” Was it my fault for being honest and admitting that I have never worked with these technologies in the production environment? While I did take some courses, do they count? My conscience prevents me from lying, so I go out there and admit I lack these skills. What bothers me is that I feel I would thrive working with these technologies if given a fair chance. But, unfortunately, it seems the world doesn’t work that way.&lt;/p&gt;

&lt;p&gt;Sometimes I don’t even go that far because I was rejected by an online testing platform. I openly admit I am pretty bad at solving algorithm tasks, so I often fail online tests. But am I required to know algorithms if I am in charge of building your website? I don’t see it and cannot remember the last time some algorithm saved the day. The hiring process has been broken for so long that nobody even tries to fix it. I could only guess how many quality people weren’t hired just because they failed some ridiculous online test.&lt;/p&gt;

&lt;p&gt;Often times I am the one that rejects a client. The most common reason is compensation. I worked so hard to be able to reach my current rate. Nobody knows how many nights I’ve been learning or working on a side project to master a skill, framework, or technique. I’m constantly learning and trying to apply my newly acquired knowledge whenever applicable. Clients often don’t even realize all aspects of the delivered project. I am never happy with my average job, so I always try to provide top solutions. I am aware that the global economic situation is far from ideal, so I adjusted my rate, which, by the way, I think is more than fair anyway. Still, there are principles I cannot walk over.&lt;/p&gt;

&lt;p&gt;Sometimes I reject job offers because they require me to solve an exercise. With more than ten years in the industry, I reject solving some foolish task that will take more than a few days. It is because even when I don’t work on paying projects, I work every day. Be it that I am looking for a job and applying, which I think is even more demanding than doing your job, be it that I am preparing my newsletter, optimizing and updating my site, or writing articles. So I reject proving myself all over again when I could do something that makes me feel like I am doing something worthwhile.&lt;/p&gt;

&lt;p&gt;Another reason for rejection is because of the timezone difference. I’m a family man who appreciates my time too much, so I cannot accept being around my computer all day. For example, I had to reject a high-profile client last month because they expected me to be available for a possible meeting the entire day. I usually work in the morning and offer time slots when I am available in the afternoon for meetings. Still, I cannot be available the whole day waiting for a meeting to happen or not. I’ve worked for more than six years with clients worldwide, and everyone appreciated my time by arranging a meeting at least a day in advance so I could plan my time efficiently. That is all I ask, and it is a dealbreaker for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Still positive
&lt;/h2&gt;

&lt;p&gt;It is hard to stay positive when dealing with constant rejection, but I am somehow still positive. It still excites me when I speak with potential clients. I still look forward to hearing about every new project. I guess I just had to wait patiently for the perfect opportunity to arrive.&lt;/p&gt;

&lt;p&gt;Stay positive and happy coding, everyone!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
    </item>
    <item>
      <title>How to measure page loading time with Performance API</title>
      <dc:creator>Silvestar Bistrović</dc:creator>
      <pubDate>Wed, 10 May 2023 07:23:58 +0000</pubDate>
      <link>https://dev.to/starbist/how-to-measure-page-loading-time-with-performance-api-3gci</link>
      <guid>https://dev.to/starbist/how-to-measure-page-loading-time-with-performance-api-3gci</guid>
      <description>&lt;p&gt;A while ago, I stumbled across a blog post by &lt;a href="https://timkadlec.com/" rel="noopener noreferrer"&gt;Tim Kadlec&lt;/a&gt;. Although the blog post was intriguing, something else caught my attention. In Tim’s footer, there’s a text saying how much time did it take to load the page. Naturally, I wanted to incorporate this feature into my website, so I “borrowed” Tim’s code &lt;em&gt;(Mr. Kadlec is aware of this, by the way)&lt;/em&gt;. However, while adjusting the code for my site, I noticed numerous deprecation warnings popping up. Needless to say, it bothered me so much that I had to find a way to eliminate these warnings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fms23u7w1pxlnznr8l62h.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fms23u7w1pxlnznr8l62h.jpeg" alt="Screenshot of VS Code showing deprecation warning for the performance.timing." width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The new way
&lt;/h2&gt;

&lt;p&gt;MDN recommends using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance_API" rel="noopener noreferrer"&gt;Performance API&lt;/a&gt; to gauge the performance of websites and web applications. Unfortunately, while the documentation is comprehensive, it doesn’t provide many examples. So I had to experiment with several approaches, but the results didn’t match the results from the “original” script. Not until I noticed that you could save the &lt;code&gt;performance.mark()&lt;/code&gt; as a variable and read its properties.&lt;/p&gt;

&lt;p&gt;Check out the GIF below, demonstrating how the “old” and “new” versions produce almost identical outcomes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F1tmmt8hi16j01ydb4eoz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F1tmmt8hi16j01ydb4eoz.gif" alt="Page reloading multiple times showing different results for the “old” and “new” way of calculating page load time." width="760" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the final code for getting the page load time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;perf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;$perf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.js-perf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$perf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Wait for the page to finish loading&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pageEnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pageEnd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pageEnd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;

      &lt;span class="nx"&gt;$perf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`Page loaded in &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;loadTime&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s.`&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;perf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the load event is complete, I store the &lt;code&gt;performance.mark(‘pageEnd’)&lt;/code&gt; into a variable. The variable contains several properties, but we only need &lt;code&gt;startTime&lt;/code&gt;. To get the final result in seconds, I divided &lt;code&gt;startTime&lt;/code&gt; by 1000 and displayed it in my placeholder.&lt;/p&gt;

&lt;h2&gt;
  
  
  NPM package
&lt;/h2&gt;

&lt;p&gt;To save you some time, I’ve created an NPM package named &lt;a href="https://www.npmjs.com/package/page-loaded-in" rel="noopener noreferrer"&gt;page-loaded-in&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Place the following code into your &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; and include the &lt;code&gt;.js-page-loaded-in&lt;/code&gt; element to see how fast your page loads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/page-loaded-in@0.0.3/dist/index.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"js-page-loaded-in"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Prioritizing performance when developing web-based projects is crucial to provide users with a seamless and efficient experience. Measuring page loading time using the Performance API is one way to demonstrate that a page is performing well.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
