<?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: JSGuru</title>
    <description>The latest articles on DEV Community by JSGuru (@jsguru_io).</description>
    <link>https://dev.to/jsguru_io</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%2Forganization%2Fprofile_image%2F159%2F4b936035-21ca-4a21-ba9d-6217941e049d.png</url>
      <title>DEV Community: JSGuru</title>
      <link>https://dev.to/jsguru_io</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jsguru_io"/>
    <language>en</language>
    <item>
      <title>Go for PHP or Any Other Developer</title>
      <dc:creator>Sasha Blagojevic</dc:creator>
      <pubDate>Mon, 27 Jan 2020 10:23:01 +0000</pubDate>
      <link>https://dev.to/jsguru_io/go-for-php-or-any-other-developer-4jbb</link>
      <guid>https://dev.to/jsguru_io/go-for-php-or-any-other-developer-4jbb</guid>
      <description>&lt;p&gt;&lt;span&gt;Long time no read! I’ve been quite busy building awesome stuff for our clients so I haven’t had the time to write in quite a while. I still don’t have it to be frank, but this is gonna be a somewhat short read so I managed to squeeze it into my schedule.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="h.i61btza3x0es"&gt;&lt;span&gt;TLDR&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;If you’re not interested in the story behind this &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; just skip to the end. I highly recommend covering these resources if you’re considering learning&lt;/span&gt;&lt;span&gt; GO.&lt;/span&gt;&lt;sup&gt;[c]&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id="h.nzbnrmddxobs"&gt;&lt;span&gt;Why Go suddenly?&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;I’ve been helping out on an awesome big data / IoT project which is powered by none other then GO! Our client was coming from a Python background and when you add the terms Big Data and Internet of Things to this mix you can clearly see why GO is a natural fit for this project. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;It has been really interesting switching from PHP to Go lang. I must admit at the beginning it was a bit of a challenge to wrap my head around all of the different concepts. Not only was I switching from a scripting language to a compiled one, but Go lang is also a functional language, where as PHP supports both the &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://sasablagojevic.com/object-oriented-programming&amp;amp;sa=D&amp;amp;ust=1580123772171000"&gt;Functional&lt;/a&gt;&lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://sasablagojevic.com/object-oriented-programming&amp;amp;sa=D&amp;amp;ust=1580123772171000"&gt; and &lt;/a&gt;&lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://sasablagojevic.com/object-oriented-programming&amp;amp;sa=D&amp;amp;ust=1580123772172000"&gt;Object Oriented Paradigm&lt;/a&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;To add fuel to the fire GO lang has its own twist with its concurrency model - &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://gobyexample.com/goroutines&amp;amp;sa=D&amp;amp;ust=1580123772172000"&gt;goroutines&lt;/a&gt;&lt;/span&gt;&lt;span&gt; and &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://gobyexample.com/channels&amp;amp;sa=D&amp;amp;ust=1580123772172000"&gt;channels&lt;/a&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;When your client demands GO lang as the power train you can be pretty sure it’s not going to be a walk in the park, you can expect it to be a high performance / high load type of a project so there will be no cutting corners and optimization needs to be on your mind all the time!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I’d consider my role in this project as kind of a sheepdog since I was setting the path and guiding our junior developers as they do tend to behave like lost sheep sometimes. Client being the shepherd in this analogy I guess lol.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="h.mzc1zd1v7tsl"&gt;&lt;span&gt;Major Differences between PHP and GO&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Aside from the obvious fact that GO is a compiled language these are some of the major differences: &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;span&gt;Switch&lt;/span&gt;&lt;span&gt; statement does not fall through by default, you have to explicitly add the fallthrough keyword&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;span&gt;For&lt;/span&gt;&lt;span&gt; is the same as &lt;/span&gt;&lt;span&gt;While&lt;/span&gt;&lt;span&gt;, that’s the only loop keyword&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;span&gt;There are no Classes / Objects, there are &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://gobyexample.com/structs&amp;amp;sa=D&amp;amp;ust=1580123772174000"&gt;Structs&lt;/a&gt;&lt;/span&gt;&lt;span&gt; which have some of the behaviour, they can have members and methods defined on them&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;span&gt;There are no explicit access modifiers like &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://www.php.net/manual/en/language.oop5.visibility.php&amp;amp;sa=D&amp;amp;ust=1580123772174000"&gt;public, protected and private&lt;/a&gt;&lt;/span&gt;&lt;span&gt; but there is a naming convention&lt;/span&gt;&lt;span&gt;. If you declare a variable / type  / function lowercase first it will be treated as private on the package level, if you define a member / method lowercase first on a Struct it will not be accessible publicly. On the other hand if you write them uppercase first it will be publicly accessible.&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;span&gt;Since there are no Classes there is no Inheritance, but we can achieve Polymorphism because GO has &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go&amp;amp;sa=D&amp;amp;ust=1580123772175000"&gt;Interfaces&lt;/a&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;span&gt;Interfaces in GO have their own twist and are a bit different than in PHP. While in PHP you have to specify which class implements what interface in GO every data type implements an empty interface{} by default. You can think of this interface{} as something similar to &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://www.typescriptlang.org/docs/handbook/basic-types.html%23any&amp;amp;sa=D&amp;amp;ust=1580123772175000"&gt;TypeScript’s any&lt;/a&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt; When you create your own custom interfaces you will need to add the implementation of these methods on the desired structs. GO will not check if the interfaces are satisfied during the build process, unlike some other compiled languages, it will be evaluated during runtime when the actual method is called, if you call the method on a &lt;/span&gt;&lt;span&gt;Struct&lt;/span&gt;&lt;span&gt; that does not satisfy the type hinted &lt;/span&gt;&lt;span&gt;Interface&lt;/span&gt;&lt;span&gt; your application will fail.&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;span&gt;There are no exceptions in a traditional sense, there are no try / catch blocks although there is a &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://github.com/golang/go/issues/32437&amp;amp;sa=D&amp;amp;ust=1580123772176000"&gt;proposal to introduce try&lt;/a&gt;&lt;/span&gt;&lt;span&gt;. What we have though are &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://blog.golang.org/defer-panic-and-recover&amp;amp;sa=D&amp;amp;ust=1580123772176000"&gt;panics and recover&lt;/a&gt;&lt;/span&gt;&lt;span&gt;, but recover can only be used to recover from a panic that happened on different goroutine. How do we handle errors then? Well, GO functions have multiple return values. Usually the first value is the desired result and the second value is the error if there is any, otherwise nil. &lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;I’m of the opinion that each language should be written in its idiomatic way, that is the way to get the most out of the language and in addition your code will be easily understandable by the wider community and new developers that might join you or replace you later on. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;That’s the whole point behind language style guides, admittedly some have a more strict some less, some don’t have one at all - PHP didn’t have one for a long time before PSRs came into play and our community was honestly a mess, a million of different styles and approaches that just unnecessarily added to our cognitive load. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;That being said this is a list of resources that you most definitely should read if you want to write idiomatic Go and follow community best practices:&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="h.n614kz22bv9f"&gt;&lt;span&gt;Must Read / Watch List&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;1. &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://github.com/golang/go/wiki/CodeReviewComments%23package-names&amp;amp;sa=D&amp;amp;ust=1580123772178000"&gt;Official Go Code Review Comments&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;2. &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://github.com/golang-standards/project-layout&amp;amp;sa=D&amp;amp;ust=1580123772178000"&gt;Go Standard Project Layout (Community)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;. &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1&amp;amp;sa=D&amp;amp;ust=1580123772178000"&gt;Ben Johnson - Standard Package Layout (Community)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;. &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://blog.golang.org/package-names&amp;amp;sa=D&amp;amp;ust=1580123772179000"&gt;Go Docs - Package Naming&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;. &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://peter.bourgon.org/go-best-practices-2016/&amp;amp;sa=D&amp;amp;ust=1580123772179000"&gt;Peter Bourgon - Go Best Practices Six Years In (QCon London 2016)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;. &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://peter.bourgon.org/go-for-industrial-programming/&amp;amp;sa=D&amp;amp;ust=1580123772180000"&gt;Peter Bourgon - Go For Industrial Programming (GopherCon EU 2018)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;7&lt;/span&gt;&lt;span&gt;. &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://www.youtube.com/watch?v%3DMzTcsI6tn-0&amp;amp;sa=D&amp;amp;ust=1580123772180000"&gt;Ashley McNamara + Brian Ketelsen. Go best practices (GopherCon Russia 2018)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt;. &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://talks.golang.org/2014/names.slide%231&amp;amp;sa=D&amp;amp;ust=1580123772180000"&gt;Andrew Gerrard GoLand Talks 2014 (Google)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;9&lt;/span&gt;&lt;span&gt;. &lt;/span&gt;&lt;span&gt;&lt;a href="https://www.google.com/url?q=https://talks.golang.org/2014/organizeio.slide%231&amp;amp;sa=D&amp;amp;ust=1580123772180000"&gt;David Crawshaw - Organizing Go Code 2014 (Google)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>php</category>
    </item>
    <item>
      <title>PHP Serbia was a blast</title>
      <dc:creator>Sasha Blagojevic</dc:creator>
      <pubDate>Tue, 28 May 2019 23:59:19 +0000</pubDate>
      <link>https://dev.to/jsguru_io/php-serbia-was-a-blast-3fn7</link>
      <guid>https://dev.to/jsguru_io/php-serbia-was-a-blast-3fn7</guid>
      <description>&lt;p&gt;&lt;em&gt;Originaly published at &lt;a href="https://sasablagojevic.com/php-serbia-was-a-blast"&gt;sasablagojevic.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It's time we talked about the phelephant in the room. *Ba Dum Tss! Get it? This is double wordplay, elephant in the room and php + elephant == phelephant. Ok, I'm gonna stop now...&lt;/p&gt;




