<?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: Abdulhamid Oumer</title>
    <description>The latest articles on DEV Community by Abdulhamid Oumer (@abdulhamidoumer).</description>
    <link>https://dev.to/abdulhamidoumer</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%2F103925%2F3c1a0176-8e99-410c-bea4-86d6cf0b2926.png</url>
      <title>DEV Community: Abdulhamid Oumer</title>
      <link>https://dev.to/abdulhamidoumer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abdulhamidoumer"/>
    <language>en</language>
    <item>
      <title>Cooked up a React Native boilerplate</title>
      <dc:creator>Abdulhamid Oumer</dc:creator>
      <pubDate>Mon, 11 Oct 2021 22:28:59 +0000</pubDate>
      <link>https://dev.to/abdulhamidoumer/react-boilerplate-for-react-native-487k</link>
      <guid>https://dev.to/abdulhamidoumer/react-boilerplate-for-react-native-487k</guid>
      <description>&lt;p&gt;If you have worked with &lt;a href="https://www.reactboilerplate.com/"&gt;React Boilerplate&lt;/a&gt; before you probably know how much time it saves you when getting started with a big project. Not only at the start of a project, react boilerplate also comes in handy when you are in the middle of development. It makes writing repetitive codes easier by providing you with it's own CLI tools to generate boilerplate codes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kTPGYlI7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fltag4gc03w8d9ykm6c4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kTPGYlI7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fltag4gc03w8d9ykm6c4.gif" alt="Repeating Code" width="300" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I started working on a React Native project recently and thought to my self why there was no similar thing for React Native, to the best of my knowledge. So I decided to migrate some of the things we knew on &lt;a href="https://www.reactboilerplate.com/"&gt;React Boilerplate&lt;/a&gt; and &lt;a href="https://github.com/react-boilerplate/react-boilerplate-cra-template"&gt;React Boilerplate CRA Template&lt;/a&gt; to a separate react native template. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: Current version of the template might not be too optimal for production builds.&lt;/p&gt;

&lt;p&gt;The template takes some part of the original react boilerplates like the component and slice generators, redux toolkit setup and redux saga. It also adds react native specific CLI tools like App Icon setters and Splash screen logo setters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/abdulhamidOumer/react-native-typescript-boilerplate"&gt;The template&lt;/a&gt; comes by default with the tools listed below :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://redux-toolkit.js.org/"&gt;Redux Toolkit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reactnavigation.org/"&gt;React Navigation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/react-native-splash-screen"&gt;React Native Splash Screen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://redux-saga.js.org/"&gt;Redux Saga&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/reduxjs/reselect"&gt;Reselect&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This blog assumes that you are familiar with &lt;a href="https://reactnative.dev/"&gt;&lt;code&gt;react-native&lt;/code&gt;&lt;/a&gt; and the CLI tool provided by &lt;code&gt;react-native&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the template
&lt;/h2&gt;

&lt;p&gt;Getting started with the template is fairly easy. There are only a few number of steps as listed down below. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: using &lt;a href="https://yarnpkg.com/"&gt;YARN&lt;/a&gt; over NPM is recommend when using this template.&lt;/p&gt;

&lt;p&gt;1. Create react native app by providing&lt;code&gt;react-native typescript-boilerplate&lt;/code&gt; as a template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx react-native myapp --template https://github.com/abdulhamidOumer/react-native-typescript-boilerplate.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2. Get into the generated app's directory and explore the code and features.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd myapp
yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3. Get started by setting your app icon or splash screen icon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn set
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command is used to set native related assets for your app. One pain point of working with react native is generating app icons with their corresponding platform size guidelines. By using this command you will be able to generate both Android and IOS app icons as well as splash screen icons based on the platform recommended size guideline just from one picture. Pictures that you want to use as app icon or as a splash screen logo need to be inside &lt;code&gt;src/assets/images&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;4. Optional - Initiate husky pre-commit hooks&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn init-husky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will initiate a new git repository for your project if it doesn't exist currently and sets up husky so you can utilize pre commit and push hooks.&lt;/p&gt;

