<?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: Vinay Krishnan</title>
    <description>The latest articles on DEV Community by Vinay Krishnan (@vnaydev).</description>
    <link>https://dev.to/vnaydev</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%2F810389%2F153484aa-6610-436a-9ec5-454e5ab9dd0b.jpeg</url>
      <title>DEV Community: Vinay Krishnan</title>
      <link>https://dev.to/vnaydev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vnaydev"/>
    <language>en</language>
    <item>
      <title>Progressive Web Apps : An introduction</title>
      <dc:creator>Vinay Krishnan</dc:creator>
      <pubDate>Mon, 09 Jan 2023 03:44:12 +0000</pubDate>
      <link>https://dev.to/vnaydev/progressive-web-apps-an-introduction-1k5j</link>
      <guid>https://dev.to/vnaydev/progressive-web-apps-an-introduction-1k5j</guid>
      <description>&lt;p&gt;The core idea behind building a PWA is to deliver the best user experience for normal web applications across all devices. When we access web apps through a browser, the overall experience never catches up with that offered by a native application. Hence, with the help of the available open web technologies, PWAs provide an augmented web experience for users who use the most modern version of their browsers on par with the OS dependent applications like android, iOS or windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  What makes it so cool…
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;It can be accessed from any device having modern browsers.&lt;/li&gt;
&lt;li&gt;It can be visited, shared and bookmarked like a normal website.&lt;/li&gt;
&lt;li&gt;It works offline.&lt;/li&gt;
&lt;li&gt;It can be installed just like any other native app with home screen shortcuts.&lt;/li&gt;
&lt;li&gt;It can handle push notifications.&lt;/li&gt;
&lt;li&gt;It can access the hardware features of the device like camera, Bluetooth etc.&lt;/li&gt;
&lt;li&gt;While developing native apps, we need to maintain a single codebase for each platform but developing PWA demands only a single codebase. Hence, it reduces the maintainability.&lt;/li&gt;
&lt;li&gt;Native apps constantly remind users of new updates. While PWAs automatically updates the content in the background with a simple page refresh.&lt;/li&gt;
&lt;li&gt;By applying proper SEO techniques, PWAs can be indexed by search engines and hence can widen the app’s visibility.&lt;/li&gt;
&lt;li&gt;Compared to native apps, the time required for developing PWAs is very less. Hence, it reduces the developmental cost by large folds.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Relevance
&lt;/h3&gt;

&lt;p&gt;Pinterest’s website was old and had poor web performance. From analytics, they realized the difficulty in elevating the user base especially as the number of unauthenticated web users were large. Hence, after 3 months they rebuilt the existing web app using React and converted into a PWA which saw a massive growth in their business. They were also successful in reducing the bundle size of the web app which led to a drastic change in the CPU performance as well. &lt;/p&gt;

&lt;p&gt;As a result, the time spent by users on the platform increased by 40% and the revenue generated by advertisements shot up to 44%. &lt;/p&gt;

&lt;h3&gt;
  
  
  Building blocks of a PWA
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Responsive&lt;/strong&gt; : Since PWA offers cross device compatibility, it must be responsive across all devices. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service worker&lt;/strong&gt; : This is a script file that asynchronously runs tasks in the background without compromising on the page performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS&lt;/strong&gt; : since PWA requires a service worker, it must be hosted from HTTPS endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manifest&lt;/strong&gt; : This is a json file where we can include all the metadata associated with our app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s dig a little deeper…&lt;/p&gt;

&lt;h3&gt;
  
  
  Service worker
&lt;/h3&gt;

&lt;p&gt;The service worker is responsible for ensuring that the PWA is reliable and independent of the network status. &lt;/p&gt;

&lt;p&gt;It can access the cache from the client side and can store data such as static assets that don't need to be fetched over and over again like stylesheets, html, images etc. This enables the PWA to load only the necessary data during offline mode. It can thereby reduce the page loading latency and can improve the overall performance as well. &lt;/p&gt;

&lt;p&gt;We can also enable the service worker to listen for events that occur during network changes and can serve, modify or intercept the network requests within the application in a dynamic manner.&lt;/p&gt;

&lt;p&gt;In short, the two main features of a PWA such as the one time installation and caching is done using the service worker script. It can also be used to handle push notifications when the user is not using the website.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTPS
&lt;/h3&gt;