&lt;p&gt;I wanted to summarise my impressions after the &lt;a title="PHP Serbia 2019 conference" href="https://2019.phpsrbija.rs/" rel="noopener"&gt;PHP Serbia 2019 conference&lt;/a&gt; since this was my first time attending. I thought it might be helpful to those people who are on the fence whether it's worth visiting it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR &lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;&lt;strong&gt;PHP Serbia 2019 line-up&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The line-up&lt;/strong&gt; and the topics covered were all really good. &lt;a title="Zeev Suraski" href="https://twitter.com/zeevs" rel="noopener"&gt;Zeev Suraski&lt;/a&gt; was this year's keynote and he gave us an overview of the PHP since he joined the band of brothers known as &lt;em&gt;php internals devs&lt;/em&gt; and more importantly all the cool stuff that will be included in the upcoming php7.4 and php8. Yep guys, php8 will be coming hopefully by the end of 2020. Oh how the time flies by, I mean I haven't been in this game that long and I witnessed the amazing evolution from php5 to php8.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ow_GEkXo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sasablagojevic.com/img/content/139/zeev.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ow_GEkXo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sasablagojevic.com/img/content/139/zeev.jpg" width="880" height="1062"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I said, all the talks were good but the ones that stood out to me and I recommend you watch when the organizers share the videos are the following (in no particular order):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Hello my name is "if"  &lt;/em&gt;by &lt;a href="https://twitter.com/movetodevnull" rel="noopener"&gt;Sebastian Feldman&lt;/a&gt;, not only did he dance like a madman and put Michael Jackson to shame, but he also gave us a low-level insight and deeper understanding of how different types of if statements work under the hood in php, yes you might have thought that a ternary if statement is just a shorthand way of writing a regular if statement, but when it gets converted to &lt;a title="Zend Opcodes" href="https://x-team.com/blog/learn-about-php-opcodes/" rel="noopener"&gt;opcodes&lt;/a&gt; it's actually not, and the same goes for using the null coalescing statement.&lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Git legit&lt;/em&gt;  by &lt;a href="https://twitter.com/vanamerongen" rel="noopener"&gt;Pauline Vos&lt;/a&gt; explained the difference between &lt;strong&gt;git rebase&lt;/strong&gt; and &lt;strong&gt;git merge&lt;/strong&gt; strategies in an easily digestible way, even by dummies like myself. Now we can finally put this feud to rest and just pick one that aligns with us philosophically because this is the same shit as OOP vs FP, one is not better than the other they both have their trade-offs. There is no silver bullet in software development no matter how strong we try to find it!&lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;You're not a {framework} developer! - &lt;/em&gt;if you are a Symfony or Laravel fanboy you might strongly disagree with this one :D, but &lt;a href="https://twitter.com/tdutrion" rel="noopener"&gt;Thomas Dutrion&lt;/a&gt; gave a good starting point on how to abstract and protect ourselves from the framework. There were some really good examples for both Symfony and Laravel frameworks on how to abstract at both the &lt;em&gt;Model&lt;/em&gt; and &lt;em&gt;Controller&lt;/em&gt; level. &lt;span&gt;Our domain logic shouldn't know about our infrastructure (framework)&lt;/span&gt;, this is my key takeaway from this talk, at least that's how I understood it and it makes perfect sense to me now. For those of you who are saying &lt;em&gt;But how often do we change a framework&lt;/em&gt;? we are not necessarily going to change the framework itself but we need to protect ourselves from future updates of &lt;em&gt;our framework&lt;/em&gt; as well. Each major version will have breaking changes and choosing not to update will compromise both performance and security of our codebase - that's how we get legacy codebases that everybody hates working with.&lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Making architecture explicit  &lt;/em&gt;by &lt;a href="https://twitter.com/hgraca" rel="noopener"&gt;Herberto Graca&lt;/a&gt;, we all know that organizing code and folders can be a pain in the ass and a huge liability if done poorly. Well, Herberto had some great charts and breakdowns on organizing code the &lt;a title="Domain Driven Development" href="https://medium.com/the-coding-matrix/ddd-101-the-5-minute-tour-7a3037cf53b8" rel="noopener"&gt;DDD&lt;/a&gt; way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I highly suspect that &lt;a href="https://twitter.com/@marcelpociot" rel="noopener"&gt;Marcel Pociot's&lt;/a&gt; talk &lt;em&gt;Getting started with WebSockets&lt;/em&gt; and &lt;a href="https://twitter.com/@faguo" rel="noopener"&gt;Damien Seguy's&lt;/a&gt; &lt;em&gt;T&lt;/em&gt;&lt;em&gt;op 10 PHP coding traps&lt;/em&gt; were awesome as well but unfortunately, I did not attend them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1qZCercY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sasablagojevic.com/img/content/139/IMG_0263.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1qZCercY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sasablagojevic.com/img/content/139/IMG_0263.jpg" width="880" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is me winning a free ticket for PHPSerbia 2020 and a Phelephant on the conf quiz :D&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;Venue and organization&lt;/h3&gt;

&lt;p&gt;The venue is a big theater in &lt;a title="Zemun" href="https://theculturetrip.com/europe/serbia/articles/top-10-things-to-see-and-do-in-zemun-serbia/" rel="noopener"&gt;Zemun&lt;/a&gt;, there were two tracks A and B, B being the smaller one obviously. Well, it was quite smaller compared to A, so what happened was that all the people that were interested in a talk at track B could not fit in or chose not to stand. This only happened two times though. Gauging the audience's interest and which speaker should get the short stick end is tricky, so maybe, as Damien Seguy suggested, attendees could vote somehow, when the lineup is known, which talks they're interested in so the organizers at least have some estimate. &lt;/p&gt;

&lt;p&gt;There were food and beverages in abundance. I was well fed and watered like a plant xD. I must highlight that the food was really tasty and the Conferences' craft beer as well. What I also really liked compared to other conferences I attended (that being &lt;a title="Webcamp Zagreb" href="https://2019.webcampzg.org/" rel="noopener"&gt;Webcamp Zagreb&lt;/a&gt; times two lol) they had a real espresso machine so I could get my daily 37 doses of macchiato, yes I'm an addict and I'm not ashamed. I basically didn't spend a dime the whole day throughout the conference there was really no need to.&lt;/p&gt;

&lt;p&gt;In general, the organizers did a great job and they were very welcoming, &lt;span&gt;you just felt at home from day one&lt;/span&gt;. &lt;/p&gt;

&lt;p&gt;My only pet peeve is that maybe the talks could be a bit shorter so we have a small pause in between them to reset our brains, chit-chat, drink a coffee or whatevz or maybe I'm just spoiled by WebcampZg.&lt;/p&gt;

&lt;h3&gt;Final verdict&lt;/h3&gt;

&lt;p&gt;I give it a solid &lt;strong&gt;9/10&lt;/strong&gt; just because I'm afraid if I gave them 10 they'll get lazy. Now is the time for you to stop thinking and start preparing for the next one!&lt;/p&gt;

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

&lt;p&gt;P.S. Thanks to my company &lt;a title="JSGuru - Your reliable software development partner" href="https://jsguru.io" rel="noopener"&gt;JSGuru&lt;/a&gt; for paying the ticket, I mean who doesn't like free stuff! &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originaly published at &lt;a href="https://sasablagojevic.com/php-serbia-was-a-blast"&gt;sasablagojevic.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>webdev</category>
      <category>conference</category>
    </item>
    <item>
      <title>Improve Your Ionic App Performance</title>
      <dc:creator>Boris Joskic</dc:creator>
      <pubDate>Thu, 07 Feb 2019 14:46:11 +0000</pubDate>
      <link>https://dev.to/jsguru_io/improve-your-ionic-app-performance-2p2j</link>
      <guid>https://dev.to/jsguru_io/improve-your-ionic-app-performance-2p2j</guid>
      <description>&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0041lc9rkx1igqj7cfst.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0041lc9rkx1igqj7cfst.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ionic allows developers to build mobile applications using web technologies and allows access to native features such as file storage, camera, flashlight and many more. The first version was released in 2013 and built using Apache Cordova and AngularJS but recent versions, while still using Apache Cordova, are using Angular instead of AngularJS.&lt;/p&gt;

&lt;p&gt;The most recent version of Ionic, version 4, includes performance improvements but in my opinion, it’s still having a tough time competing with the performance of native apps, or even React Native.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Make a production build&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This might be an obvious one. While developing and testing, we usually build debug versions of the app. How many times have you build an apk and after installing you realized it’s a debug apk? I’ve done it... a couple of times.&lt;/p&gt;

&lt;p&gt;The default build command will generate a debug apk which does not have optimized code.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ionic cordova build android --prod --release&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;command will do the trick. It will generate a production-ready apk with minified and optimized code.&lt;/p&gt;

&lt;p&gt;Consider this first tip more like a reminder..&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Add a Service Worker&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Adding a Service Worker to an Ionic app has its benefits. One of them is that it can cache your static assets so your app can load faster. Not only can it cache your app’s static assets, but it can also cache some data from the API? That probably has some use.&lt;/p&gt;

&lt;p&gt;Ionic has built-in support for service workers and adding it is pretty easy.&lt;/p&gt;

&lt;p&gt;If you are interested, you can get more information in their documentation.&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%2Fdelivery.eusi.cloud%2Fapi%2Fv1%2Ff1a4305c-e431-4668-ae4c-02f78c656a41%2Fmedia%2Fs3%2F1549549262275_190206-18-2-Cache.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%2Fdelivery.eusi.cloud%2Fapi%2Fv1%2Ff1a4305c-e431-4668-ae4c-02f78c656a41%2Fmedia%2Fs3%2F1549549262275_190206-18-2-Cache.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Native Page Transitions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;By default, when switching to a different page, Ionic will use CSS animations to switch between views. This works fine mostly, but you may notice lags sometimes on devices with lower specs and also it’s not very customizable.&lt;/p&gt;

&lt;p&gt;To solve this problem, you should switch to Native Page Transitions which uses native hardware device acceleration to animate transitions.&lt;/p&gt;

&lt;p&gt;From my experience, performance is improved and the app feels much more native.&lt;/p&gt;

&lt;p&gt;It’s supported on Android, iOS and Windows Mobile and you can start using it pretty quickly.&lt;/p&gt;

&lt;p&gt;Regarding the customization, you can change the swipe direction, duration, delay in Android and iOS and more.&lt;/p&gt;

&lt;p&gt;You can get more information in their &lt;a href="https://ionicframework.com/docs/native/native-page-transitions/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Use Virtual Scroll and Infinite Scroll&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you are working with a list, you are probably using the Ionic list component which is completely fine and will offer native UI depending on the platform.&lt;/p&gt;

&lt;p&gt;However, if you have a large list you may notice some sluggishness. To get rid of that, you can start using Virtual Scroll and Infinite Scroll.&lt;/p&gt;

&lt;p&gt;Infinite Scroll is just an Ionic component with the infinite scroll logic. It will call a certain action when user reaches the end of the list. It’s great for pagination as you can load a certain number of items, and when needed load more and append it to the original list. It also offers customization of the loading indicator where you can change the text and spinner.&lt;/p&gt;

&lt;p&gt;Virtual scroll will take full list of the array, but only render items that are currently visible which can greatly improve performance. As the user scrolls, views are reused but are filled with different data depending of the row.&lt;/p&gt;

&lt;p&gt;When should you use Virtual Scroll?&lt;/p&gt;

&lt;p&gt;When you have a somewhat larger amount of data but do not need the Infinite scroll option(eg. all data is loaded in one API call), you can use it and it will greatly benefit you!&lt;/p&gt;

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

&lt;p&gt;Great performance does not come by default in Hybrid apps no matter which starter kit you use. Before trying any performance optimization tricks, do not forget to optimize your own code, remove unused imports and CSS and optimize your images! Even the small stuff can make a difference.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before you go…
&lt;/h3&gt;

&lt;p&gt;If you enjoyed reading this post please &lt;strong&gt;share&lt;/strong&gt; it. You should check out our other publications, you might like them too! We write from time to time about software development, tips and tricks, and how to become a better developer and business person in general. Join us on the journey of constant improvement!&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://www.facebook.com/jsguruio/" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;, &lt;a href="https://twitter.com/jsguru_software" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.linkedin.com/company/jsguru" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/jsguru" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; or &lt;a href="https://dev.to/jsguru_io"&gt;DEV.to&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://jsguru.io/blog/improve-your-ionic-app-performance" rel="noopener noreferrer"&gt;&lt;em&gt;jsguru.io&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ionic</category>
      <category>mobileappdevelopment</category>
      <category>ionicframework</category>
      <category>angular</category>
    </item>
    <item>
      <title>Why You Should Care What You Npm Install</title>
      <dc:creator>Sasha Blagojevic</dc:creator>
      <pubDate>Thu, 20 Dec 2018 13:36:52 +0000</pubDate>
      <link>https://dev.to/jsguru_io/why-you-should-care-what-you-npminstall-267c</link>
      <guid>https://dev.to/jsguru_io/why-you-should-care-what-you-npminstall-267c</guid>
      <description>&lt;p&gt;As if we haven't learned anything from the &lt;em&gt;&lt;a href="https://qz.com/646467/how-one-programmer-broke-the-internet-by-deleting-a-tiny-piece-of-code/" rel="noopener noreferrer"&gt;Left-pad&lt;/a&gt;&lt;/em&gt; debacle on November 26th the Javascript world was shaken once again.&lt;/p&gt;




