<?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: Cătălina Hasnaș</title>
    <description>The latest articles on DEV Community by Cătălina Hasnaș (@catalinahasnas).</description>
    <link>https://dev.to/catalinahasnas</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%2F1213615%2F8ff8d080-05fd-423c-b0eb-d74408b46726.jpeg</url>
      <title>DEV Community: Cătălina Hasnaș</title>
      <link>https://dev.to/catalinahasnas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/catalinahasnas"/>
    <language>en</language>
    <item>
      <title>Improve performance, accessibility and SEO of your projects</title>
      <dc:creator>Cătălina Hasnaș</dc:creator>
      <pubDate>Mon, 20 Nov 2023 12:32:18 +0000</pubDate>
      <link>https://dev.to/catalinahasnas/improve-performance-accessibility-and-seo-of-your-projects-56l6</link>
      <guid>https://dev.to/catalinahasnas/improve-performance-accessibility-and-seo-of-your-projects-56l6</guid>
      <description>&lt;h2&gt;
  
  
  Improving My Old Project: A Focus on User Experience
&lt;/h2&gt;

&lt;p&gt;I am a big fan of frontend mentor’s challenges. My favorite thing about the concept is that each person can use the challenge as a means to learn aspects of frontend development that are relevant to them. &lt;/p&gt;

&lt;p&gt;Inspired by this &lt;a href="https://www.youtube.com/watch?v=BkDH55WDiDU"&gt;video on technical SEO for developers&lt;/a&gt;, I came back to my previously completed &lt;a href="https://www.frontendmentor.io/challenges/news-homepage-H6SWTa1MFl"&gt;News homepage challenge&lt;/a&gt; in order to focus on an aspect that I've overlooked when building personal projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6RxHOfhl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9zq88afrhizf43wm2bng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6RxHOfhl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9zq88afrhizf43wm2bng.png" alt="frontend mentor News Homepage challenge" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out the deployed version &lt;a href="https://catalina-hasnas.github.io/news-homepage-main/"&gt;on Github pages&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As frontend developers, we are also responsible for ensuring that our sites are performant, accessible, and optimized for search engines. This not only enhances the user experience but also increases the visibility of our sites, ultimately leading to higher traffic and engagement.&lt;/p&gt;

&lt;p&gt;For the purpose of this article, we’re going to focus on the user experience part of SEO, with Accessibility and Performance being a part of it. Google's &lt;a href="https://pagespeed.web.dev/"&gt;PageSpeed Insights&lt;/a&gt; provides a comprehensive report on the user experience of a page on both mobile and desktop devices, offering suggestions for improvement. These metrics are among the many factors Google considers when &lt;a href="https://developers.google.com/search/docs/appearance/page-experience"&gt;ranking your website&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k5vo6tys--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hftzsb24o5nwnqyqnc5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k5vo6tys--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hftzsb24o5nwnqyqnc5g.png" alt="PageSpeed Insights" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article serves as a beginner’s checklist, a practical guide that can be immediately implemented into your existing projects to enhance these metrics.&lt;/p&gt;

&lt;p&gt;Having said that, here are the changes I implemented to my News HomePage in order to get a perfect score of 100 on all categories of PageSpeed Insights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Semantic HTML&lt;/li&gt;
&lt;li&gt;Image Optimization&lt;/li&gt;
&lt;li&gt;Font Optimization&lt;/li&gt;
&lt;li&gt;Javascript improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Semantic HTML: A Foundation for Accessibility and SEO
&lt;/h2&gt;

&lt;p&gt;Semantic HTML is the proper use of HTML to emphasize the meaning of content in web pages and web applications rather than simply defining its appearance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NgjJ0Rif--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3m7wp2htfkl3ocokiflz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NgjJ0Rif--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3m7wp2htfkl3ocokiflz.png" alt="Semantic HTML meme with the bird" width="800" height="833"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more information on this, I find &lt;a href="https://www.semrush.com/blog/semantic-html5-guide/"&gt;Semantic HTML: What It Is and How to Use It Correctly&lt;/a&gt; to be a good introduction into the subject.&lt;/p&gt;

&lt;p&gt;Or check out this article in the mdn documentation: &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Document_and_website_structure"&gt;Document and website structure&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By using a logical hierarchy of &lt;code&gt;headings&lt;/code&gt; and key structural elements like &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;,&lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;, we can create a cascading hierarchy. This forms an accessibility tree that search engines use to comprehend the structure and content of a web page.&lt;/p&gt;