&lt;p&gt;Full documentation for the current version is available on &lt;a href="https://abdulhamidoumer.gitbook.io/rn-ts-boilerplate/"&gt;GitBook&lt;/a&gt;. Any kind of contribution is always welcome and appreciated as I am getting started with the project there is still a lot to be done. Full code available on &lt;a href="https://github.com/abdulhamidOumer/react-native-typescript-boilerplate"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📖 &lt;a href="https://abdulhamidoumer.gitbook.io/rn-ts-boilerplate/"&gt;GitBook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 &lt;a href="https://github.com/abdulhamidOumer/react-native-typescript-boilerplate"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>reactnative</category>
      <category>react</category>
    </item>
    <item>
      <title>Pointing cPanel Hosting Domain To Netlify: The pain of hosting websites in Ethiopia</title>
      <dc:creator>Abdulhamid Oumer</dc:creator>
      <pubDate>Tue, 14 Sep 2021 22:55:42 +0000</pubDate>
      <link>https://dev.to/abdulhamidoumer/pointing-cpanel-hosting-domain-to-netlify-the-pain-of-hosting-websites-in-ethiopia-53po</link>
      <guid>https://dev.to/abdulhamidoumer/pointing-cpanel-hosting-domain-to-netlify-the-pain-of-hosting-websites-in-ethiopia-53po</guid>
      <description>&lt;p&gt;I recently finished working on my portfolio site &lt;a href="https://abdulhamid.et"&gt;abdulhamid.et&lt;/a&gt;, this blog is dedicated to one of the issue I was facing while trying to implement my site on a Next.JS environment. Something to note here is that, this was not the first time I was facing this issue, the same exact thing happened when we were trying to implement our podcast &lt;a href="https://zemachfm.com"&gt;Zemach FM&lt;/a&gt;'s new site.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disclaimer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This guide assumes that you already have a free Netlify subdomain site.&lt;/li&gt;
&lt;li&gt;Some cPanel hosting providers give access to some resources and disable some resources by default. This tutorial is designed with the assumption that you have &lt;code&gt;Domain&lt;/code&gt;, &lt;code&gt;Subdomain&lt;/code&gt; and &lt;code&gt;Zone Editor&lt;/code&gt; access from your hosting provider.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The core problem is how do you deploy a JAM stack website with your own custom domain from Ethiopia. Recently some web-hosting services have been coming up here and there in Ethiopia. But All the services I have run in to use C-Panel hosting. This will solve the domain name purchasing issue in our Ethiopia, but hosting sites that are not static or not Wordpress on cPanel is going to be painful. Some of the providers claim they have Node.JS support but they are full of bugs with no support to CI/CD integrations, you will have to be willing to upload your code base every time you make a change. This is not scalable. There might be a way to implement automatic deployment right from your repository, but I am not aware of it currently. Plus I am sure you will all agree with me that cloud hosting services like &lt;a href="https://netlify.com"&gt;Netlify&lt;/a&gt; and &lt;a href="https://vercel.com"&gt;Vercel&lt;/a&gt; have much superior response time compared to most of the hosting providers that we currently have access to in Ethiopia.&lt;/p&gt;

&lt;p&gt;Of course the main reason we can't use paid services outside Ethiopia is because it's impossible to make international payments online from Ethiopia. But thanks to &lt;a href="https://netlify.com"&gt;Netlify&lt;/a&gt;, I was able to deploy my portfolio with their free plan. &lt;/p&gt;

&lt;p&gt;So I have a custom domain and my Next.JS site on netlify with it's own automatic build and deploy set up. What can be done to integrate the two separate services ?&lt;/p&gt;