&lt;p&gt;A popular Npm library with over 2 million installs had a backdoor. Wait, what?! Yep, you heard it correctly the &lt;em&gt;&lt;a href="https://github.com/dominictarr/event-stream/issues/116" rel="noopener noreferrer"&gt;event-stream&lt;/a&gt;&lt;/em&gt; library which was not archived at that time and was used all over the place from your garage script kiddie to enterprise systems was infected with an obnoxious back-door, a crypto miner /stealer/something. From now on we will call it the C - virus for dramatic effect.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Damn crypto hype, it's high time the bubble burst and let us go on with our lives. - &lt;a href="https://twitter.com/blackcat_dev" rel="noopener noreferrer"&gt;Me&lt;/a&gt;, December 2018&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But, how did it happen? Well, a combination of unfortunate circumstances and the author's faith in people led us here where we are today.&lt;br&gt;
The author stopped using and maintaining the library a long time ago. Since it wasn't archived over time it became a dependency of many projects and lo and behold one day a good Samaritan slid into his inbox and offered to take the burden of maintaining the library upon himself and to carry the torch onwards, but he was not good, was he now.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1067124100332744704-828" src="https://platform.twitter.com/embed/Tweet.html?id=1067124100332744704"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1067124100332744704-828');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1067124100332744704&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;The author transferred the rights of the Npm module to this kind stranger but left the module's code on his Github account since there were some problems with name conflict when he tried to transfer it to the stranger's account, or so he says, but I suppose they weren't accidental either. This Samaritan was one nefarious schemer.&lt;br&gt;
As soon as he got hold of the library he removed the publishing rights of the old author, added the &lt;code&gt;flatmap-stream&lt;/code&gt; module which contained the C-virus, did a minor version bump and finally a new release on Npm.&lt;br&gt;
The event-stream library was updated to the new minor version all over the world.&lt;br&gt;
As soon as he planted the C-virus, he removed the &lt;code&gt;flatmap-stream&lt;/code&gt; module from the library and then he did a major version bump and once again a new release on Npm. Quite smart isn't it? Now there was nothing suspicious in the codebase but since it was a major version update most of the systems wouldn't update to it because they are version locked to the previous major version thus they would still have the infected code.&lt;br&gt;
Even one of my coworkers got infected, barely anyone noticed, but Kevin Beaumont.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1067125660014051330-270" src="https://platform.twitter.com/embed/Tweet.html?id=1067125660014051330"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1067125660014051330-270');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1067125660014051330&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;That was a brief summary and I probably missed a step or two but you get the picture.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;SHORT NOTICE:&lt;/strong&gt;&lt;br&gt;
We shouldn't blame the author, he probably didn't really think it through that much but maintaining open source software is a real hassle and can be really mentally draining on the authors, especially in today's entitled society where people expect everything for nothing. So let's not put the blame on him.&lt;/p&gt;



&lt;p&gt;Now let's get back on track! Oh, here's another gem by Kevin Beaumont&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1067130326395351040-919" src="https://platform.twitter.com/embed/Tweet.html?id=1067130326395351040"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1067130326395351040-919');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1067130326395351040&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Hallelujah, praise the Lord! Preach! People didn't come up with this meme for no reason:&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AxMYsLPXMT02nL83x3Qbp6w.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AxMYsLPXMT02nL83x3Qbp6w.png" alt="Npm modules"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways from this mess:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sometimes we take for granted and don't think what we Npm install/composer require/yarn add&lt;/li&gt;
&lt;li&gt;Developers have become lazy. We have started taking "don't reinvent the wheel too literally", instead of writing a few extra lines we'd rather require a library, sometimes even for the most trivial of tasks (especially in the Javascript World this seems to be the trend)&lt;/li&gt;
&lt;li&gt;You should always put careful thought in what you require as a dependency, more dependencies can sometimes mean more technical debt&lt;/li&gt;
&lt;li&gt;Add a layer of abstraction and design an interface as a bridge/adapter between your domain logic and libraries, so you can swap them more easily if the need arises&lt;/li&gt;
&lt;li&gt;When a library stops being maintained we now own that code and it is our responsibility to fix it as part of our codebase or find a suitable replacement for it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These lessons were once again learned the hard way by many businesses this November.&lt;/p&gt;

&lt;p&gt;Thanks for reading my long rant!&lt;/p&gt;




&lt;h3&gt;
  
  
  Before you go…
&lt;/h3&gt;

&lt;p&gt;If you enjoyed reading this post please share it. You should check out our other publications, you might like them too! We write from time to time about software development, tips and tricks, and how to become a better developer and business person in general. Join us on the journey of constant improvement!&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://www.facebook.com/jsguruio/" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;, &lt;a href="https://twitter.com/jsguru_software" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.linkedin.com/company/jsguru" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/jsguru" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; or &lt;a href="https://dev.to/jsguru_io"&gt;DEV.to&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://jsguru.io/blog/why-you-should-care-what-you-npm-install" rel="noopener noreferrer"&gt;jsguru.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>npm</category>
      <category>security</category>
    </item>
    <item>
      <title>SEO Guide for Websites</title>
      <dc:creator>Sasha Blagojevic</dc:creator>
      <pubDate>Mon, 01 Oct 2018 13:46:01 +0000</pubDate>
      <link>https://dev.to/jsguru_io/seo-guide-for-websites--2g2e</link>
      <guid>https://dev.to/jsguru_io/seo-guide-for-websites--2g2e</guid>
      <description>&lt;p&gt;This guide will cover a very important topic for every digital business, search engine optimization. SEO can sometimes appear as a black box, there is a lot of magic behind it and it's constantly changing and evolving. In this article, we will try to dispell it by leading you through some of the SEO best practices.&lt;/p&gt;




&lt;p&gt;Besides the &lt;a href="https://seo-hacker.com/google-algorithm-update-july-2018/"&gt;latest Google algorithm updates&lt;/a&gt;, working on our company’s website SEO and trying to battle through the avalanche of information is what prompted me to write this guide, if nothing as a reference for future self.&lt;/p&gt;

&lt;p&gt;This is by no means a comprehensive guide, I will go over the SEO fundamentals you need to cover if you want a shot at appearing on the Google's first page and we all know how it is in practice, if you are not on the first page, it's as if you don't exist, let's be honest, how often do you go to the second or the third page? Yeah, thought so…&lt;/p&gt;

&lt;p&gt;If you are interested in the history of the Google's algorithm and how it changed over the time the guys and gals at Moz have organized it in a nice &lt;a href="https://moz.com/google-algorithm-change"&gt;searchable list&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Let's start from the beginning, what is a search engine?
&lt;/h4&gt;

&lt;p&gt;You know how your website has different pages, and it has a navigation bar that links to every one of them? Well, you can look at Google, or any other search engine for that matter, as the internet's navigation menu. Google "collects" all the websites from the world and indexes them. But how does he collect them?&lt;/p&gt;

&lt;p&gt;Well, there are three ways how Google can discover your website:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;From DNS registries - if you're not familiar with the term DNS, I recommend you read this &lt;a href="https://www.cloudflare.com/learning/dns/what-is-dns/"&gt;article&lt;/a&gt;. While we're at it, did you know that &lt;a href="https://www.theregister.co.uk/2005/02/01/google_domain_seller/"&gt;Google itself is a DNS registrar&lt;/a&gt; although they do not sell domains?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If other websites link to your, Google will follow those links and discover you (unless there is a &lt;a href="https://support.google.com/webmasters/answer/96569?hl=en"&gt;rel="nofollow"&lt;/a&gt; attribute on them). Those links are called inbound links and they are one of the major factors that determine your SEO ranking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By adding your website and sitemap to the Google Search Console you are basically telling Google "Hi my name is so and so, and this is my address, here you can see my living room, and that is my kitchen, oh I almost forgot about the porch…" ;). &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BuvxV1Br--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://delivery.eusi.cloud/api/v1/f1a4305c-e431-4668-ae4c-02f78c656a41/media/s3/1538239337662_JSGuru-Body-Image-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BuvxV1Br--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://delivery.eusi.cloud/api/v1/f1a4305c-e431-4668-ae4c-02f78c656a41/media/s3/1538239337662_JSGuru-Body-Image-1.png" alt="An illustratin depicting a network of devices" width="880" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Google Search Console
&lt;/h1&gt;

&lt;p&gt;This should be your first step on your path to SEO glory. Go to the Google Search Console, add your website and go through the verification process, and now you are at your first crossroads. You have two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can either add both of your website versions, a non-www and www version (e.g. &lt;a href="https://jsguru.io"&gt;https://jsguru.io&lt;/a&gt; and &lt;a href="https://jsguru.io"&gt;https://www.jsguru.io&lt;/a&gt;) and choose a preferred one. In our case, we set the preferred one to be the non-www.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Or you can add only one version to the Google Search Console, whichever you prefer, and configure your server to redirect from the other version to your preferred one (e.g. add only &lt;a href="https://jsguru.io"&gt;https://jsguru.io&lt;/a&gt; to Google Search Console, and redirect from &lt;a href="https://jsguru.io"&gt;https://www.jsguru.io&lt;/a&gt; to &lt;a href="https://jsguru.io"&gt;https://jsguru.io&lt;/a&gt;). It must be a permanent redirect so your HTTP Response Code should be 301.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Either way, you must handle both of the domain variants, if you just leave them in the wild, without handling them as previously described, there is a high probability Google will treat them as duplicate content, and duplicate content is penalized. &lt;/p&gt;

&lt;p&gt;On the other hand, it would be really bad user experience and detrimental to your brand if you served only one domain variant and your website errored out on the other one.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Sitemaps
&lt;/h1&gt;

&lt;p&gt;Sitemaps are, as the name already says, a map of all your website pages represented in a format Google or any other search engine can easily digest. It is a collection of all your links, usually in an XML document, but it can also be in a different format such as HTML for example. Look at them as a skeleton of your website.&lt;br&gt;
There are a lot of &lt;a href="https://www.xml-sitemaps.com/"&gt;free online tools&lt;/a&gt; that can generate them for you. After you've done that you should &lt;a href="https://support.google.com/webmasters/answer/183668?hl=en"&gt;submit it to Google Search Console&lt;/a&gt; under the Sitemaps section. This will allow Google to index you more easily, but still, be patient, it can take time.&lt;/p&gt;

&lt;p&gt;If you have a publishing website like a news magazine or a blog, it would be best if you could find a way to automatically update them to reflect the changes on your website.&lt;/p&gt;

&lt;p&gt;Since you can submit as many different sitemaps to Google Search Console as you want, a good approach would be to have at least two sitemaps, one for the "static" part of your website that doesn't change that often and another one for the "dynamic" part of your website which is updated frequently, like the blog section for example.&lt;/p&gt;

&lt;p&gt;In our case we have two sitemaps, one that covers our main navigation and contains links to the pages like Home, About Us, What We Do and so on, and another one for our blog where we publish articles every two weeks.&lt;/p&gt;
&lt;h1&gt;
  
  
  3. HTTPS vs HTTP
&lt;/h1&gt;

&lt;p&gt;From July 2018 Google Chrome has started to mark websites without HTTPS as non-secure, which could negatively impact your traffic, users might decide to leave your website because they perceive it as insecure, or they might get worried that it's some kind of a scam, in addition, HTTPS websites are reported to have a slight ranking advantage over HTTP websites.&lt;/p&gt;

&lt;p&gt;In the early days of internet getting an SSL certificate and securing your website with HTTPS was a tedious and expensive process, but thanks to the open source community and Let's Encrypt Foundation it is now both free and easy to set up. &lt;br&gt;
Follow these links for a detailed tutorial on how to add HTTPS to your website:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04"&gt;Apache tutorial&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04"&gt;Ngnix tutorial&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  4. Meta tags
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Yes, meta tags are still a thing!&lt;/em&gt; &lt;br&gt;
The description meta tag allows you to customize the brief description which will be shown in the search results, otherwise, you're leaving it up to Google to determine what's important and what will be shown, which can lead to some nasty and completely unrelated descriptions. Traditionally, the description length was capped at 155 characters, but recently Google started to allow more, so to play it safe your description should be &lt;a href="https://moz.com/blog/how-long-should-your-meta-description-be-2018"&gt;between 50 and 300 characters&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Although the keywords meta tag has been obsolete for some time, I still included it, because the SEO tool I use bugged me that it was missing and since I'm a bit OCD I just had to add it.&lt;/p&gt;

&lt;p&gt;The og, not to be confused with original gangsta, meta tags are used by Facebook, LinkedIn, and other social media to determine what content will be shown when someone shares your page. Same goes for the twitter meta tags.&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;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"JSGuru is a high-quality software development shop where clients come first. We build your desired products and provide excellent, long-term customer support so that you can focus on the core of your business."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"keywords"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"software development, web development, mobile development"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Facebook--&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:url"&lt;/span&gt;                &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:type"&lt;/span&gt;               &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"website"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:title"&lt;/span&gt;              &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"JSGuru"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:description"&lt;/span&gt;        &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"JSGuru is a high-quality software development shop where clients come first. We build your desired products and provide excellent, long-term customer support so that you can focus on the core of your business."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:image"&lt;/span&gt;
      &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/img/jsguru.png"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Twitter --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:card"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"summary_large_image"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:site"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"@jsguru_software"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:creator"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"@jsguru_software"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:title"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"JSGuru"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"JSGuru is a high-quality software development shop where clients come first. We build your desired products and provide excellent, long-term customer support so that you can focus on the core of your business."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:image"&lt;/span&gt;
      &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/img/jsguru.png"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  5. Canonical Links 
&lt;/h1&gt;

&lt;p&gt;What are canonical links? For all of you who are not familiar with the term, canonical links are HTML tags that you put in the HEAD of your document and their purpose is to point to the original source of the content.&lt;br&gt;
Canonical links can point to a different page/ link from the current page you are on, or they can be self referencing, meaning they can point to the same page you are currently on.&lt;/p&gt;

&lt;p&gt;When Google comes across a canonical link that points to a different page it says to him "Hey don't index this page, the actual source you should index is there.".&lt;/p&gt;

&lt;p&gt;If the canonical link is self-referencing, that signals to Google "Ok this is the definite root of the content". If Google were to come across the same content again on a different website he would definitely know that your content is actually the original.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;JSGuru - What We Do&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&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;"canonical"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/what-we-do"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
 ...
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you remember how I mentioned earlier that we should handle both the non-www and www version of our domain? Well, be careful not to mix them in your canonical links, choose one preferred version and stick with it!&lt;/p&gt;

&lt;h1&gt;
  
  
  6. Localization - hreflangs 
&lt;/h1&gt;

&lt;p&gt;What if you have a multilingual site and you want different language versions served depending on the country of the visitor? How to go about that?&lt;/p&gt;

&lt;p&gt;A common, but a discouraged approach is to geolocate the user by his IP address. This is usually done by storing the IP tables in your database and comparing them with the user's or using a third party service like &lt;a href="https://ipinfo.io/"&gt;Ipinfo&lt;/a&gt;.&lt;br&gt;
After determining the user's location you would store it in a cookie and serve the appropriate language.&lt;/p&gt;

&lt;p&gt;This seems like a sensible approach, doesn't it? But why is it discouraged? &lt;/p&gt;

&lt;p&gt;Well, firstly the geolocation by IP is not that precise, especially nowadays when people value their online privacy and are using VPN's more and more, additionally, some internet providers themselves use proxies when giving out dynamic IPs.&lt;/p&gt;

&lt;p&gt;Secondly what if the user is a German but he is in England on a business trip? He would get the English version and we don't want that.&lt;/p&gt;

&lt;p&gt;Thirdly you are taking away the possibility to manually choose the language version from the user. &lt;/p&gt;

&lt;p&gt;Last but not the least, you are preventing Google from properly indexing all your website versions because their crawling servers are mainly in the US.&lt;/p&gt;
&lt;h3&gt;
  
  
  Now that we went over what not do, let's go over what you should do!
&lt;/h3&gt;

&lt;p&gt;First and foremost, the pages your hreflang links are pointing to should have the same content just in a different language, they should never have a completely different content, that is a NO NO.&lt;/p&gt;

&lt;p&gt;When it comes to actual linking, you have two options: &lt;/p&gt;
&lt;h4&gt;
  
  
  a) Add hreflang link in the head of the HTML document
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- English (default) language page --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;JSGuru - What We Do&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&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;"canonical"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/what-we-do"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; 
          &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"x-default"&lt;/span&gt;  
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/what-we-do"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; 
          &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt; 
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/what-we-do"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; 
          &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"de"&lt;/span&gt; 
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/de/was-wir-tun"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; 
          &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"de-ch"&lt;/span&gt; 
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/de/was-wir-tun"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; 
          &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"de-at"&lt;/span&gt; 
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/de/was-wir-tun"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
 ...
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It is important that you add the hreflang links on all pages not just your default language page.&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="c"&gt;&amp;lt;!-- German Language Page --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;JSGuru - Was Wir Tun&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; 
          &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"x-default"&lt;/span&gt;  
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/what-we-do"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; 
          &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt; 
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/what-we-do"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; 
          &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"de"&lt;/span&gt; 
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/de/was-wir-tun"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; 
          &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"de-ch"&lt;/span&gt; 
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/de/was-wir-tun"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; 
          &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"de-at"&lt;/span&gt; 
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/de/was-wir-tun"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
 ...
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be careful not to combine hreflang tags with canonical links which point to different pages, as well. Hreflang tags can only be combined with self-referencing canonical links.&lt;/p&gt;