&lt;p&gt;PWAs must be served with HTTPS protocol because of the following reasons :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Service worker demands an HTTPS connection.&lt;/li&gt;
&lt;li&gt;Secures privacy of the user&lt;/li&gt;
&lt;li&gt;Assures the authenticity of the content&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Manifest file
&lt;/h3&gt;

&lt;p&gt;This is a json file that contains all the necessary metadata regarding the PWA. This file also makes the PWA installable across devices. This metadata includes the title of our app, theme color, manner in which it should be displayed, adding logos etc. Once we have created the manifest.json file, we can link it in the head tag of our html file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;To sum up, PWAs have shortened the gap between web apps and native apps. Without a doubt, we can say that PWAs are the future of web apps. Now that many companies across the world are converting their web apps to PWAs assures the fact that it is going to be a path breaker in the software industry.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>3 ways to load a script file</title>
      <dc:creator>Vinay Krishnan</dc:creator>
      <pubDate>Sun, 10 Apr 2022 12:28:19 +0000</pubDate>
      <link>https://dev.to/vnaydev/3-ways-to-load-a-script-file-2dn</link>
      <guid>https://dev.to/vnaydev/3-ways-to-load-a-script-file-2dn</guid>
      <description>&lt;p&gt;There are 3 ways to add script files in our HTML page. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using normal script tags without any attributes.&lt;/li&gt;
&lt;li&gt;Using async keyword.&lt;/li&gt;
&lt;li&gt;Using defer keyword.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In all of the above 3 cases, the script tags are placed inside the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of the HTML.&lt;/p&gt;

&lt;p&gt;To start off, let’s create a boilerplate HTML code with a button inside the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;.&lt;br&gt;
Next, create a script file (say one.js) and link the external script on the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of HTML.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Inside the script file one.js, &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a function (say display)&lt;/li&gt;
&lt;li&gt;Inside the function add a &lt;code&gt;console.log(“hello world”)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Declare a querySelector to access the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; from the DOM.&lt;/li&gt;
&lt;li&gt;Assign that to a variable (say button) and log it onto the console.&lt;/li&gt;
&lt;li&gt;Now, try to modify the &lt;code&gt;innerText&lt;/code&gt; of that button.&lt;/li&gt;
&lt;li&gt;Last, call the function on top of the script.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now, in the console we get the following error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--saNtHHns--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1kedbuoy2fas4yytjnjp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--saNtHHns--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1kedbuoy2fas4yytjnjp.jpg" alt="alt text" width="736" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why did we get the error?&lt;/p&gt;

&lt;p&gt;Browser parses the HTML from top to bottom. Here, we have declared our script file on the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of HTML. When the parser hits the script tag, the HTML parsing is stopped. The control goes to the script file and the function gets invoked. After the console log gets printed, when it tries to access the button from the DOM, it fails to find it as it is still not rendered yet. Hence, it displays null. And the line for modifying the &lt;code&gt;innerText&lt;/code&gt; also throws an error eventually.&lt;br&gt;
In short, the script files block the rendering of the HTML because the parsing happens sequentially. &lt;/p&gt;

&lt;p&gt;How to get rid of this error?&lt;/p&gt;

&lt;p&gt;Place the script tag at the bottom of the HTML. Now, the script file is accessed and executed at the end after the browser has rendered the entire necessary HTML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using async attribute&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Place the script tag at the head of the HTML itself. But, now add an attribute named ‘async’ along with the script tag. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here, we don’t get any errors. This is because adding the async keyword asynchronously fetches the script files as and when the HTML parsing happens. But the HTML parsing resumes only after the script files have finished executing. We cannot predict the speed of execution of script files and rendering of HTML once we add the async keyword. &lt;/p&gt;

&lt;p&gt;So when should we avoid using it?&lt;/p&gt;

&lt;p&gt;When we want to load multiple script files that have dependency on each other, it might be better if we stay away from using async keywords because the order of execution of scripts is not guaranteed.&lt;/p&gt;

&lt;p&gt;So when should we use it?&lt;/p&gt;

&lt;p&gt;When we want to load a script which is independent from the rest of the script files added, its okay to use async because the order of execution does not matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using the defer keyword&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Place the script tag at the head of the HTML itself. But, now add an attribute named ‘defer’ along with the script tag. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This behaves exactly similar to the situation where we embed the script tag at the bottom of the HTML page.&lt;/p&gt;