&lt;p&gt;That's where the cPanel's Zone editor and Netlify's custom domain come in to play. Let's first see how we can point our root domain from cPanel to our Netlify site instance.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First navigate to the &lt;code&gt;Zone Editor&lt;/code&gt; from the home page of your cPanel.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v8JfK4Wk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lqopr8zglpbxq94qf0br.png" alt="Click zone editor"&gt;
&lt;/li&gt;
&lt;li&gt;From there click &lt;code&gt;Manage&lt;/code&gt; on your main domain.&lt;/li&gt;
&lt;li&gt;After the page finishes loading there will be two records with your root domain names, at the top of the list. Change their settings according to the screenshot below. The &lt;code&gt;A&lt;/code&gt; record will point to Netlify's default &lt;a href="https://docs.netlify.com/domains-https/custom-domains/configure-external-dns/#configure-an-apex-domain"&gt;load balancer IP address&lt;/a&gt;, &lt;code&gt;75.2.60.5&lt;/code&gt;. Change the second record to an &lt;code&gt;MX&lt;/code&gt; type and fill in your netlify site default subdomain. You can find your netlify default subdomain at app.netlify.com &amp;gt; Your Web App / Domain &amp;gt; Domain Settings
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2qPEyzMm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t12os271oae840jadtz6.png" alt="Zone editor domain list"&gt;
&lt;/li&gt;
&lt;li&gt;Go to your netlify dashboard click on the site you want to configure &amp;gt; Domain Setting &amp;gt; Add Domain Alias. This will open a setting modal. On the modal fill in your new domain and save your changes.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lxZcMR-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/izhvnlip0dezpygy9s2o.png" alt="Site list"&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZoSRSQJl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvtoah304ce1zsagg0lf.png" alt="Add Root Domain Alias"&gt;
&lt;/li&gt;
&lt;li&gt;After that finishes saving, you can set the root domain as a primary domain. Just click on the &lt;code&gt;options&lt;/code&gt; dropdown next to the newly added domain.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Pointing a cPanel Subodmain to Netlify
&lt;/h2&gt;

&lt;p&gt;If you are pointing a subdomain to your netlify instance, the process can take place as follow.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the subdomain by clicking on the &lt;code&gt;Subdomains&lt;/code&gt; button in your cPanel Domains section.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NhDh-dzn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mi28636iqex1x17df3bf.png" alt="Create Cpanel Subdomain"&gt;
&lt;/li&gt;
&lt;li&gt;Give your subdomain a name and leave the root directory the default value of the form.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8yRoVVfy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jwgkigv604jdtk1jbvb3.png" alt="Cpanel Subdomains"&gt;
&lt;/li&gt;
&lt;li&gt;Go back to the previous &lt;code&gt;Domains&lt;/code&gt; section at the home page of cPanel and navigate to &lt;code&gt;Zone Editor&lt;/code&gt;. From there click &lt;code&gt;Manage&lt;/code&gt; on your main domain.&lt;/li&gt;
&lt;li&gt;Find your subdomain on the list that is displayed. You will probably find two version of your subdomain. one with the prefix &lt;code&gt;www&lt;/code&gt; and one without.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sOuLwavB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1xqe0mnbxw1vk073ydg5.png" alt="New subdomains"&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove the one with the &lt;code&gt;www&lt;/code&gt; prefix and edit the main subdomain just like it's shown below. Change the record type to &lt;code&gt;CNAME&lt;/code&gt; and the record to your netlify's default subdomain. You can find your netlify default subdomain at app.netlify.com &amp;gt; Your Web App / Domain &amp;gt; Domain Settings.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zmL6sWrq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0jhqb33mv2e0lempe8uc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zmL6sWrq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0jhqb33mv2e0lempe8uc.png" alt="Subdomain record edit"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally go to your netlify dashboard click on the site you want to configure &amp;gt; &lt;code&gt;Domain Setting&lt;/code&gt; &amp;gt; &lt;code&gt;Add Domain Alias&lt;/code&gt;. This will open a setting modal. On the modal fill in your new subdomain and save your changes.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lxZcMR-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/izhvnlip0dezpygy9s2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lxZcMR-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/izhvnlip0dezpygy9s2o.png" alt="Site list"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sNv6hgiR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5r5hnpj34uzh5yyo2xcl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sNv6hgiR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5r5hnpj34uzh5yyo2xcl.png" alt="Add Subdomain Alias"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now if your DNS configuration was correct your new domain and subdomain are good to go. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: You might need to wait a few minute until your sites SSL kicks in. Until then you can surf your site in un-secure mode.&lt;/p&gt;