&lt;p&gt;In our code example, we included the canonical link only in our English (default) language page, that's because that is the original source of our content, the German page shouldn't include the canonical link because it's the same content just in a different language, if we were to include it we would just confuse the Google crawler.&lt;/p&gt;

&lt;h4&gt;
  
  
  b) Add hreflang link to the sitemap
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;urlset&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.sitemaps.org/schemas/sitemap/0.9"&lt;/span&gt;
        &lt;span class="na"&gt;xmlns:xhtml=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/1999/xhtml"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;loc&amp;gt;&lt;/span&gt;https://jsguru.io/what-we-do&lt;span class="nt"&gt;&amp;lt;/loc&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;xhtml:link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"alternate"&lt;/span&gt; 
                &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"x-default"&lt;/span&gt; 
                &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/what-we-do"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;xhtml:link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"alternate"&lt;/span&gt;
                &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"de"&lt;/span&gt;
                &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/de/was-wir-tun"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;xhtml:link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"alternate"&lt;/span&gt;
                &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;
                &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://jsguru.io/what-we-do"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;lastmod&amp;gt;&lt;/span&gt;2018-08-28T09:24:19+00:00&lt;span class="nt"&gt;&amp;lt;/lastmod&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;priority&amp;gt;&lt;/span&gt;1.00&lt;span class="nt"&gt;&amp;lt;/priority&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/urlset&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;IMPORTANT - you should always provide the full link including the protocol (also known as an absolute link) to the canonical or hreflang link tags!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can read more in-depth about localization, hreflang tags and an additional approach to localization I didn't cover &lt;a href="https://support.google.com/webmasters/answer/189077#language-codes"&gt;here&lt;/a&gt;.&lt;br&gt;
Here are some tools which can be helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.aleydasolis.com/english/international-seo-tools/hreflang-tags-generator/"&gt;Hreflang tag generator&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://hreflang.ninja/"&gt;Hreflang tag validation tool&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  7. Images and Videos
&lt;/h1&gt;

&lt;p&gt;When it comes to images you should always add the alt attribute which contains the textual description of the image. The benefits of adding alt attributes are twofold, firstly it will make your website more accessible, the visually impaired people will get the description of the image, and secondly Google will be able to understand the context of your images which will, as a result, increase your visibility in the search results both on the general search and image search.&lt;/p&gt;

&lt;p&gt;Same goes for the videos as well. No matter whether you are adding them directly on your website or on platforms like Youtube/Vimeo you should always provide transcripts. Google can't process images and videos, the only way search engines can discern their content is by textual descriptions.&lt;/p&gt;
&lt;h1&gt;
  
  
  8. Google Structured Data
&lt;/h1&gt;

&lt;p&gt;If you ever thought about SEO being a black box, wait 'till you start with Google Structured Data, that is a black Pandora's box. There's no closing this lid when you open it.&lt;/p&gt;

&lt;p&gt;This is such a vast topic that it deserves a whole new blog post in itself, but I'll try to cover the basics here and provide you with some helpful links.&lt;/p&gt;

&lt;p&gt;Google Structured Data is an implementation of the Schema.org standard for rich data. Google uses this data to fill it's Knowledge Graph, and show you rich search results a.k.a. &lt;a href="https://webmasters.googleblog.com/2016/05/introducing-rich-cards.html"&gt;Google Rich Cards&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What's more, you can do everything right and your structured data might still not appear in the search results.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using structured data enables a feature to be present, it does not guarantee that it will be present. &lt;br&gt;
The Google algorithm tailors search results to create what it thinks is the best search experience for a user, depending on many variables, including search history, location, and device type. &lt;br&gt;
In some cases, it may determine that one feature is more appropriate than another, or even that a plain blue link is best. - per &lt;a href="https://developers.google.com/search/docs/guides/sd-policies"&gt;Google's Policy&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can provide the structured data in three formats, but Google recommends &lt;a href="https://json-ld.org/"&gt;JSON-LD&lt;/a&gt; so we will concentrate on that format. Here is an example of how it looks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script type="application/ld+json"&amp;gt;
    {
         "@context": "http://schema.org",
         "@type":"LocalBusiness",
         "address": {
             "@type": "PostalAddress",
             "addressLocality": "Manhattan",
             "addressRegion":  "NY",
             "postalCode":"10036",
             "streetAddress": "400 Broadway"
         },
         "description": "This is your business description.",
         "name": "Craig's Car Repair",
         "telephone": "555-111-2345",
         "openingHours": "Mo,Tu,We,Th,Fr 09:00-17:00",
         "geo": {
             "@type": "GeoCoordinates",
             "latitude": "20.75",
             "longitude": "13.98"},
             "sameAs" : [
                 "http://www.facebook.com/example",
                 "http://www.twitter.com/example",
                 "http://plus.google.com/example"
             ]
    }
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have an example of &lt;em&gt;LocalBusiness&lt;/em&gt; entity which is a subset of &lt;em&gt;Organization&lt;/em&gt; entity. You should always try to be as specific as possible with structured data and use the most narrow definition of the entity as in this example. Additionally, you should always try to provide all possible attributes.&lt;/p&gt;

&lt;p&gt;You can find example snippets that have been tried and tested by the community on this &lt;a href="https://jsonld.com/"&gt;link&lt;/a&gt;, just replace the values with your own.&lt;/p&gt;

&lt;p&gt;I also recommend &lt;a href="https://technicalseo.com/seo-tools/schema-markup-generator/"&gt;Merkle structured data generation tool&lt;/a&gt; for starters, and later when you get a better understanding of how everything works you can expand on the generated data with additional properties.&lt;/p&gt;

&lt;p&gt;Another option is to use &lt;a href="https://support.google.com/webmasters/topic/2774098?hl=en&amp;amp;ref_topic=2692946"&gt;Data Highlighter&lt;/a&gt;, it is a tool within Google Search Console under Search Appearance section, but it is currently only visible in the old view! Google is currently rolling out a new Search Console so I'm not sure about the future of this tool, it is to be determined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where should you put your structured data?
&lt;/h3&gt;

&lt;p&gt;Structured data should go in the head of the HTML document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/ld+json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{...}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is one general rule of thumb that you should adhere to, all the data that you've put in the script tag should be actually visible on that page. For more info, you should consult the Google Guidelines.&lt;/p&gt;

&lt;p&gt;Here are some links that could be helpful, as well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/search/docs/guides/intro-structured-data"&gt;Intro to structured cards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/search/docs/guides/search-gallery"&gt;Guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://search.google.com/test/rich-results"&gt;Rich Cards Search Results Testing Tool&lt;/a&gt; &lt;em&gt;(currently in beta and limited to following entities: &lt;a href="https://developers.google.com/search/docs/data-types/job-posting"&gt;Job posting&lt;/a&gt;, &lt;a href="https://developers.google.com/search/docs/data-types/recipe"&gt;Recipe&lt;/a&gt;, &lt;a href="https://developers.google.com/search/docs/data-types/course"&gt;Course&lt;/a&gt;, &lt;a href="https://developers.google.com/search/docs/data-types/media"&gt;TV and Movie&lt;/a&gt;, &lt;a href="https://developers.google.com/search/docs/data-types/event"&gt;Event&lt;/a&gt;)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://search.google.com/structured-data/testing-tool"&gt;Google Structured Data Validation Tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codelabs.developers.google.com/codelabs/structured-data/#0"&gt;Google's Simple Tutorial on How to Add Rich Cards&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  9. Google Local Business
&lt;/h1&gt;

&lt;p&gt;Google Business, among other things, is essentially a more user-friendly way of adding LocalBusiness structured data, and you should definitely do it!&lt;/p&gt;

&lt;p&gt;If your business has multiple locations you should add all of them. It is best to combine this method and adding structured data manually because if Google's Knowledge Graph is populated with your social media pages and B2B platforms like &lt;a href="https://clutch.co/profile/jsguru"&gt;Clutch&lt;/a&gt; it will automatically link them to your business and your reviews will be shown in the rich results.&lt;/p&gt;

&lt;p&gt;There's nothing much to add here, let's move on!&lt;/p&gt;