&lt;p&gt;You can find the accessibility tree of a website in Developer Tools &amp;gt; Accessibility Tab on Firefox and under the Elements tab &amp;gt; Accessibility tab in Chrome. A good way to review it by trying to understand the &lt;em&gt;purpose&lt;/em&gt; of the elements if you couldn’t perceive it visually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cHTeoBFV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pszbhe7a4woznk3jrq9d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cHTeoBFV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pszbhe7a4woznk3jrq9d.png" alt="Accesibility tree of aside html tag" width="731" height="605"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few changes that I made in this regard that I can highlight are: &lt;/p&gt;

&lt;h3&gt;
  
  
  1. Adding a visually hidden &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; to convey information about the site for screen readers and search engines;
&lt;/h3&gt;

&lt;p&gt;The element must be visually hidden without using &lt;code&gt;display: none&lt;/code&gt;, because this would remove it from the accessibility tree. Read more on usage of h1 tag: &lt;a href="https://wdn.unl.edu/page-title-h1-best-practices"&gt;Page Title - H1 - Best Practices&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Use this strategy with caution, because Google can find hidden text to be deceptive. This could potentially lead to your site being penalized by Google, but only if you &lt;a href="https://www.redefineyourmarketing.com/blog/hidden-text-seo-what-google-thinks"&gt;use it unethically&lt;/a&gt;.&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;header&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"visually-hidden"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Latest News in Technology&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;nav&amp;gt;&lt;/span&gt; ... &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;   &lt;span class="nc"&gt;.visually-hidden&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-10000px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&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;h3&gt;
  
  
  2. Consistent usage of a logical a hierarchy of &lt;code&gt;headings&lt;/code&gt; in articles;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--43kxYyRE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dxruk6vatd2yv295h9hh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--43kxYyRE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dxruk6vatd2yv295h9hh.jpg" alt="Headings" width="526" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This news homepage has articles in the sidebar as well as at the bottom of the page. Notice the consistent usage of &lt;code&gt;h3&lt;/code&gt; for article names, &lt;code&gt;h4&lt;/code&gt; for article description. Even though &lt;em&gt;“02”&lt;/em&gt; is the largest text in the article, it is a simple &lt;code&gt;span&lt;/code&gt; due to &lt;em&gt;lack of meaning&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There’s not a lot of strict rules around semantic HTML, but if you build a habit of  thinking about the meaning of an element, you will start making better choices every time. Read more about &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements"&gt;heading elements&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&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;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"section-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"assets/images/image-top-laptops.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"top-laptops"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;02&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Top 10 Laptops of 2022&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;Our best picks for various needs and budgets.&lt;span class="nt"&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;article&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;The Downsides of AI Artistry &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;
           What are the possible adverse effects of on-demand AI image generation?
         &lt;span class="nt"&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;hr&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Correct usage of links and buttons;
&lt;/h3&gt;

&lt;p&gt;The central button that says: &lt;strong&gt;Read more&lt;/strong&gt; is actually a link styled like a button. Its purpose is to take a user to a new &lt;em&gt;location&lt;/em&gt;, where he can read the entire article. Buttons trigger an &lt;em&gt;action&lt;/em&gt;, for example, toggle the menu from opened to closed, which we’re going to touch upon later. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SGbcT-oX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cymi6fhcwc2070oal6yb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SGbcT-oX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cymi6fhcwc2070oal6yb.png" alt="Links and Buttons" width="504" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Adding &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;desc&lt;/code&gt; elements to provide text alternatives for SVG content;
&lt;/h3&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;svg&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Open Navigation Menu&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;desc&amp;gt;&lt;/span&gt;
         Button that opens the menu containing navigation links
         &lt;span class="nt"&gt;&amp;lt;/desc&amp;gt;&lt;/span&gt;
     …
   &lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Correct usage of &lt;code&gt;aria-&lt;/code&gt; attributes;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;aria-&lt;/code&gt; attributes provide additional semantics about the role, state, and functionality of an element, which can be especially helpful for assistive technologies like screen readers. Let’s take a look at our toggle button.&lt;br&gt;
Aria-label represents the name of this button that doesn’t have text. It is read by screen readers to help visually impaired users know the purpose of the button.&lt;br&gt;
The aria-expanded indicates to assistive technology whether the controlled element (the menu) is expanded or collapsed.&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;nav&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navigation-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
        &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"toggle-menu"&lt;/span&gt;
        &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
        &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"toggle menu"&lt;/span&gt;
        &lt;span class="na"&gt;aria-controls=&lt;/span&gt;&lt;span class="s"&gt;"menu"&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;svg&amp;gt;&lt;/span&gt;
       ...
          &lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"menu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; Home &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          ...
       &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Optimize Images: Prioritizing Contentful Paint and Layout Stability