</description>
      <category>netlify</category>
      <category>devjournal</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Get that hundo 💯 (Part 2) - Using WebP Without Fearing Browser Support</title>
      <dc:creator>Abdulhamid Oumer</dc:creator>
      <pubDate>Mon, 08 Feb 2021 20:58:46 +0000</pubDate>
      <link>https://dev.to/abdulhamidoumer/get-that-hundo-part-2-using-webp-without-fearing-browser-support-4dck</link>
      <guid>https://dev.to/abdulhamidoumer/get-that-hundo-part-2-using-webp-without-fearing-browser-support-4dck</guid>
      <description>&lt;p&gt;On my &lt;a href="https://dev.to/abdulhamidoumer/get-that-hundo-part-1-handling-unused-font-awesome-css-styles-17nd"&gt;previous post&lt;/a&gt; we saw how I was able to improve my lighthouse scores by moving away from font-awesome and using SVG sprites. We stopped last time when I got the lighthouse scores down below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y27XiDyd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/41yai2zxapxrec0vnkf5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y27XiDyd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/41yai2zxapxrec0vnkf5.png" alt="Last Score" width="880" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the second part of "Get that hundo" I will share with you how I was able to implement one of the optimizations recommended by lighthouse :&lt;/p&gt;

&lt;h2&gt;
  
  
  Using a next-gen image format
&lt;/h2&gt;

&lt;p&gt;One of the suggestions made by lighthouse was to use a next-generation image format that is smaller in size. Some of these image formats are &lt;code&gt;webp&lt;/code&gt;, &lt;code&gt;JPEG XR&lt;/code&gt; or &lt;code&gt;JPEG 2000&lt;/code&gt;. Why even bother serving your images in this format? Well, these image formats are the superior ones in both compression and quality compared to their predecessors &lt;code&gt;PNG&lt;/code&gt; and &lt;code&gt;JPEG&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Out of the three next-gen formats I chose WebP because it is supported in more browsers, it is being developed by Google currently and it also supports both lossy &amp;amp; lossless compressions.&lt;/p&gt;

&lt;p&gt;To convert images to WebP we can easily use sites like &lt;a href="https://webp-converter.com/"&gt;webp-converter.com&lt;/a&gt;. This specific tool even has the ability to do lossless or lossy compression.&lt;/p&gt;

&lt;p&gt;Now when using WebP the main issue that you face is browser compatibility. WebP is not even supported on safari except for the latest version, which is 14 at the time of writing this blog. That is where the HTML &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; tag comes into play. &lt;/p&gt;

&lt;p&gt;Picture tag takes one &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag and zero or more sources as a child element. The &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; tag will then automatically choose the image source that will suit the user's browser or other conditions like max-width of the screen, if all sources don't meet the condition it will fallback to the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag source. Below is a code showing you how we could take advantage of this :&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;picture&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"./assets/avatar.webp"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/webp"&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;srcset=&lt;/span&gt;&lt;span class="s"&gt;"./assets/avatar.png"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/png"&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;width=&lt;/span&gt;&lt;span class="s"&gt;"200px"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200px"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"avatar"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bio-container__content__avatar avatar"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./assets/avatar.png"&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;Now, we can handle images in our HTML this way but what about background images that are set by a CSS style. There is a solution for that.&lt;/p&gt;

&lt;p&gt;On Google developers WebP FAQ &lt;a href="https://developers.google.com/speed/webp/faq"&gt;page&lt;/a&gt; there is already a vanilla JavaScript implementation to check if a browser supports WebP formats. The implemented code takes a small part of a certain featured WebP image (i.e lossy or lossless) and tries to decode that if the operation is successful it means the browser supports WebP images. The function is implemented this way&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="c1"&gt;// check_webp_feature:&lt;/span&gt;
&lt;span class="c1"&gt;//   'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.&lt;/span&gt;
&lt;span class="c1"&gt;//   'callback(feature, result)' will be passed back the detection result (in an asynchronous way!)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;check_webp_feature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;kTestImages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;lossy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;lossless&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&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;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&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;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feature&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="nx"&gt;img&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="s2"&gt;data:image/webp;base64,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;kTestImages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;feature&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;Let's see how can we take advantage of this function to display other formats for browsers that don't WebP. The first thing we need to do is create one normal CSS style with WebP background and one other style with PNG background.&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;.full-screen-hero&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url("../assets/header-background.webp")&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.full-screen-hero.no-webp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url("../assets/header-background.png")&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;Next, we check if the browser supports WebP on window load and add the &lt;code&gt;.no-webp&lt;/code&gt; class if it doesn't support it. I will use the &lt;code&gt;lossless&lt;/code&gt; feature check for now cause that was how I converted my background image to WebP.&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;check_webp_feature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lossless&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;success&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="c1"&gt;// Recurse theough elements with WebP background and add the no-webp class &lt;/span&gt;
            &lt;span class="nx"&gt;fullScrenHero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bgElement&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="nx"&gt;bgElement&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="s1"&gt;no-webp&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="p"&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;This optimization didn't have much effect on the lighthouse performance score because I was already using WebP as a background image before all this but now I was able to solve the compatibility issues on safari.&lt;/p&gt;