&lt;h1&gt;
  
  
  10. Blog
&lt;/h1&gt;

&lt;p&gt;Blog is still the &lt;em&gt;Holy Grail&lt;/em&gt; of SEO and Digital Marketing. Despite the over-saturation with articles on many topics, this is still the best organic way to build links and increase traffic to your website.&lt;/p&gt;

&lt;p&gt;You should try to publish regularly, but you shouldn't sacrifice quality over quantity, Google's algorithms have shifted more towards quality vs. quantity in recent years. Not only do they look for quality in the content but the quality of the links that lead to it as well.&lt;/p&gt;

&lt;p&gt;When it comes to the blog the only dilemma you can have is whether to host it on a subdomain e.g. blog.jsguru.io or a subfolder &lt;a href="https://jsguru.io/blog"&gt;jsguru.io/blog&lt;/a&gt;. &lt;br&gt;
Well, actually it's not a dilemma, you should &lt;a href="https://www.smartinsights.com/search-engine-optimisation-seo/internal-linking-strategy/which-is-best-for-blog-seo-subdomain-or-subfolder/"&gt;host it in a subfolder&lt;/a&gt; because subdomains are treated as different domains by Google so they will need to build their own reputation independently of your main domain. There is no value added to you with this approach.&lt;/p&gt;

&lt;p&gt;When it comes down to the implementation of the blog you should still, at least partially stick to the old-school server-side rendered approach because Google indexing is two-pass, the second pass is for JS only websites which is a week after the initial pass, especially if your business model is centred around publishing. This has been confirmed by a Paul Kinlan on Twitter:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wgykguff--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/2736788281/13811f0063041a72d7ea6ede7b89fedd_normal.png" alt="Paul Kinlan profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Paul Kinlan
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/paul_kinlan"&gt;@paul_kinlan&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      &lt;a href="https://twitter.com/HenrikJoreteg"&gt;@HenrikJoreteg&lt;/a&gt; Indexing is delayed for pure client side sides. Google indexer is two-pass, first run is without js, then week later it's with is (or there abouts)
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      12:26 PM - 12 Sep 2018
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1039852756113080320" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1039852756113080320" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1039852756113080320" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;h1&gt;
  
  
  11. Google Page Insights
&lt;/h1&gt;

&lt;p&gt;Performance is one of the major factors of your ranking. The lower the load time of your website the higher your ranking will be, especially when it comes to mobile devices.&lt;/p&gt;

&lt;p&gt;One great tool you can leverage when it comes to performance tweaking is &lt;a href="https://developers.google.com/speed/pagespeed/insights/"&gt;Google Page Insights&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some basic and common ways of improving your website performance are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minify your javascript and css files.&lt;/li&gt;
&lt;li&gt;When adding jpg/jpeg images compress them to 80% of the quality, the difference will not be visible in the web environment but their size will significantly decrease.&lt;/li&gt;
&lt;li&gt;If possible use a cookieless (stateless) domain to serve your static assets like images.
Serving different images for different screen sizes. There is no need to load a 1920x1080px image on a 320px wide screen.&lt;/li&gt;
&lt;li&gt;Lazy loading images - loading images only when they enter the viewport of the device.&lt;/li&gt;
&lt;li&gt;Gzip compression and browser caching (images, javascript, css). Here's a nice tutorial for &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-increase-pagespeed-score-by-changing-your-nginx-configuration-on-ubuntu-16-04"&gt;improving your page insight rank for ngnix servers&lt;/a&gt;. If you're using apache you should look up &lt;em&gt;mod_deflate&lt;/em&gt; and &lt;em&gt;mod_expires&lt;/em&gt; extensions.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html"&gt;script defer and async&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  12. Mobile Responsive and Mobile First Indexing
&lt;/h1&gt;

&lt;p&gt;More and more internet users are coming from mobile devices, actually, they have surpassed the desktop users in general, and according to this trend, Google has shifted its focus on mobile devices several years ago. If you remember Google used to show a tag &lt;em&gt;mobile-friendly&lt;/em&gt; in its search results.&lt;/p&gt;

&lt;p&gt;Nowadays there is no need for it, and having a mobile-friendly website that offers a pleasant experience on all screen sizes is a no-brainer. In order to offer a better mobile UX, some people have sacrificed the content in the mobile versions of their websites.&lt;/p&gt;

&lt;p&gt;With the latest changes to Google Algorithm, now they might pay the price for it. Google has started &lt;a href="https://webmasters.googleblog.com/2018/03/rolling-out-mobile-first-indexing.html"&gt;&lt;strong&gt;mobile first indexing&lt;/strong&gt;&lt;/a&gt;, but what does that mean?&lt;/p&gt;

&lt;p&gt;Previously Google would crawl the desktop version of the website for indexing, from now on, the mobile version will be used for indexing. So if you left out content to fit everything nicely in the smaller screens, your SEO  might suffer. &lt;/p&gt;

&lt;h1&gt;
  
  
  13. Summary
&lt;/h1&gt;

&lt;p&gt;If you've come this far I congratulate you, it has been exhausting for me to write all of this, I can only imagine how it is to read it! Yes, you deserve to pat yourself on the shoulder. &lt;br&gt;
If I wanted you to take anything from this article it would be the following.&lt;/p&gt;
&lt;h4&gt;
  
  
  The three most important factors for good SEO are:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;quality content,&lt;/li&gt;
&lt;li&gt;quality traffic and&lt;/li&gt;
&lt;li&gt;quality links.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As with everything in life quality trumps quantity, long gone are the days where you could just pay for links on some obscure websites or churn out shallow articles that barely touch the topic they are supposed to cover.&lt;br&gt;
And lastly, have patience, these things take time, Google has no infinite amount of resources, and indexing new websites is not really on the top of their priority list, so it might take a few weeks or even months, to start having some real results.&lt;/p&gt;

&lt;p&gt;OMG! I almost forgot I highly recommend you watch this Q&amp;amp;A with Riva from &lt;a href="http://digital4startups.com/"&gt;Digital4Startups&lt;/a&gt; we had the privilege of hosting her in our offices. The video quality su*ks but the audio is the important part anyway!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/dFi2JBXG4dg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you go…
&lt;/h2&gt;

&lt;p&gt;If you enjoyed reading this post please share it. You should check out our other publications, you might like them too! We write from time to time about software development, tips and tricks, and how to become a better developer and business person in general. Join us on the journey of constant improvement!&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://www.facebook.com/jsguruio/"&gt;Facebook&lt;/a&gt;, &lt;a href="https://twitter.com/jsguru_software"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.linkedin.com/company/jsguru"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/jsguru"&gt;Medium&lt;/a&gt; or here on &lt;strong&gt;DEV.to&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>google</category>
    </item>
    <item>
      <title>Leaving the Old Ways - jQuery vs React</title>
      <dc:creator>Sasha Blagojevic</dc:creator>
      <pubDate>Thu, 16 Aug 2018 15:21:30 +0000</pubDate>
      <link>https://dev.to/jsguru_io/leaving-the-old-ways---jquery-vs-react-4f69</link>
      <guid>https://dev.to/jsguru_io/leaving-the-old-ways---jquery-vs-react-4f69</guid>
      <description>&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%2Fdelivery.eusi.cloud%2Fapi%2Fv1%2Ff1a4305c-e431-4668-ae4c-02f78c656a41%2Fmedia%2Fs3%2F1534422989797_react-vs-jquery-header.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%2Fdelivery.eusi.cloud%2Fapi%2Fv1%2Ff1a4305c-e431-4668-ae4c-02f78c656a41%2Fmedia%2Fs3%2F1534422989797_react-vs-jquery-header.png" alt="Main Image, React logo on thumbs up"&gt;&lt;/a&gt;&lt;br&gt;
Contrary to popular belief, React’s biggest use cases are not SPAs, it’s the hybrid apps that are most common, and the best fit in my opinion, in this post I will cover how and why I went from a React hater to a React fanboy, and why React is a perfect replacement for jQuery.&lt;/p&gt;



&lt;p&gt;I used to have some kind of an inner resistance when React and Vue first started to gain traction and were becoming the de facto standard for building modern UIs.&lt;/p&gt;

&lt;p&gt;Yes, I’m purposefully leaving Angular out, even though AngularJS was the pioneer of the front end revolution that brought us web 2.0.&lt;/p&gt;

&lt;p&gt;Angular is philosophically on the completely opposite side of the spectrum, it’s a full-blown SPA framework, whereas React is just a view library, and I’m still not convinced SPAs are the right way and personally I prefer the hybrid approach.&lt;/p&gt;

&lt;p&gt;For all of you that are thinking right now  - “And what about Vue?” , Vue would be somewhere in between these two extremes.&lt;/p&gt;

&lt;p&gt;Contrary to popular belief, React’s biggest use cases are not SPAs, it’s the hybrid apps that are most common, and the best fit in my opinion. Don’t believe me? Well look what Facebook’s Dan Abramov had to say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s interesting that React became associated so much with SPAs but Facebook isn’t using it for SPAs (except for the Instagram website and some internal tools) - &lt;em&gt;&lt;a class="mentioned-user" href="https://dev.to/dan_abramov"&gt;@dan_abramov&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One of my major pet peeves was Webpack and all the tooling they brought with themselves.&lt;/p&gt;

&lt;p&gt;I held a strong opinion that they were introducing unnecessary complexity to the front end, yes they made us developers feel like rocket scientists with the amount of tweaking we had to do and the number of levers and gears we had to pull and turn to make them run, but at the end of the day, did they really add value to the business?&lt;/p&gt;

&lt;p&gt;Did they improve the product and the user experience to warrant a higher maintenance and development cost and a higher barrier of entry for new bloods, when we could have done the same with plain ole jQuery, or even better, vanilla JS?&lt;/p&gt;

&lt;p&gt;After I found out React introduced react-cli I decided to give it another go, and boy oh boy was I pleasantly surprised.&lt;/p&gt;

&lt;p&gt;With the introduction of react-cli (and vue-cli) all that nitty-gritty tooling and those build steps that were equivalent of getting a PhD in Computer Science were out of the way for 80–90% of use cases, although you still had to roll up your sleeves and mess around with webpack for some edge cases.&lt;/p&gt;

&lt;p&gt;Sure if you’re building something fairly simple, may it be a contact form with an Ajax submit or something entirely different but that is simple enough, vanilla JS is, in my opinion, a sound approach, there is no need to roll out the big guns. You can even go with jQuery, but there is really no need for it in today’s world, but that’s a completely different topic.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep it simple  -  &lt;em&gt;this should always be your mantra&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In that case, if you were to use a framework, 90% of your code would be the frameworks infrastructure and the rest would be your actual logic. That is a major overkill, you are introducing unnecessary boilerplate and increasing your bundle size which directly impacts performance. Bigger bundle means a lot more bytes have to be sent over the INTERNETZ, so you’re actually costing your business, just because you wanted to use that shiny new thing.&lt;/p&gt;

&lt;p&gt;Oh, you think those milliseconds don’t matter much? Well they can quickly add up, especially on high traffic sites, just because today’s machines are powerful doesn’t mean we should be reckless and throw anything at them, we need to be conservative with our resources.&lt;/p&gt;

&lt;p&gt;Look at it like this, it’s as if you are building a foundation for a ten story building only to put a tent on it.&lt;/p&gt;

&lt;p&gt;React, versus the old way, really comes to shine when you are building complex UIs.&lt;/p&gt;

&lt;p&gt;With React the simplicity of development increases with the complexity of the UI you are building, or in other words, the cost of development is inversely proportional to the complexity in comparison with the vanilla JS/jQuery approach.&lt;/p&gt;

&lt;p&gt;Here’s a little graph for all you visual types.&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%2Fdelivery.eusi.cloud%2Fapi%2Fv1%2Ff1a4305c-e431-4668-ae4c-02f78c656a41%2Fmedia%2Fs3%2F1534422990085_react-vs-jquery-graph.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%2Fdelivery.eusi.cloud%2Fapi%2Fv1%2Ff1a4305c-e431-4668-ae4c-02f78c656a41%2Fmedia%2Fs3%2F1534422990085_react-vs-jquery-graph.png" alt="Graph representing how the simplicity of implementation increases with the complexity of your UI when using React"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Talk is cheap, let’s get our hands dirty with an example from the real world.&lt;/p&gt;

