6 ways to improve Lighthouse
Tags: react, javascript, webdev, lighthouse
Published: 2020-09-05 11:52:32

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bnpowi7usqr3bxclytpw.PNG)

`Lighthouse` it's a tool that can help us improve the website in several aspects: Performance, Accessibility, Best Practices, SEO, and PWA. If you don't know how to use `Lighthouse,` open the `dev tools` in chrome on any website, then search for the `Lighthouse` tab and run a test (you can also run it from the command line, or as a Node module). 
Before we start, I want to mention some ground rules about how to test it correctly. First, **remember always run the test on `incognito window.`** why? Because on a regular chrome window runs many apps (like chrome extension) that interfere with the `Lighthouse` test. Seconde, **remember that can be the difference between test to test** (especially in Performance test). I found an excellent explanation of why there are differences from test to tet in this article [Lighthouse Changes How Performance Score is Calculated](https://calibreapp.com/blog/lighthouse-changes-scoring-algorithm). So, if, for example, the performance test shows: 100, 80, 90, 95, it's okay because you are in the 90-100 range. But, if the test shows: 80, 68, 85, 75, it implies performance issues because you are in the 70-80 range and need to check how to improve it. Let's dive into the steps to improve the scoring.

### 1. Choose a good hosting
It may seem obvious to many developers, but hosting is one of the most important things when you want to check the website performance. For example, I used [Heroku](https://www.heroku.com/) that, in my opinion, is one of the best hostings, but in the free mode, the server goes to "sleep" after half an hour. The "sleeping mode" influenced performance scoring, so I changed to [Netlify](https://www.netlify.com/). It made a lot of difference in the scoring.

### 2. Make a general order in the files
Delete unnecessary files like images, javascript files, HTML files, CSS files, etc. Check again for unnecessary lines in the code, and if it is not in use **Delete them, don't make them comment**. Why? Because any line adds size to the file. Maybe, on small projects, the number of lines does not have a significate impact on the performance score, but it does on large projects.  

### 3. Compress, compress and compress again
One of the best ways to improve performance scoring is by compressing. You can use these tips:
* **compress images**: You can build your own compress API in the server or use image CDN that offers this service. My solution was to use image compressor online like [imagecompressor](https://imagecompressor.com/)(there a lot of other compressors online on the web) before uploading the image to the project.
* **compress from the server-side**: If you are using node.js to serve the build folder, you can use the `compression` package: 
```javascript
let compression = require('compression');
app.use(compression());
```
You can see the full code in my GitHub : [portfolio-server](https://github.com/tomeraitz/portfolio/blob/master/server.js)
* **compress in the build process**: you can compress the build folder files by the package `gzipper` (npm install) and add this to the package.json :
```json
  "scripts": {
    "build": "node scripts/build.js && gzipper compress ./build",
    ...
  }
```
### 4. Implement lazy loading
Let's think about how the browser loads the js files. **If the browser sees the `<script>` tag it stops the HTML parsing process (a.k.a "block") downloads and executes the script.** In HTML5, `defer` and `async` attributes change the browser's behavior about the javascript execution order. (I won't expand on the subject, but if you want more information, I found an interesting discussion on the subject on StackOverflow: [How are JavaScript files loaded and executed?](https://stackoverflow.com/questions/2392147/how-are-javascript-files-loaded-and-executed)). So after we understood what is "blocking," let's talk about React. Usually, in React, we do `import component from '../ ...` from all the components to the app(the father), **the browser will ship all of the scripts in the beginning.** The solution is `lazy loading` (code-splitting) components, **`lazy loading` helps you to ship to the browser only the components that are in use on the page.** (for more information you can look on [code-splitting-suspense](https://web.dev/code-splitting-suspense/)). for example : 
```javascript
import React, { Component , Suspense ,lazy} from 'react';
import './App.css';
import LoadPage from './components/LoadPage';
const Main = lazy(() => {
  return new Promise(resolve => {
    setTimeout(() => resolve(import('./components/Main')), 5000);
  });
});
class App extends Component {
  render() {
    return (
      <div>
        <Suspense fallback={<LoadPage />}>
          <Main></Main>
        </Suspense>
      </div>
    )
  }
}
export default App;
```
You can see the full code in my GitHub : [portfolio-App.js](https://github.com/tomeraitz/portfolio/blob/master/src/App.js).
* The `Main` is a functional component.
* The regular syntax for lazy import is: `lazy(() => import('./components/Main'));`, but I wanted delay the import to extand the loading animation.
* `<Suspense fallback={<LoadPage />}></Suspense>` will load the loadPage until the main page is loaded.

### 5. optimize SEO score
> SEO stands for Search Engine Optimization, which is the practice of increasing the quantity and quality of traffic to your website through organic search engine results.

From [moz.com](https://moz.com/learn/seo/what-is-seo).
In the technical point of view, there are some cases we can add to the HTML for improving the SEO score:
* Add `title` to your HTML (inside the `head` tag).
* Add `<meta name="viewport">` tag with width or initial-scale.
* Add document has a meta description (subtitle on google search) like:
```HTML
 <meta name="description" content="Specializing in JavaScript and js frameworks. I believe in elegant solutions for complex problems. If you are seeking for a developer, you can get in touch with me here.">
```
* Add robots.txt to the project. In simple words, the robots.txt in charge of blocking crawlers on parts of your website.
* Add `alt` attribute to `<img>` tag. Explain what the picture is.

### 6. General score improving
* Add SSL to your website (from HTTP to HTTPS).
* Add `label` tag to `input` tag like :
```HTML
<input className="input-small" type="text" id="name" placeholder="Your Name" name="name" value={state.name} onChange={this.handleFields} />
<label htmlFor="name">Your Name</label>
```
If you want to hide the `label` tag you can just add this to the CSS:
```CSS
label{
    font-size: 0;
    height: 1px;
}
```
You can view the project on GitHub: [Tomer-portfolio](https://github.com/tomeraitz/portfolio). I may forget other ways to improve scoring. I encourage you to leave a comment on things that can add to this subject or let me know what you think about this article.