&lt;p&gt;That's it now the site is ready to serve WebP on supporting browsers and PNGs on browsers that don't support WebP.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>javascript</category>
      <category>css</category>
      <category>html</category>
    </item>
    <item>
      <title>Get that hundo 💯 (Part 1) - Handling unused font-awesome css styles</title>
      <dc:creator>Abdulhamid Oumer</dc:creator>
      <pubDate>Mon, 01 Feb 2021 05:58:35 +0000</pubDate>
      <link>https://dev.to/abdulhamidoumer/get-that-hundo-part-1-handling-unused-font-awesome-css-styles-17nd</link>
      <guid>https://dev.to/abdulhamidoumer/get-that-hundo-part-1-handling-unused-font-awesome-css-styles-17nd</guid>
      <description>&lt;p&gt;As I have mentioned in my &lt;a href="https://dev.to/abdulhamidoumer/finish-that-side-project-building-my-portfolio-site-series-4e7i"&gt;last blog&lt;/a&gt;, I have promised to share my experiences in building my portfolio site as a side project.&lt;/p&gt;

&lt;p&gt;Today we will be taking a look at how we can improve our lighthouse score by taking care of unused CSS issue that was caused by font-awesome, according to how it worked for me at least. So the story of how I decided to go through this topic goes like this, I just threw some stuff like font-awesome and some styles to the landing page without considering performance at first and see how that can affect my lighthouse score. Note that I have only written a few lines of Javascript to handle some smooth scrolling at this time, but lo and behold the performance score is in the gutters.&lt;/p&gt;

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

&lt;p&gt;Now there were some reasons as to why this was happening, I will try to investigate and solve the main reason on this blog :&lt;/p&gt;

&lt;h2&gt;
  
  
  Unused CSS styles
&lt;/h2&gt;

&lt;p&gt;Now, why would unused CSS styles affect a site's speed? The logic is pretty simple, unused CSS will increase the size of your page thus taking a longer time to finish a request. When the unused styles are few in number it might not have a drastic effect on the page size. But when the unused styles come from libraries like font awesome or bootstrap, which have somewhat larger minified file sizes (58KB &amp;amp; 149KB respectively) lighthouse will be complaining about a lot of unused styles. Besides, you will also have a lot of redundant code.&lt;/p&gt;

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

&lt;p&gt;By also taking a look at the developer console coverage tab, we can see from above that 99% of the code is redundant and unused.&lt;/p&gt;

&lt;p&gt;So what can we do to resolve unused CSS issues when using icon fonts like font-awesome. One solution can be using tools like &lt;a href="https://fontello.com/" rel="noopener noreferrer"&gt;fontello&lt;/a&gt;. Fontello allows you to create your own font icon pack by letting you pick the icons that your site will be using, It has got icon packs from font-awesome 4.7, Typicons and more. you will also be able to add your own SVG icons. &lt;/p&gt;