&lt;p&gt;We have an invoice form, aside from the general data like the date of the invoice, the due date of the invoice, subject etc., the user needs to be able to add/remove invoice items.&lt;/p&gt;

&lt;p&gt;Invoice items, on the other hand, have the following:    &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name and/or the description of the product/service you’re invoicing,&lt;/li&gt;
&lt;li&gt;it's quantity,&lt;/li&gt;
&lt;li&gt;price,&lt;/li&gt;
&lt;li&gt;any discount you may give,&lt;/li&gt;
&lt;li&gt;any penalty interest that incurred,&lt;/li&gt;
&lt;li&gt;then we might have VAT tax or sales tax depending on your country’s laws&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and finally, all the calculations that go with the aforementioned.&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%2Fdelivery.eusi.cloud%2Fapi%2Fv1%2Ff1a4305c-e431-4668-ae4c-02f78c656a41%2Fmedia%2Fs3%2F1534422989041_react-vs-jquery-form.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%2Fdelivery.eusi.cloud%2Fapi%2Fv1%2Ff1a4305c-e431-4668-ae4c-02f78c656a41%2Fmedia%2Fs3%2F1534422989041_react-vs-jquery-form.png" alt="Image representing a complex form"&gt;&lt;/a&gt;&lt;br&gt;
You see now how a seemingly simple thing can get complicated quickly?&lt;/p&gt;

&lt;p&gt;With the old approach, you would have to have a lot of things on your mind, you would need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Add change event handlers on all the different input fields, and some of them would additionally need to cancel each other out so you would need to track when to detach them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Every time an invoice item is added or removed you would need to manipulate the DOM, by either adding or removing child nodes or writing HTML as a string.&lt;/p&gt;

&lt;p&gt;No matter the choice, you’d need to concatenate some HTML and fill it with variables, which can get unruly pretty fast. ECMA 6 string literals do ease this a bit, but still, it can get cumbersome.&lt;/p&gt;

&lt;p&gt;Imagine a designer changes something, on how many places would you need to changes all those bits that you’re glueing together in your vanilla JS code?&lt;/p&gt;

&lt;p&gt;Another thing you would need to keep in your mind is that if you manipulate DOM as a string you’re killing all the event handlers on those particular DOM elements. Yep, another gotcha moment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculations  -  every time an invoice item is added or removed you need to calculate its particular values and in addition update the invoice’s subtotal, tax, total, etc. Essentially you would be creating your own state store.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I probably might have missed a thing or two that would pop up while trying to handle this use case the old way, as it usually is, everything sounds simpler on paper until you start to implement it and a whole new spectrum of cases that need to be handled appears.&lt;/p&gt;

&lt;p&gt;Using React requires a slight shift in your mindset, in a nutshell, you only need to be concerned with one thing, the state. This simplifies the logic immensely, you are only concerned about your state, that is the only thing you need to manipulate, and your invoice input fields and invoice items will be re-rendered according to the changes in your state.&lt;/p&gt;

&lt;p&gt;Let’s take a look at our simplified code example, this might give you a clearer picture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prop-types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InvoiceItemForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;subtotal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;taxRate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;tax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;invoiceItems&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;handleInputChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtotal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtotal&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taxRate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtotal&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taxRate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="c1"&gt;// Clear the last input&lt;/span&gt;
          &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
                      &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;taxRate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                      &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.17&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                  &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                      &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                      &lt;span class="k"&gt;break&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;rowIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rowIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;rowIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;items&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;renderCells&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rowIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cells&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rowIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;];&lt;/span&gt;

      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;cells&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;);&lt;/span&gt;
          &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;cells&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeItem&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Remove Item&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cells&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;render &lt;/span&gt;&lt;span class="p"&gt;()&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
                    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
                    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;price&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
                    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;quantity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
                    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;taxRate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taxRate&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
                    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subtotal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtotal&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
                    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tax&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tax&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
                    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;total&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;table&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;thead&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Item no.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Description&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Price&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Quantity&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tax Rate&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Subtotal&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tax&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Total&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;thead&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;tbody&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="si"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;tr&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                                    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;renderCells&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                                &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                            &lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="p"&gt;})&lt;/span&gt;
                    &lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;tbody&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;table&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    );
  }
}
export default InvoiceItemForm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vuoala, that’s it!&lt;/p&gt;

&lt;p&gt;Hey, do you have a jQuery app you would like to migrate or are you just trying to figure out which framework would be best for your next million dollar idea? Contact us at &lt;a href="mailto:info@jsguru.io"&gt;info@jsguru.io&lt;/a&gt;, and let that be our headache.&lt;/p&gt;




&lt;h4&gt;
  
  
  Before you go…
&lt;/h4&gt;

&lt;p&gt;If you enjoyed reading this post please share it. You should check out our other publications, you might like them too! We write from time to time about software development, tips and tricks, and how to become a better developer and business person in general. Join us on the journey of constant improvement!&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://www.facebook.com/jsguruio/" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;, &lt;a href="https://twitter.com/jsguru_software" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.linkedin.com/company/jsguru" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/jsguru" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; or &lt;a href="https://dev.to/jsguru_io"&gt;DEV.to&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://jsguru.io" rel="noopener noreferrer"&gt;jsguru.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>jquery</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Do's and Don'ts for Javascript Newbies </title>
      <dc:creator>JelenaKalaba</dc:creator>
      <pubDate>Fri, 27 Jul 2018 13:00:07 +0000</pubDate>
      <link>https://dev.to/jsguru_io/dos-and-donts-for-javascript-newbies--5dkl</link>
      <guid>https://dev.to/jsguru_io/dos-and-donts-for-javascript-newbies--5dkl</guid>
      <description>&lt;p&gt;Since the day Brendan Eich created it, JS has had many makeovers, changes, additions, and frameworks added to its body. After a lifetime of turbulence, JS has been shaped into how we see it now in 2018, and yet there is much more growth awaiting in its future.&lt;/p&gt;

&lt;p&gt;Today, I think the current state of JavaScript is best described by Atwood’s quote: “Any application that can be written in JavaScript will eventually be written in JavaScript.” Virtually anything you imagine can be written in JavaScript.&lt;/p&gt;

&lt;p&gt;In this post, we will give you some tips on what to do, and what not to do, for both JS newbies and for those who have had some previous experience in this language.&lt;/p&gt;

&lt;p&gt;There are some common rules of thumb when it comes to writing JavaScript code that should always be on your mind. Such rules relate to variable declarations, naming conventions, code commenting, striving to write cleaner code and keeping up with the JavaScript world in general. Let’s tackle some of these. &lt;/p&gt;

&lt;h3&gt;
  
  
  VARIABLES
&lt;/h3&gt;

&lt;p&gt;When it comes to naming variables, using the camelCase rule is generally considered to be the best practice. That’s how we at JSGuru name them and it helps when the whole team uses this rule as it helps keep the code uniform. &lt;/p&gt;

&lt;p&gt;It is also important to keep variable names short, concise, and descriptive. This should be adhered to as much as possible due to the fact that code is shared most of the time. The reader should be able to figure out what is stored in that variable or what it refers to without logging it in the console and backtracking your code. A good variable name should tell the reader about the context it is being used in within a chunk of code, and not refer to its value or purpose it is being used for from the user’s point of view. For example, “userAnswer” is a better variable name than “userInput”, as it clearly refers to, from a coding standpoint to a question asked earlier. You know exactly what input it refers to. Along the same lines, avoid using generic names such as “num” and “arr”, without at least appending it with information related to what it refers to, i.e. “selectedColors”. Along the same lines, “wantsSubscriptions” or “shouldRemember” is better than “trueOrFalse”. Use verbs and plural/singular to help indicate the value, instead of some acronym related to the type of value inside of a name. &lt;/p&gt;

&lt;p&gt;Making the code cleaner and easier to read is considered a good practice. You can do this by placing the declaration of the variables at the beginning of your script, adding var or let in front of the first variable in the list, and only the first one. A comma can divide the rest, and to seal the deal place a semi-colon at the end of this declaration. Initialize variables first-hand when you declare them so that we avoid undefined values, and then do everything else.&lt;/p&gt;

&lt;h3&gt;
  
  
  LET OR CONST INSTEAD OF VAR
&lt;/h3&gt;

&lt;p&gt;Since the adoption of ES6 (also known as the ECMAScript 2015) standard, variables should be declared using the keywords let and const. The reason behind abandoning the var keyword is that it should provide clearer meaning regarding the purpose of the variable and the context in which it is used. Const should generally hold references to values that will not be changed over time, even though, in cases of objects and arrays, it is allowed to mutate them. On the other hand, the keyword let indicates that a value might be changed or that a different value will be assigned to the particular variable. If you try to change the value of a const, JavaScript will tell you about it and help you avoid bugs. A good use case for const is storing a reference to a DOM element which you always want to keep in that variable. Keyword let is meant to be used with loops or mathematical algorithms, generally when its value is expected to vary. Variables declared with let and const aren’t hoisted, like those declared with var.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fj4hrgtmytrifgf6c6vwh.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fj4hrgtmytrifgf6c6vwh.png" alt="Body image - comments"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  COMMENTS
&lt;/h3&gt;

&lt;p&gt;Have you ever found yourself in a situation where you looked at your old code only to see there are no comments related to it? Maybe you forgot to write them at the time or you accidentally postponed writing them and wound up forgetting to do so later. Whatever the case may be, now you’re in a situation where you’re looking at a bunch of hieroglyphs and start feeling overwhelmed because you don’t know where to start reading and understanding it. Writing clean code and adhering to good naming conventions can surely help, but a more complex chunk of code sometimes just simply needs one or two comments to help the reader understand it quicker. I remember returning to my code on multiple occasions and spending a good amount of time figuring out what I wrote and how exactly I went about it. This is when I learned the importance of writing some logic inside comments, just to serve as notes and help me understand it quicker in the future. You will, almost undoubtedly, find yourself in a situation where you are trying to understand the code you or someone else wrote and wishing there were some comments around it just to speed up the process of catching up.&lt;/p&gt;

&lt;p&gt;Use this experience as a motivation to help you understand the importance of writing comments and keep it in mind next time you write some complex logic. Just write a short sentence capturing the essence of that chunk and trust me, you’ll thank yourself in the future. More importantly, whoever reads your code will be grateful as well. As a side note, it doesn’t hurt to make your comments humorous and positive since negativity and arrogance are counterproductive.&lt;/p&gt;

&lt;h3&gt;
  
  
  FORMATTING CODE
&lt;/h3&gt;

&lt;p&gt;Formatting code can be tricky sometimes. To help you with this you should try out code linters like ESLint or JSLint (links to official site ). Both of these tools will help you have cleaner and better code in line with community standards. The least you can do is use whitespace and newlines to group your code into related chunks. This will make your code that much more readable and you will be able to make sense of it a lot quicker!   &lt;/p&gt;

&lt;h3&gt;
  
  
  EFFICIENCY
&lt;/h3&gt;

&lt;p&gt;In this section, we will remind you of the importance of general efficiency in programming. These are some common newbie pitfalls when it comes to Javascript.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Fetching DOM elements
&lt;/h4&gt;

&lt;p&gt;If I got a dollar every time I saw document.getElementById scattered all around the code, I'd be a millionaire by now. If the DOM elements haven't actually changed, just store it in a variable an use it later down the road.&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;let&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;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;someElementId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseover&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h1&amp;gt;Hello Again!&amp;lt;/h1&amp;gt;&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially common with jQuery, we've all seen code like this:&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="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;actioned&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;hover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &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="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &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;Instead of:&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;let&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;actioned&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &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="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &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;What you should also keep on your mind is that fetching a DOM element by Id is the fastest method, so you should use it over other methods like document.getElementsByClassName, document.getElementsByTagName document.querySelector, etc. whenever you can.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. DOM manipulation in the loop
&lt;/h4&gt;