&lt;/h2&gt;

&lt;p&gt;Image optimization is crucial for &lt;a href="https://developers.google.com/search/docs/appearance/core-web-vitals"&gt;Core Web Vitals&lt;/a&gt; (the set of metrics that Google uses to measure the user experience of a webpage) for several reasons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact on Largest Contentful Paint (LCP)&lt;/strong&gt;: Images can significantly impact the LCP score, which measures how long it takes for the largest element on the page to become visible to the user. If an image is enqueued too late or takes too long to load, it can significantly slow down the page’s LCP score.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact on Cumulative Layout Shift (CLS)&lt;/strong&gt;: Images can cause layout shifts if they are not properly sized and are inserted into the page after it has already loaded, causing other elements to move around. This can negatively impact the CLS score, which measures the visual stability of a page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N2YBbvwP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vnxlz534yxhc2jh9jihk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N2YBbvwP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vnxlz534yxhc2jh9jihk.gif" alt="Layout shift" width="600" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To address these issues, I implemented a few changes. Note that this is just stretching the surface of image optimization. You can find more information on other important topics such as image compression on the internet if you want to dive deeper.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Defining the width and height attributes of images;
&lt;/h3&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;picture&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"image"&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;media=&lt;/span&gt;&lt;span class="s"&gt;"(min-width: 62em)"&lt;/span&gt;
        &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"assets/images/image-web-3-desktop.jpg"&lt;/span&gt;
        &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"850"&lt;/span&gt;
        &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;
      &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
           &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"assets/images/image-web-3-mobile.jpg"&lt;/span&gt;
           &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"article-image"&lt;/span&gt;
           &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"480"&lt;/span&gt;
           &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;
         &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/picture&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While these values do not dictate the rendered size of the image, they assist the browser in reserving the appropriate amount of space for the image. You can still style the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; with css.&lt;/p&gt;

&lt;p&gt;This approach is effective when you have control over the image. In instances where you don't, such as when fetching from an API, alternative solutions exist. One such solution is to &lt;a href="https://www.amitmerchant.com/prevent-image-layout-shift-using-this-simple-css-hack/"&gt;set the size of the parent container and contain the image within it&lt;/a&gt;.&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="nc"&gt;.image-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&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;These are similar to what &lt;a href="https://nextjs.org/docs/app/building-your-application/optimizing/images"&gt;Next.js&lt;/a&gt; uses with its Image component in order to prevent layout shifts. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZVBjc-dK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1cuasgn25k94mv56fmol.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZVBjc-dK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1cuasgn25k94mv56fmol.gif" alt="layout stability with display absolute" width="600" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Adding high priority preloading of the image that is the largest and appears first on the screen;
&lt;/h3&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;link&lt;/span&gt;
     &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"preload"&lt;/span&gt;
     &lt;span class="na"&gt;fetchpriority=&lt;/span&gt;&lt;span class="s"&gt;"high"&lt;/span&gt;
     &lt;span class="na"&gt;as=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt;
     &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"assets/images/image-web-3-mobile.jpg"&lt;/span&gt;
     &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/jpg"&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;I didn’t do this for this project, but you can also add &lt;strong&gt;lazy loading&lt;/strong&gt; for the images that are not immediately displayed on the page.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Using alternative image formats;
&lt;/h3&gt;

&lt;p&gt;While this project utilizes images in the .jpg format, alternative formats such as &lt;code&gt;.avif&lt;/code&gt; or &lt;code&gt;.webp&lt;/code&gt; can &lt;a href="https://photutorial.com/image-format-comparison-statistics/"&gt;provide better quality photos when compressed and smaller file size when uncompressed&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimize Fonts: Tackling Layout Shifts and Load Times
&lt;/h2&gt;

&lt;p&gt;Along with images, fonts are the culprits of layout shifts and prolonged load times, due to requests made to the Google Fonts API. &lt;/p&gt;