&lt;p&gt;Another solution can be using inline SVGs. When using inline SVGs you will be inserting the SVG code right in the HTML. This will bring all your icons with just one HTTP request unlike font icons which will require another request. Not only that SVGs hold the upper hand when it comes to accessibility. Tags like &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; make it accessible for screen readers. With that in mind I decided to use inline SVG. Let's take a look at one way you can achieve that step by step.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download the icons in SVG format. Fontawesome already lets you do that easily from the &lt;a href="https://fontawesome.com/icons?d=gallery" rel="noopener noreferrer"&gt;gallery&lt;/a&gt; page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build your SVG icon system with tools like &lt;a href="https://icomoon.io/" rel="noopener noreferrer"&gt;IcoMoon&lt;/a&gt; or &lt;a href="http://fontastic.me/" rel="noopener noreferrer"&gt;Fontastic&lt;/a&gt;. IcoMoon will give you an SVG sprite and some css code that you can insert in to your project. Here's an example of the code I got from IcoMoon.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: absolute; width: 0; height: 0; overflow: hidden;"&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.1"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt; &lt;span class="na"&gt;xmlns:xlink=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/1999/xlink"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;defs&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;symbol&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"icon-blog-solid"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 32 32"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;blog-icon&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M10.762 14.175c-0.912-0.181-1.762 0.556-1.762 1.488v3.15c0 0.637 0.444 1.15 1.044 1.375 1.137 0.425 1.956 1.525 1.956 2.813 0 1.656-1.344 3-3 3s-3-1.344-3-3v-15.5c0-0.831-0.669-1.5-1.5-1.5h-3c-0.831 0-1.5 0.669-1.5 1.5v15.5c0 5.594 5.131 10.013 10.938 8.794 3.4-0.712 6.144-3.462 6.856-6.856 1.087-5.181-2.313-9.825-7.031-10.762zM13.063 0c-0.575-0.031-1.063 0.425-1.063 1v1.975c0 0.531 0.412 0.969 0.938 0.994 8.087 0.438 14.587 7 15.056 15.094 0.031 0.525 0.469 0.938 0.994 0.938h2.006c0.575 0 1.031-0.488 1-1.063-0.531-10.2-8.731-18.4-18.931-18.938zM13.081 6c-0.581-0.044-1.081 0.419-1.081 1.006v2.006c0 0.525 0.406 0.956 0.925 0.994 4.8 0.394 8.625 4.263 9.056 9.075 0.050 0.519 0.475 0.919 0.994 0.919h2.012c0.581 0 1.050-0.5 1.006-1.081-0.525-6.881-6.031-12.387-12.912-12.919z"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/path&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;symbol&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"icon-twitter-brands"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 32 32"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;twitter-icon&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M28.711 9.482c0.020 0.284 0.020 0.569 0.020 0.853 0 8.67-6.599 18.66-18.66 18.66-3.716 0-7.168-1.076-10.071-2.944 0.528 0.061 1.036 0.081 1.584 0.081 3.066 0 5.888-1.035 8.142-2.802-2.883-0.061-5.3-1.949-6.132-4.548 0.406 0.061 0.812 0.102 1.239 0.102 0.589 0 1.178-0.081 1.726-0.223-3.005-0.609-5.259-3.249-5.259-6.437v-0.081c0.873 0.487 1.888 0.792 2.964 0.832-1.766-1.178-2.924-3.188-2.924-5.462 0-1.218 0.325-2.335 0.893-3.31 3.228 3.98 8.081 6.579 13.523 6.863-0.101-0.487-0.162-0.995-0.162-1.502 0-3.614 2.924-6.558 6.558-6.558 1.888 0 3.594 0.792 4.792 2.071 1.482-0.284 2.904-0.832 4.162-1.584-0.487 1.523-1.523 2.802-2.883 3.614 1.32-0.142 2.599-0.508 3.777-1.015-0.893 1.299-2.010 2.457-3.289 3.391z"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/path&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;symbol&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"icon-arrow-down-solid"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 28 32"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;arrow-down-icon&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M25.819 13.906l1.387 1.387c0.587 0.588 0.587 1.538 0 2.119l-12.144 12.15c-0.588 0.587-1.537 0.587-2.119 0l-12.15-12.15c-0.588-0.587-0.588-1.537 0-2.119l1.388-1.387c0.594-0.594 1.563-0.581 2.144 0.025l7.175 7.531v-17.962c0-0.831 0.669-1.5 1.5-1.5h2c0.831 0 1.5 0.669 1.5 1.5v17.962l7.175-7.531c0.581-0.613 1.55-0.625 2.144-0.025z"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/path&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/defs&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;p&gt;The CSS code looks like this&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&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;1em&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;1em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;stroke-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;currentColor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;currentColor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.icon-github-brands&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;0.96875em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.icon-instagram-brands&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;0.875em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.icon-linkedin-brands&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;0.875em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.icon-arrow-down-solid&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;0.875em&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;/li&gt;
&lt;li&gt;&lt;p&gt;Add the SVG sprite to your HTML file body. Don't worry it's hidden so it will only appear when you call and use them. And add the CSS styles to your CSS file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Call your icons where you normally would use font icons. For example, I was able to wrap my inline SVG by my &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags this way.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"full-screen-hero__contents__socials__item"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://www.twitter.com/aotwits"&lt;/span&gt; &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"icon icon-twitter-brands"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;use&lt;/span&gt; &lt;span class="na"&gt;xlink:href=&lt;/span&gt;&lt;span class="s"&gt;"#icon-twitter-brands"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/use&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;code&gt;xlink:href&lt;/code&gt; value references the ID of your SVG icon from the sprite. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By handling unused CSS problems this way I was able to improve my performance and accessibility score by 20 points. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv2vtw428lc27d81c3g2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv2vtw428lc27d81c3g2i.png" alt="Improved performance"&gt;&lt;/a&gt;&lt;br&gt;
But that's not enough largest contentful paint still needs some work and like what the title says we will not stop until we get that hundo !! I will be back with some more solutions on Part 2. You can view the source code of this project on &lt;a href="https://github.com/abdulhamidOumer" rel="noopener noreferrer"&gt;github&lt;/a&gt; and view my site on &lt;a href="https://abdulhamid-dev.netlify.app/" rel="noopener noreferrer"&gt;netlify&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>webdev</category>
      <category>css</category>
    </item>
    <item>
      <title>Finish that side project — Building my portfolio site series </title>
      <dc:creator>Abdulhamid Oumer</dc:creator>
      <pubDate>Sun, 24 Jan 2021 16:27:30 +0000</pubDate>
      <link>https://dev.to/abdulhamidoumer/finish-that-side-project-building-my-portfolio-site-series-4e7i</link>
      <guid>https://dev.to/abdulhamidoumer/finish-that-side-project-building-my-portfolio-site-series-4e7i</guid>
      <description>&lt;p&gt;Disclaimer: This is my first blog post on DEV.to so bare with me.&lt;/p&gt;