&lt;p&gt;This is an example of what not to do. Here we fetch a DOM element from within our loop. That means that we unnecessarily fetch it on every iteration and then subsequently we fill its inner HTML on every iteration as well.&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;function&lt;/span&gt; &lt;span class="nf"&gt;processArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;myArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;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;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;myArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;myArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first thing we can do to optimize this code is to move the fetch statement above the loop. By doing this, we will not change the logic of this code block but give the code a significant velocity boost, while also decreasing the memory usage at the same time. To avoid the constant updating of the DOM with every iteration, as this is quite time-consuming, it would be a good idea to move the innerHTML out of the loop, as well.&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;let&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;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;someElementId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseover&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h1&amp;gt;Hello Again!&amp;lt;/h1&amp;gt;&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These examples help us keep two things in mind when we talk about the code's efficiency. Firstly, to declare variables outside the loop and secondly to reduce DOM operations and make sure to use them intelligently.&lt;/p&gt;

&lt;p&gt;In addition, it's important to remember to use let more then var when you're creating new variables.&lt;/p&gt;

&lt;p&gt;However, global variables defined with let will not be added as properties on the global window object like those defined with var.&lt;/p&gt;

&lt;h3&gt;
  
  
  STRICT MODE
&lt;/h3&gt;

&lt;p&gt;We are encouraged to use ''Strict Mode'' when our goal is to create more robust JavaScript code. Strict Mode changes (previously accepted) ''bad syntax'' into real errors. It means that trying to add values to the properties of a mistyped variable, which would create a new global variable in the regular mode, will now give you an error. In Strict Mode, any assignment with a non-writable property, a getter-only property, a non-existing property, a non-existing variable, or a non-existing object, will throw an error.&lt;/p&gt;

&lt;p&gt;Staying up to date with the newest JavaScript standards is perhaps the most important thing on this list.&lt;/p&gt;

&lt;p&gt;Firstly, your code will be modern and most likely written close to what industry standards are at the time. In addition by using the newest features, you and all other developers are encouraging and creating a need for browsers to implement those features and start supporting them out of the box. Right now, this is done with the help of transpilation tools such as Babel. If you’re not familiar with Babel, simply put, it “translates” newest JavaScript code into the format which browsers of today can understand. Babel reads your JavaScript code and compiles the newest features you used down to ES5, which all browsers can understand. Some browsers support ES6 features already, but using Babel and similar tools is still necessary because we want our JavaScript to be supported by all browsers and older versions as well.&lt;/p&gt;

&lt;p&gt;For further information regarding Babel, I recommend you visit their website they have a great documentation which will get you started quickly.&lt;/p&gt;

&lt;p&gt;What's more, you will make your life easier! Newest JavaScript features are amazing and they get better and better with each specification. They are an improvement to the old ways of doing things, i.e. using Promises or Async/Await to avoid being in a callback pyramid of doom.&lt;/p&gt;

&lt;p&gt;Learning new things means leaving your comfort zone, but trust me, once you pick them up, you’ll never look back. Couple of features I’d recommend looking into are Array methods (map, reduce, filter), async/await, and of course, my favorite - String Literals. &lt;/p&gt;

&lt;p&gt;It’s important to remember, you can always improve your coding skills and write cleaner code. It’s a marathon, not a sprint, so don’t feel overwhelmed if your code is not as clean as it can be. The most important thing is that it works! Over time, as you become more experienced and start adhering to industry standards, you will start writing cleaner code, and even then, there will be tons of room for improvement, just like there always is with everything! So don’t get discouraged, it just takes time.&lt;/p&gt;

&lt;p&gt;I hope that you found this article helpful guide. Until next time, Jelena, signing out...&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>bestpractice</category>
    </item>
    <item>
      <title>Why Your Business Needs a Progressive Web App</title>
      <dc:creator>Bojan Gvozderac</dc:creator>
      <pubDate>Thu, 28 Jun 2018 14:39:48 +0000</pubDate>
      <link>https://dev.to/jsguru_io/why-your-business-needs-a-progressive-web-app-41ee</link>
      <guid>https://dev.to/jsguru_io/why-your-business-needs-a-progressive-web-app-41ee</guid>
      <description>&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%2Fdelivery.eusi.cloud%2Fapi%2Fv1%2Ff1a4305c-e431-4668-ae4c-02f78c656a41%2Fmedia%2Fs3%2F1530179495083_JSG-PWA-Cover.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%2Fdelivery.eusi.cloud%2Fapi%2Fv1%2Ff1a4305c-e431-4668-ae4c-02f78c656a41%2Fmedia%2Fs3%2F1530179495083_JSG-PWA-Cover.png" alt="featured image"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;You ever look at a web site and think: "Everything is either a potato or not a potato…" and more ( or less? ) importantly: "This web site would be great as an app!"? If you did, you're not alone, buddy boy!&lt;/p&gt;

&lt;p&gt;Some very cool folks over at &lt;em&gt;Internet HQ&lt;/em&gt; ( don't fact check this just blindly believe that it exists ) that govern how the internet behaves agree with you ( the potato thing &lt;em&gt;AND&lt;/em&gt; the web site as an app thing! &lt;em&gt;WOW! Look at you go!&lt;/em&gt; ).&lt;br&gt;
They introduced a concept called Progressive Web App - PWA, for short.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;strong&gt;It's called Progressive Web App because it progressively gets better as you use it&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;PWA = Progressive Web Awesome!&lt;/strong&gt;&lt;br&gt;
There are a couple of key things that'll make you want to rock out with PWAs&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Offline Mode&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Imagine this scenario.&lt;br&gt;
You're on a news site and just finished reading an article, at some point in time later you want to reread that same article or show it to somebody else but there's a catch!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You don't have internet access!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If the article you want to read is on a non-PWA site you're EFFED and getting a big fat serving of "No internet connection" screen buuuuuut if the article is on a PWA site you'll be reading your article just fine.&lt;/p&gt;

&lt;p&gt;What PWAs can do is save the web pages you've visited and make them available even when you don't have internet access.&lt;br&gt;
To me this is a &lt;em&gt;game changer&lt;/em&gt;, it mitigates every web site's greatest weakness and, in some cases, completely nullifies it!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Push Notifications&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Lets take a look at another scenario.&lt;/p&gt;

&lt;p&gt;You own an e-commerce site and looking at your web site analytics reports you came to the conclusion that a lot of your visitors come to your online store, look at items, think about buying something, maybe even go through some of the purchase process and then just leave never to be seen again.&lt;/p&gt;

&lt;p&gt;What PWAs can do for you is send &lt;em&gt;push notifications&lt;/em&gt; that feel natural and look native to the device your visitors are using - even if the browser isn't open on their device - to let them know that the item they've been looking at earlier is, for example, discounted and with the click of a button can place them back in the purchase process where they've left off.&lt;/p&gt;

&lt;p&gt;The takeaway is clear.&lt;br&gt;
Having a PWA site is like having a sales person working around the clock on bringing you new customers or re-engaging with old ones, letting them know you still value their business.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A really good example is Jumia. There's a link later in the blog, make sure you check it out.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Web Share&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In this scenario…&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I'm kidding! No scenario for this one. Phew!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Kidding aside, the ability to share content between apps and platforms in the modern world is absolutely necessary.&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Web share invokes the devices native share functionality, this means that any app or platform that has allowed sharing on it PWAs will be able to share content with that app or platform.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I lied we're gonna go through a scenario&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Say you own a business and sharing content is a key part of your online marketing strategy.&lt;br&gt;
When you first hired a web development studio they integrated Facebook and Twitter sharing and that was perfect at the time but later on your business has grown and expanded to, lets say, China. &lt;em&gt;Nice!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now you need to integrate sharing on WeChat. In order for you web development team to integrate WeChat they need to read the developer documentation ( which may or may not be translated to a language your developers are comfortable with ), next they need to write the code, after that they need to test if the new code works and also that it doesn't break any of the old functionality.&lt;/p&gt;

&lt;p&gt;All of this work costs money - hundreds if not thousands of dollars that could have gone somewhere else like marketing for your product.&lt;/p&gt;

&lt;p&gt;With PWAs all of this avoided because writing one sharing functionality covers all relevant platforms for your web app visitors.&lt;br&gt;
&lt;em&gt;Share away my wayward son!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cuts Costs&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In most cases businesses don't need anything more than a web site to be present and relevant online but in other cases they need a small part of functionality that is reserved only for native devices.&lt;/p&gt;

&lt;p&gt;This &lt;em&gt;forced&lt;/em&gt; businesses to invest in costly native apps for both Android and iOS which can cost anywhere between $20 000 and $120 000.&lt;/p&gt;

&lt;p&gt;PWAs want to solve this by making web sites more like native apps and extending their functionality with device native features, as a result it cuts costs significantly because companies now have to develop only for one platform instead of three.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks PWA!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Progressive Web Apps turn a boring old web site that's just THERE to an indispensable tool for converting visitors to clients&lt;/strong&gt;&lt;/strong&gt;&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%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F0%2AaQfUDPQI2r-UUG-X.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%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F0%2AaQfUDPQI2r-UUG-X.png" alt="success stories image"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Success Stories&lt;/em&gt;&lt;br&gt;
Still not convinced that PWAs are the sauce of awesome? Fine, lets ask these upstanding businesses:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AliExpress ( &lt;a href="https://developers.google.com/web/showcase/2016/aliexpress" rel="noopener noreferrer"&gt;LINK&lt;/a&gt; )&lt;/em&gt;&lt;br&gt;
Aliexpress is a popular e-commerce site that lets you order items directly from China.&lt;/p&gt;

&lt;p&gt;After migrating their site to PWA these are the results they saw:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;104% for new users across all browsers; 82% increase in iOS conversion rate&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;2X more pages visited per session per user across all browsers&lt;/li&gt;
&lt;li&gt;74% increase in time spent per session across all browsers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Jumia ( &lt;a href="https://developers.google.com/web/showcase/2016/jumia" rel="noopener noreferrer"&gt;LINK&lt;/a&gt; )&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Jumia is a leading e-commerce site in Africa. I'm gonna highlight the challenge that they faced ( taken from the LINK above )&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nearly a quarter of shopping carts were abandoned on Jumia's mobile site every day.&lt;br&gt;
To counter this, they reminded customers via email to complete their purchases. But getting people to provide their email addresses is challenging, and email open rates are low. With over 65% of their web traffic on mobile browsers, Jumia looked to progressive web app technologies like Push Notifications to solve their problem and re-engage mobile users who had abandoned carts.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What PWA did for them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;38% Open rate&lt;/li&gt;
&lt;li&gt;9X more conversion on previously abandoned carts from web push users&lt;/li&gt;
&lt;li&gt;7.85% conversion rate on previously abandoned carts from web push users, vs. 4.5% for native app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Twitter ( &lt;a href="https://developers.google.com/web/showcase/2017/twitter" rel="noopener noreferrer"&gt;LINK&lt;/a&gt; )&lt;/em&gt;&lt;br&gt;
C'mon… I'm not gonna explain Twitter to you, you know what it is.&lt;/p&gt;

&lt;p&gt;Twitters PWA became the default web experience on mobile devices in April 2017.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note from the Engineering Lead:&lt;br&gt;
Twitter Lite is now the fastest, least expensive, and most reliable way to use Twitter.&lt;br&gt;
The web app rivals the performance of our native apps but requires less than 3% of the device storage space compared to Twitter for Android.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;65% increase in pages per session&lt;/li&gt;
&lt;li&gt;75% increase in Tweets sent&lt;/li&gt;
&lt;li&gt;20% decrease in bounce rate&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;You Want a Piece of This?!&lt;br&gt;
So you saw the greatness of PWA and want to get in on the action.&lt;br&gt;
You could spend months learning the necessary technology and how to write PWA code or you could head on over to &lt;a href="//jsguru.io"&gt;jsguru.io&lt;/a&gt; and let us do all the heavy lifting for you.&lt;/p&gt;




&lt;p&gt;Before you go…&lt;br&gt;
If you enjoyed reading this post please share it. You should check out our other publications, you might like them too! We write from time to time about software development, tips and tricks, and how to become a better developer and business person in general. Join us on the journey of constant improvement!&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://www.facebook.com/jsguruio/" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;, &lt;a href="https://twitter.com/jsguru_software" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.linkedin.com/company/jsguru" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/jsguru" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; or &lt;a href="https://dev.to/jsguru_io"&gt;DEV.to&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="//jsguru.io"&gt;jsguru.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>progressivewebapps</category>
      <category>business</category>
      <category>webdev</category>
      <category>startup</category>
    </item>
    <item>
      <title>React image lazy load component Revisited</title>
      <dc:creator>Bojan Gvozderac</dc:creator>
      <pubDate>Thu, 24 May 2018 08:06:31 +0000</pubDate>
      <link>https://dev.to/jsguru_io/react-image-lazy-load-component-revisited-4dej</link>
      <guid>https://dev.to/jsguru_io/react-image-lazy-load-component-revisited-4dej</guid>
      <description>&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3s28bia94sk35q3v5487.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3s28bia94sk35q3v5487.png" alt="title image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A long a$$ time ago I created a simple React component that would lazily load an image and while it’s busy loading an image it would show a placeholder and wrote a tutorial how I did it. It is inspired by Polymer’s iron-image and a neat little trick how to transition from placeholder to loaded image.&lt;/p&gt;

&lt;p&gt;The Magic&lt;br&gt;
While playing around with Polymer (shameless &lt;a href="https://medium.com/jsguru/polymer-tonnes-of-potential-not-quite-there-yet-f7516a65c96d" rel="noopener noreferrer"&gt;LINK&lt;/a&gt; to another article I wrote) I learned that you can make a pretty cool “Blur Up” animation by taking the image you want to show, scaling it down to 1% of its width and height, using that as the placeholder and when the original size image is done loading you fade it in over the placeholder.&lt;/p&gt;

&lt;p&gt;This creates an effect that looks like a blurred image hinting what it’s supposed to show suddenly sharpening to reveal the original image.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6fxt34nkz0pc3qd028ky.gif" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6fxt34nkz0pc3qd028ky.gif" alt="bad@$$ demo gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sweet!&lt;br&gt;
The Reaction&lt;br&gt;
He he… see what I did there? The title is The Reaction and we’re talking about a React component! …I’m sorry you had to read that.&lt;br&gt;
When I released my component into the wild I thought it wouldn’t be interesting to a lot of people since it’s a relatively basic component but to my surprise the interest for my component started growing and growing.&lt;/p&gt;

&lt;p&gt;Thanks React community! Appreciate it!&lt;br&gt;
The article I wrote keeps getting views and claps and according to medium statistics the activity is coming mostly from google search!&lt;/p&gt;

&lt;p&gt;It made me really happy that I found a topic that continues to interest the React dev community and that I offered a possible solution to a problem as well as shared some of my knowledge.&lt;/p&gt;

&lt;p&gt;The Realization&lt;br&gt;
Looking at everything that’s happening something dawned on me…&lt;/p&gt;

&lt;p&gt;While the article explaining the concept behind image lazy load and the neat trick I learned from Polymer is cool, the component it self sucked big time.&lt;/p&gt;

&lt;p&gt;That’s why I decided to rework the component and publish it on npm as a library!&lt;/p&gt;

&lt;p&gt;The Good Stuff&lt;br&gt;
If you’re lookin’ for that sweet sweet component to use in your sweet sweet project then head on over to sweet sweet npm and install it (sweet sweet &lt;a href="https://www.npmjs.com/package/react-image-lazy-load-component" rel="noopener noreferrer"&gt;LINK&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;If you’re looking for the Github page you can find it here (&lt;a href="https://github.com/jsguru-io/react-image-lazy-load" rel="noopener noreferrer"&gt;LINK&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Before you go…&lt;br&gt;
If you enjoyed reading this post please share it. You should check out our other publications, you might like them too! We write from time to time about software development, tips and tricks, and how to become a better developer and business person in general. Join us on the journey of constant improvement!&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://www.facebook.com/jsguruio/" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;, &lt;a href="https://twitter.com/jsguru_software" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.linkedin.com/company/jsguru" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/jsguru" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; or &lt;a href="https://dev.to/jsguru_io"&gt;DEV.to&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://jsguru.io/blog/React-image-lazy-load-component-Revisited" rel="noopener noreferrer"&gt;jsguru.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Top 10 reasons to upgrade your Angular Application</title>
      <dc:creator>Boris Joskic</dc:creator>
      <pubDate>Thu, 03 May 2018 12:01:09 +0000</pubDate>
      <link>https://dev.to/jsguru_io/top-10-reasons-to-upgrade-your-angular-application-5dlg</link>
      <guid>https://dev.to/jsguru_io/top-10-reasons-to-upgrade-your-angular-application-5dlg</guid>
      <description>&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%2Fcdn-images-1.medium.com%2Fmax%2F1000%2F1%2AbRlKDjxqkQTfgEz40jdftA.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%2Fcdn-images-1.medium.com%2Fmax%2F1000%2F1%2AbRlKDjxqkQTfgEz40jdftA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Angular is a popular JavaScript framework, used to create web, desktop and mobile applications. It is built and maintained by Google.&lt;/p&gt;

&lt;p&gt;Angular 5 (codename pentagonal-donut) was released on November 1, 2017, a major release containing new features, and focusing on making your Angular application faster, smaller and easier to use.&lt;/p&gt;

&lt;p&gt;So, with all these new features, what are top 10 reasons you should upgrade to Angular 5?&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1) Performance&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Angular 5 will make you application smaller and much faster. Angular CLI v1.5 comes with a build optimizer turned on by default and Angular compiler is improved to enable faster builds and rebuilds. Size of the bundle is reduced by removing AST classes, only changed files are emitted for incremental compilation and much more. Ahead of time compiler is turned on by default and it is much faster than in Angular 4. It’s different from Just In Time compilation because it converts Angular Typescript into JavaScript code before the browser downloads and runs it. The Just In Time compiler was compiling application at runtime. Using AOT gives faster rendering, smaller download sizes and detects template errors earlier. This makes Angular 5 faster in development and production.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2) Progressive Web Apps&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A Progressive Web App (PWA) is a web application that uses modern web capabilities to deliver an app-like experience to users. It is an experience that combines the best of the web and mobile applications.&lt;/p&gt;

&lt;p&gt;A Progressive Web App works for every user, regardless of their browser, it’s responsive, always up-to-date thanks to service workers, and if served via HTTPS, it’s safe as well, and all the while it feels like a real app!&lt;/p&gt;

&lt;p&gt;Right now, the development of progressive web applications a complex process. One needs to take care during both development and deployment that neither caching nor the delivery of older versions is impaired.&lt;/p&gt;

&lt;p&gt;This has changed with Angular 5. The development of progressive web applications should be simplified so they can even be created by default.&lt;/p&gt;

&lt;p&gt;With Angular-CLI, Angular has the ability to create configuration and code on its own. Essentially, this allows the creation of mobile web applications that have features of native mobile applications, like offline capability, push notifications and an application logo in the start menu of a particular platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3) Build Optimizer&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The Angular team focused on making Angular 5 faster, smaller and easier to use. In Angular 5, production builds created with the Angular CLI will now apply the build optimizer by default. The build optimizer is included in Angular CLI.&lt;/p&gt;