&lt;p&gt;When defer keyword is used, the script files are fetched parallely with the HTML parsing. And the scripts will be executed only when the HTML parsing is finished. &lt;/p&gt;

&lt;p&gt;When should we use it?&lt;/p&gt;

&lt;p&gt;We can use it when we want to add multiple script files that are dependent on each other. If we have the habit of embedding script tags at the head section of the HTML page, it would be better to use defer keyword.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Move zeroes</title>
      <dc:creator>Vinay Krishnan</dc:creator>
      <pubDate>Sat, 26 Mar 2022 17:38:47 +0000</pubDate>
      <link>https://dev.to/vnaydev/move-zeroes-3o00</link>
      <guid>https://dev.to/vnaydev/move-zeroes-3o00</guid>
      <description>&lt;p&gt;Leetcode problem : &lt;a href="https://leetcode.com/problems/move-zeroes/"&gt;https://leetcode.com/problems/move-zeroes/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brute force solution&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;We can solve this question using two for loops.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialize a variable (say count) equal to 0.&lt;/li&gt;
&lt;li&gt;Start a for loop from 0 to array.length&lt;/li&gt;
&lt;li&gt;If we come across a non-zero element,

&lt;ul&gt;
&lt;li&gt;Insert the current element to index = count of the array.&lt;/li&gt;
&lt;li&gt;Increment count.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Start the second loop from count to array.length&lt;/li&gt;
&lt;li&gt;In the body, keep inserting 0 to each current location as it iterates.&lt;/li&gt;
&lt;li&gt;Return array&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Optimized solution&lt;/strong&gt; :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialize a variable (say count) equal to 0.&lt;/li&gt;
&lt;li&gt;Start a for loop from 0 to array.length&lt;/li&gt;
&lt;li&gt;If we come across a non-zero element,

&lt;ul&gt;
&lt;li&gt;Swap the current element with the element at index = count of the array.&lt;/li&gt;
&lt;li&gt;Increment count.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Return array&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>javascript</category>
      <category>leetcode</category>
      <category>beginners</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Two Sum</title>
      <dc:creator>Vinay Krishnan</dc:creator>
      <pubDate>Sat, 26 Mar 2022 11:01:27 +0000</pubDate>
      <link>https://dev.to/vnaydev/two-sum-2naj</link>
      <guid>https://dev.to/vnaydev/two-sum-2naj</guid>
      <description>&lt;p&gt;Leetcode problem : &lt;a href="https://leetcode.com/problems/two-sum/"&gt;https://leetcode.com/problems/two-sum/&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Brute force solution&lt;/strong&gt; : &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fix the first pointer to the first element of the array. &lt;/li&gt;
&lt;li&gt;We assume that this element is the first number in our output pair.&lt;/li&gt;
&lt;li&gt;Now to find the next number of the pair, we can take the difference between the target and the element pointed by the first pointer (first element). &lt;/li&gt;
&lt;li&gt;Now to find the location of the second element, take a second pointer and iterate from the second index of the array till its end.&lt;/li&gt;
&lt;li&gt;If found, we can return the index of both the elements (values of both the pointers).&lt;/li&gt;
&lt;li&gt;Else, we increment the first pointer and take its difference with the target.&lt;/li&gt;
&lt;li&gt;Then we iterate the second pointer from the third index till the end of the array.&lt;/li&gt;
&lt;li&gt;This can be implemented using two for loops and hence takes O(n^2).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Optimized solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We can use an object (or hash map). 
Why?  Because we can fetch an item from objects at O(n) complexity which is more efficient.&lt;/li&gt;
&lt;li&gt;Our aim is to implement this solution in a single for loop.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Intuition&lt;/strong&gt; : &lt;/p&gt;

&lt;p&gt;As we iterate through each element in the array, &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We need to keep track of the elements that we previously iterated. Hence, we can store the previous elements along with their indices in an object. &lt;/li&gt;
&lt;li&gt;We are simultaneously calculating the difference of that current element with the target. We then check whether the object(acts like a store) already has that difference (which is the second number in the output pair). &lt;/li&gt;
&lt;li&gt;If yes, return the value corresponding to the difference in the object (first index) and the current pointer (second index) from the loop as an array.&lt;/li&gt;
&lt;li&gt;If not found, store the current element and the pointer value(which is its index) as a key value pair in the object. As it had become a part of the previously tracked elements. &lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>leetcode</category>
      <category>algorithms</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