&lt;p&gt;For this particular project, we were provided with the specific font name and weights required, enabling us to download the necessary &lt;code&gt;.ttf&lt;/code&gt; files and incorporate them into our static assets. This eliminates the need for &lt;em&gt;server requests&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;While this approach accelerates the process, a shift from the fallback font still occurs, which can even alter the text’s line arrangement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TfyCFUyj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwchtj6t0t22tx77i00q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TfyCFUyj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwchtj6t0t22tx77i00q.gif" alt="Layout shift due to font load" width="600" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To address this, I implemented a &lt;strong&gt;fallback font strategy&lt;/strong&gt;. Arial, being a widely available font, is adjusted using several properties with the assistance of a &lt;a href="//screenspan.net/fallback"&gt;Fallback Font Generator&lt;/a&gt;. This ensures layout consistency until the desired font is loaded.&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="k"&gt;@font-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Inter"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url("../assets/fonts/Inter.ttf")&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;"truetype"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;font-display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;@font-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Adjusted Arial Fallback"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;size-adjust&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;109%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;ascent-override&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;86%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;descent-override&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;line-gap-override&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&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;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FnWPpd0w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwie15n6qcrq7ctun0st.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FnWPpd0w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwie15n6qcrq7ctun0st.gif" alt="Layout stability after custom fallback font" width="596" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Still a bit of a layout shift, but much better than before :).&lt;/p&gt;

&lt;h2&gt;
  
  
  Efficient JavaScript: Reducing Overhead and Enhancing Performance
&lt;/h2&gt;

&lt;p&gt;The News homepage project doesn’t demand extensive JavaScript coding. The only user interaction opportunity is toggling between expanded and collapsed states of a menu on a button click. We also need to handle image change when the screen size changes. Therefore, I won’t be elaborating much on the third Core Web Vital &lt;strong&gt;First Input Delay (FID)&lt;/strong&gt; (or &lt;strong&gt;Interaction to Next Paint (INP)&lt;/strong&gt; that will replace FID as a Core Web Vital in March 2024) and its optimization techniques. I encourage you to read through &lt;a href="https://web.dev/articles/fid"&gt;this web.dev article&lt;/a&gt; for more on this.&lt;/p&gt;

&lt;p&gt;Despite the project’s simplicity, I still managed to write some inefficient JavaScript code to be later improved through refactoring.&lt;/p&gt;

&lt;p&gt;The handleResize() function is not a function that I’m proud of writing, primarily due to its &lt;em&gt;over-reliance on JavaScript for presentation logic that could be handled by CSS&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;It is attached to the window’s resize event. This means it will be called every time the window is resized, which can trigger many times per second during a resize, leading to high CPU usage.&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;handleResize&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;articleImage&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="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;article-image&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matchMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;(max-width: 992px)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display-none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex-direction-column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;toggleMenuButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display-none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;articleImage&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="nx"&gt;imageMobile&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display-none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex-direction-column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;toggleMenuButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display-none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;articleImage&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="nx"&gt;imageDesktop&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleResize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;handleResize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By utilizing the &lt;code&gt;srcSet&lt;/code&gt; attribute on images to manage screen resizing and implementing a more efficient CSS logic, I was able to completely eliminate the handleResize function. I now have a single event listener on the toggle button to manage clicks. &lt;/p&gt;

&lt;p&gt;Instead of adding and removing the “display-none” and “flex-direction-column” classes depending on the screen size, the toggle() method on classList adds the “expanded” class if it doesn’t exist and removes it if it does and lets CSS handle the rest.&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;toggleMobileMenu&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="nx"&gt;navBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;expanded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;backdrop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;backdrop&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;navBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;expanded&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;toggleMenuButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aria-expanded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;toggleMenuButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aria-expanded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;span class="nb"&gt;document&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toggle-menu&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;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;toggleMobileMenu&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;While there are numerous scenarios where reducing JavaScript usage may not be straightforward, cultivating a habit of evaluating whether a task can be accomplished with less JavaScript is likely to enhance performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Continuous Journey of Improvement
&lt;/h2&gt;

&lt;p&gt;The use of Semantic HTML, image and font optimization, and JavaScript reduction are just a few strategies to improve the user experience of your website.&lt;br&gt;
It’s crucial to continuously test, learn, and adapt your strategies based on your specific needs and goals. I encourage you to try these strategies on your personal projects, as you build habits that will serve real-life projects as well. &lt;/p&gt;

&lt;p&gt;I hope you found this article helpful. As I share my knowledge with you, I am also learning myself. Therefore, your questions, comments, and suggestions are so greatly appreciated🙏 and will help improve future content. Thank you for taking the time to read and engage with this material. Happy coding!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
