Web Performance - Renderland's Saga, Book 2
Published: 2022-05-22 20:12:33

---
title: Web Performance - Renderland's Saga, Book 2
published: true
date: 2022-05-20 20:09:37 UTC
tags: 
canonical_url: https://eman.hashnode.dev/web-performance-renderlands-saga-book-2
---

# The Galactic Federation 👮🏽👽🧝🏾🤖 - Fourth Act

> Despair and frustration will not shake our belief that resistance is the only way to liberation. - Emile Lahoud.

In the first [part](https://dev.to/junubiman/web-performance-renderlands-saga-book-1-2mkp) of the series, we learned about Renderland's history, its new savior, and the invaders who sought to destroy the planet.

The Galaxy is governed by a federation known as the `Feds` or the `Federalis`, they are an intergalactic organization that governs thousands of planets and galaxies including the `Web Galaxy`.

### The Bugs 👾

A coalition of criminals who were sentenced to and then escaped from the `Devil's Planet` intergalactic prison, a maximum-security prison for the galaxy's worst of the worst. The bugs seek to dismantle the `Feds`.

The attack on Renderland was the first of many attacks that soon followed after. Their primary goal is to destroy the Pillars and Federation's `RAIL Model` in Renderland and eventually the entire Federation.

### RAIL Model 🛤

RAIL is a user-centric performance model developed by the `Feds`. It provides a structure for thinking about performance. The model breaks down the user's experience into key actions (for example, tap, scroll, load) and helps you define performance goals for each of them.

![two-Page-2.drawio.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1653076266009/5eBdEsaAum.png)

#### Response 

is the time it takes from user interaction (such as a tap) to paint. Basically its the time between user interactivity and feedback from the interaction

Based on human perception, it's recommended that user-initiated actions are responded to within 100ms in order to make users feel like their interactions are instantaneous.

#### Animation 🅰

Animation is a technique used to make objects appear like they're moving. The `Feds` have defined a budget for each frame in animation which is 16 ms (1000 ms / 60 frames per second 16 ms).

Browsers generally need an average of 6 ms to render a single frame, that's why the guideline recommends 16 ms per frame.

Humans view animations that take 16ms or less per frame as fluid, smooth and consistent

#### Idle 

Maximize idle time to increase the odds that the page responds to user input within 50 ms. Complete work in 50ms chunks so as to give the user a sense that the page is responsive

#### Load 💔

Loading pages should be seamless and in order to acquire that, the recommended time a page should take to load is 1000ms (1s).

When pages load slowly, user attention wanders, and users perceive the task as broken. Sites that load quickly have longer average sessions, lower bounce rates, and higher ad viewability.

## The Chairman 🏾

A bearded elderly man appeared to us in hologram form to assure us that the federation is fully aware of Renderland's situation and is currently mobilizing re-enforcements to rescue the planet. They've shared a list of measures to be taken to hold back the bugs until help arrives.

It was later revealed that the elderly man was the Federation's chairman and it was non-other than [Dennis Richie](https://en.wikipedia.org/wiki/Dennis_Ritchie)!

**Here is what you can do to stall the bugs until re-enforcements arrive**

- Code Split
- Compress, Cache, and Minify (CCM)
- Optimize Images

## Code Splitting

The natives had the ability to split and control their body parts at will. This makes it possible to split code into various bundles or components which can then be loaded on-demand or in parallel.

![code-splitting.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1653065397990/HqSAqz-zM.png)

**💡 There are two main types of `code-splitting`.**

### Route Based 🚏

Route-based code-splitting is a method of delivering code in chunks based on user navigation.

### Component-Based 

Component-based code splitting is a method that's used in component-based frameworks/libraries such as React.js and Vue.js.

## Caching

Besides `Minification`, the natives of Renderland also had the ability to create clones of themselves to be used in `Cacheland`.

Caching is the process of storing copies of files in a `cache`, or temporary storage location so that they can be accessed more quickly. Caching can be done on both the server-side and client-side.

**💡 There are two main types of `caches`.**

### Server-Side Cache

Server-side caching is beyond the scope of this article but you can utilize a `NoSQL` key-value store such as `Redis` to perform caching. Redis also provides a `Client-Side` caching mechanism but I haven't tried it yet. You can learn more about it [here](https://redis.io/docs/manual/client-side-caching/).

### Client-Side Cache

The process of caching assets on the client-side of things. This can be done via `HTTP` or a `Service Worker`.

#### Browser (HTTP) cache

When a browser visits a page for the first time, it stores copies of assets in its HTTP cache. It then serves non-expired requests from the cache. HTTP deals with time-based (TTL) resources.

HTTP caching occurs when the browser stores local copies of web resources for faster retrieval the next time the resource is required. As your application serves resources it can attach cache headers to the response specifying the desired cache behavior

##### HTTP Cache Headers

Browser caching can be controlled via HTTP header options that can be set on the server.

- `Cache-Control`
- `ETag`
- `Last-Modified`

#### Service worker cache

Service Worker caching requires a `fetch` event handler in an app's `service worker` file. Network requests are intercepted and responses are served from the worker's cache whenever possible.

It's generally recommended to not `re-invent the wheel` when developing production applications. Use [Workbox](https://developer.chrome.com/docs/workbox/) instead of rolling out your own workers if possible.

![1_oOcY2Gn-LVt1h-e9xOv5oA.jpeg](https://cdn.hashnode.com/res/hashnode/image/upload/v1653064900956/cp1j0VdRk.jpeg)

#### Lifecycle

Before you could use a service worker, you must first `register` it via the `ServiceWorkerContainer.register()` method. The worker's lifecycle begins after it's successfully registered.

**💡Events**

To utilize workers, you'd generally listen for `events` on a worker and then respond accordingly.

#### Download

The worker is downloaded into the client.

#### Install

The worker is being installed. If successful, then this is a good time to prepare the worker for usage.

#### Active

Installation is successful and the worker is ready to receive events. The point where this event fires is generally a good time to clean up old caches and other things associated with the previous version of your service worker.

**💡 Caching `strategies`:**

#### Cache only

Generally used for content that's considered static to a particular "version" of a website. They're usually cached in the `install` event of a service worker.

**💡 It's good for:**

- Static content.

#### Cache, falling back to the network

Generally used for building apps that are intended to be offline-first.

**💡 It's good for:**

- Application shell and common resources such as logos.

#### Network only

This strategy skips the cache and sends requests directly to the server. It's mainly used when your app requires content to always be up to date. It's also ideal for requests that cannot be cached such as `POST` or `PUT` requests.

**💡 It's good for:**

- Payment related applications
- Content that changes frequently.

## Compression

In the previous part, the bugs have infected `unoptimized` assets with a virus that caused them to grow in size which makes it difficult for them to travel and respond to requests.

The `A-Team` came up with a temporary technique to reduce their sizes thus reducing their transfer times. This technique is known as `compression`.

### HTTP Compression

**💡 There are mainly two types**

- **Lossless** means you can retrieve the original data.
- **Lossy** means you might not get the original data due to a change in its quality.

## Minification

Minification refers to the process of making assets smaller by removing comments, unnecessary characters, and white spaces.

## Optimize Images

Optimizing images allows the creation and display of images using the best format, size, and resolution according to network and device constraints.

### Formats

There are new image formats that were developed specifically for the web. They offer greater compression and quality benefits.

- [WebP](https://developers.google.com/speed/webp) is a format created by Google and it was intended as a replacement for `jpeg`, `PNG`, and `gif` formats. 

### Accessibility

Adding `ALT` tags can bring about accessibility benefits and a better user experience for users who fail to load images due to network or device constraints.

```
<figure>
    <img src="awesome-photo.png" alt="An awesome photo!!" />
</figure>

```

A well-written `ALT` tag can help your users visualize an image if it fails to load for whatever reason. It can also help images rank higher in search.

### Aspect ratio and `srcset`

#### `srcset`

This is an HTML attribute that allows you to specify different image sources to serve depending on factors such as the width of a device or its resolution.

#### Aspect ratio

Not using the appropriate aspect ratio can cause `cumulative layout shifts`.

### Lazy-loading

Setting an image's `loading` attribute to `lazy` can help the browser prioritize when to load the image

## Rendering Patterns

We've previously discussed the two main rendering patterns, namely `Client Side Rendering (CSR`) and `Server Side Rendering (SSR)`. Now it's time to introduce some new rendering patterns that combine the best of the two worlds.

#### Static Generation

A static site generator is a tool that generates a full static HTML website based on raw data and a set of templates.

#### `SSR` with Rehydration 🌨

This pattern uses a `pre-built` DOM with components rendered as HTML. The app then loads the remaining data in the client side.

#### CSR with Pre-rendering 🚧

This pattern renders an `app shell` to static HTML during build time .

* * *

## The Reinforcements 🚀 - Fifth (Final) Act

> Geography has made us neighbors. History has made us friends. Economics has made us partners. And necessity has made us allies. Those whom nature hath so joined together, let no man put asunder. - John F. Kennedy

The `Render League` and the `A-Team` has followed the Federation's advice and they managed to hold some of the bugs back. However, the danger still remains as the bugs were still fixed on destroying the pillars.

The techniques listed in the previous act could enhance an app's performance but they aren't really sufficient. Modern apps are quite complex and they contain many moving parts.

## Frameworks 

A squad of elite Federation warriors known as the Frameworks has finally arrived at the scene. They were described as evolved forms of `Scripts`. They were.

Dennis Richie has previously mentioned that `Scripts` have the ability to transform just like the `Super Saiyans` in [Dragon Ball](https://en.wikipedia.org/wiki/Dragon_Ball). This transformation gives `JS` a set of new powers and abilities that will make it easier to fight the bugs. Dennis revealed that the current form of JS is known as `Vanilla` and that it could evolve into much more powerful forms.

### React.js

> React is a free and open-source front-end JavaScript library for building user interfaces based on UI components.

At its core lies the mechanism that tracks changes in a component state and projects the updated state to the screen.

The virtual DOM (VDOM) is a programming concept where an ideal, or virtual, representation of a UI is kept in memory and synced with the real DOM by a library such as ReactDOM. This process is called reconciliation.

#### Code-Splitting

Code splitting in React can be achieved using a bundler like `Webpack` or `Browserfy`.

##### Before

```

import { robot } from './js';

console.log(robot(16, 26));

```

##### After

```

import("./js").then(robot => {
  console.log(robot.add(16, 26));
});

```

* * *

## Conclusion

Book 1 introduced a lot of concepts and book 2 expanded upon them. Book 3 shall include practical examples of most of the concepts presented in this article.

It's highly recommended to spend extra time reviewing and practicing these concepts. Learning by doing is most often the best way to learn IMHO.

![Screen Shot 2022-05-20 at 05.19.10.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1653013166109/PGmJfqLIz.png)

## Resources 📚

- [Offline Cookbook](https://web.dev/offline-cookbook/) by [Jake Archibald](https://twitter.com/jaffathecake).
- [Chrome Developers Blog](https://developer.chrome.com/tags/performance/).
- [Web Dev](https://web.dev/learn-web-vitals/).
- [Service worker caching and HTTP caching](https://web.dev/service-worker-caching-and-http-caching/)
- [Aero Twist's Blog](https://aerotwist.com/blog/).
- [Reach Docs](https://reactjs.org/)

* * *

NB: Part 3 of this series will explore the practical aspects of web rendering performance. I decided to break it into parts because I don't want to overwhelm the reader.

**Fun Fact: This article's story line was inspired by**

- This other [Tweet](https://twitter.com/JemYoung/status/1517574351645667328)
- Dragon Ball
- Rick and Morty (Season 1)
- read this https://twitter.com/adamlbunch/status/1527316680258383874/photo/1

**See you in Part 3!**