&lt;p&gt;As a developer we all know that it's important to have a portfolio site up and running for yourself. I don't think anyone disagrees when I say that. So I decided to build myself one using Gatsby and Markdown. But in my opinion, having the idea for a project is just 0.1% of the job and we can give actually starting the project a percentage of about 10. Having good discipline and consistency also plays a huge role in completing the said project. All in all, I think we've all seen enough memes about starting new projects without actually finishing the one on hand. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9c984qkobvhw0p31e9mw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9c984qkobvhw0p31e9mw.jpg" alt="Finishing A Project Meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my experience, there were some clear reasons why I was procrastinating like crazy and starting other side projects. To list some of them down below: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thinking that I have to build the site in a fancy tech stack&lt;/li&gt;
&lt;li&gt;Thinking that I need to participate in many huge projects beforehand&lt;/li&gt;
&lt;li&gt;The idea that I need to finish all the parts before putting the site on production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After figuring out these problems the next obvious step would be to find a solution. Let's go through what I thought would solve some of them.&lt;/p&gt;

&lt;p&gt;First, to solve the issue with procrastination I decided to blog my experience in a series format. This means I will share with you some of the issues I face and also how I was able to solve them every Monday. Let's hope this keeps me disciplined. &lt;/p&gt;

&lt;p&gt;In regards to choosing the best stack, why not use the most simple and performant stack HTML5, CSS &amp;amp; Vanilla JavaScript. This way I will be able to grow my basic skills in using plain JavaScript and make the site highly performant. When the need comes for a personal blog I can easily migrate to Gatsby or any other technology. You can read more about vanilla javascript performance when compared to frameworks on &lt;a href="https://medium.com/javascript-in-plain-english/javascript-frameworks-performance-60f71d321693" rel="noopener noreferrer"&gt;this blog post&lt;/a&gt; by Louis Petrik. &lt;/p&gt;

&lt;p&gt;I don't think I also need to finish the whole site before publishing it, I can have a landing page with a small description about me and my social media links. Then push features as they are finished. Besides, having the site running as early as possible will help with domain age for SEO.&lt;/p&gt;

&lt;p&gt;Finally like what Mark Zuckerberg allegedly said based on the movie &lt;em&gt;The Social Network&lt;/em&gt;, "&lt;strong&gt;Let the hacking begin&lt;/strong&gt;"&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