&lt;p&gt;The build optimizer removes parts of your application that are not needed, and it removes Angular decorators from your application’s runtime code. Decorators are used by the compilers and are not needed at runtime and can be removed.&lt;/p&gt;

&lt;p&gt;This reduces the size of your JavaScript bundles, and increases the boot speed of your application!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4) HttpClient&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before version 4.3, @angular/http was used for making HTTP requests. HTTP is now deprecated and the HttpClient API from @angular/common/http package that shipped in version 4.3 is now recommended for use in all apps.&lt;/p&gt;

&lt;p&gt;Some of the features include&lt;/p&gt;

&lt;p&gt;● JSON is an assumed default and no longer needs to be explicitly parsed&lt;/p&gt;

&lt;p&gt;● Interceptors allow middleware logic to be inserted into the pipeline&lt;/p&gt;

&lt;p&gt;● Progress events for both request upload and response download.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5) New router lifecycle events&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Router has new lifecycle events, allowing you to track the cycle of the router from the start of running guards through to completion of activation. These events could be used for things such as showing a spinner on a specific router outlet when a child is updating or to measure performance of guards and/or resolvers.&lt;/p&gt;

&lt;p&gt;This new lifecycle events are GuardsCheckStart, ChildActivationStart, ActivationStart, GuardsCheckEnd, ResolveStart, ResolveEnd, ActivationEnd, ChildActivationEnd.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;6) CLI&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Starting with Angular CLI version 1.5, support for Angular 5 is added and the CLI generates v5 projects by default and build optimizer is also turned on. By default, the build-optimizer plugin will now be applied to your build if you are using Angular 5 and building in AOT.&lt;/p&gt;

&lt;p&gt;Build command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ng&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;prod&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;optimizer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is now simplified to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ng&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;prod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Angular CLI will also warn you if you are using version of TypeScript which is not the recommended one for your Angular version. You can deactivate the warning (only if you believe in yourself and you know what you are doing) with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ng&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;typescriptMismatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;7) Forms&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To improve performance, we can now specify when validators should be executed. Every time a value is changed, the validation will most likely be performed with every keystroke!&lt;/p&gt;

&lt;p&gt;In Angular 5, forms have the ability to decide when the validity and value of a field or form are updated via on blur or on submit, instead on every input event. This can drastically improve performance!&lt;/p&gt;

&lt;p&gt;To improve performance, you can now specify when validators should be executed in forms.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;8) Pipes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In previous versions, Angular has relied on the browser to provide date, number and currency formatting using browser i18n API’s. Users were seeing inconsistent results across browsers.&lt;/p&gt;

&lt;p&gt;Angular 5 comes with new date, number and currency pipes.&lt;/p&gt;

&lt;p&gt;Pipes rely on the &lt;a href="http://cldr.unicode.org/" rel="noopener noreferrer"&gt;CLDR&lt;/a&gt; to provide locale support and configurations for any locales you want to support.&lt;/p&gt;

&lt;p&gt;Here is a &lt;a href="https://docs.google.com/spreadsheets/d/12iygt-_cakNP1VO7MV9g4lq9NsxVWG4tSfc98HpHb0k/edit%23gid=0" rel="noopener noreferrer"&gt;document&lt;/a&gt; that compares pipes between v4 and v5.&lt;/p&gt;

&lt;p&gt;You are not ready for the new pipes? You can import DeprecatedI18NPipesModule after the CommonModule.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;9) Incremental builds&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A lot of improvements have been made to the Angular compiler to make it faster, and it now enables faster builds and rebuilds. Ahead of time and incremental builds are possible when using &lt;em&gt;–aot&lt;/em&gt; with &lt;em&gt;ng serve&lt;/em&gt; command. This will probably be used by default in a future version of the Angular CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;10) Better Typescript and RxJS support&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;RxJS version 5.5 introduces a new way of using RxJS called ‘lettable operators’. Any operator can now be imported from rxjs/operators. These new operators eliminate the side effects and the code splitting / tree shaking problems that existed with the previous method of importing operators. New Angular CLI will pull this version by default and will save considerably on the bundle size!&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AwDkdwUhMM555aZ8J.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AwDkdwUhMM555aZ8J.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Would you like to upgrade your application to Angular 5?
&lt;/h3&gt;

&lt;p&gt;The Angular team built a &lt;a href="https://angular-update-guide.firebaseapp.com/" rel="noopener noreferrer"&gt;nice tool&lt;/a&gt; to make upgrading as easy as possible or &lt;strong&gt;send us a message&lt;/strong&gt; at &lt;a href="//mailto:info@jsguru.io"&gt;info@jsguru.io&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before you go…
&lt;/h3&gt;

&lt;p&gt;If you enjoyed reading this post please &lt;strong&gt;share&lt;/strong&gt; it. You should check out our other publications, you might like them too! We write from time to time about software development, tips and tricks, and how to become a better developer and business person in general. Join us on the journey of constant improvement!&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://www.facebook.com/jsguruio/" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;, &lt;a href="https://twitter.com/jsguru_software" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.linkedin.com/company/jsguru" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/jsguru" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; or &lt;a href="https://dev.to/jsguru_io"&gt;DEV.to&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://jsguru.io/blog/Top-10-reasons-to-upgrade-to-Angular-5" rel="noopener noreferrer"&gt;&lt;em&gt;jsguru.io&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>angular5</category>
      <category>angularcli</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
