Skip to content

Latest commit

 

History

History
340 lines (213 loc) · 9.99 KB

README.md

File metadata and controls

340 lines (213 loc) · 9.99 KB

Web Performance Notes 🏎️

🥸 The First Problem - If the website is slow

👉 We are losing $$$$ because of less conversion, bad user experience
👉 It's mostly Frontend Responsibilities

You're already doing things below to optimize the website

Here is The List 👉 Optimize Network Transfer
👉 Working with HTTPS and HTTP2
👉 CSS as Appetizer
👉 JavaScript
👉 Optimizing Images
👉 Defining Policy for HTTP Cache
👉 Using Service Worker

🚨 It turns out the time to Interatice on the website is still SLOW, as page load time goes from 1s to 10s, the probability of a mobile visitor to bound INCREASE BY 123%, we're losing client and money

🥸 Not Bandwidth, The problem with browsing speed on the web is LATENCY

👉 Latency is the TIME DELAY between when a data packet is sent and when it's received (express in milliseconds)
👉 EVERY Http Request to get the Response Will Have a LATENCY

👨🏻‍💻 We also have CPU and GPU problems

CPU and GPU problems


METRICS to the Rescue

We can't improve what we can't measure

BROWSER-CENTRIC METRICS

Here is the List 👉 Time to First Byte (TTFB) - browser sending http request to the server to get the response, this metric is all about time for the browser to load the first Byte from the response

👉 First Paint - First time browser paint something to the screen

👉 Page Load (Not using this event anymore at modern day)

👉 Browser centric metrics are NOT SO IMPORTANT for WEB PERFORMANCE OPTIMIZATION

USER-CENTRIC METRICS

First Interactive (Time Interactive)

👉 Simply means: The Main Thread has been Released, at least for several miliseconds
👉 Browser ONLY HAVE 1 THREAD, Single Thread

Speed Index

Below is the image process of content loading on the web of Gmail and Amazon Even Page Load Time is the same for both.
👉 BUT the user will have the FEELING of Amazon is Faster
👉 Speed Index used to measure that Feeling

Amazon and Gmail Page Loading

Time to Interactive

👉 Different with first interactive
👉 It's interactive enough for a couple of milliseconds

Largest Contenful Paint (LCP)

Custom Metric


CORE WEB VITALS

Today, Core Web Vitals is actually including 3 metrics

Largest Contentful Paint (LCP) - Initial Load

👉 How fast at which point your content appears on the screen

👉 Because it has to do with the screen, it'll be different on different viewport sizes

First Input Delay - FID - Interactivity

👉 at which moment you're releasing the thread enough to interact with the content

Cumulative Layout Shift - CLS - Visual Stability

👉 we dont want the content to ship around while the page load

Interaction to Next Paint = Responsiveness

Perfomance Budget

Where to Optimize?

Where to Optimize

👉 It's Frontend Responsibility
👉 Optimize the Backend has LESS impact and it's not a simple or Cheap Task.

🌟 OPTIMIZE THE FRONTEND HAS HIGH IMPACT, It's relatively CHEAP to optimize and RESULTS are IMMEDIATE.


BASIC OPTIMIZATION

Process of browsing the web

Process of browsing website

Evolution of HTTP: 1.1 -> 2 -> 3

Browser Cache

Typically we gonna focus on the Resource Discovery Queue

How The Cache on Browser Work? 🥸

Browser check the cache to see if we have the version of that file or not.

👉 Define Cache Headers per file

  • Absolute expiration date (1.0) - Example: this file will expired at 4PM, May 21, 2024
  • Relative expiration date (1.1) - Example: this file will expired after 2 months, 1 year,...
  • More specs / values

👉 Browser needs a resource

  1. It checks the Cache
    A) Cache Miss: we go to the network

    B) Cache HIT: the file we need are in the Cache

    🚨 It's Expired --> It's make conditional request

    Server Response Can be:

    1. Not modified (updated cache Header) OR
    2. OK, New File

    🟢 It's NOT expired => We use the file from the Cache


Back / Forward Cache (BF Cache)

👉 It keeps your page navigation in memory if the user navigates away
👉 It's automatic
👉 You shouldn't use unload events, Cache-Control: no-store
👉 Use Page Navigation API to Open / restore Connections Or Abort pending transactions

Service Worker and Cache Storage

Quick Definition of Service Worker

👉 A service worker is a web server written in JavaScript that we install locally on user's device
👉 It's kind of the similar algorithm with the Browser Cache, the difference is that this is written by us
👉 Instead of relying on the browser's cache, now you have your own cache
👉 Service worker might not help the first initial visit of user, BUT it might help from the second visit, because next time we can serve the files locally
👉 Can improve the core web vital (performance) a lot, because we dont need go to the network every time

One Use Case / Design Pattern for using Service Worker and Cache Storage

Use Case Using Service Worker


RESOURCE LOADING, FRAMES, INTERACTIVITY

👉 JavaScript blocks PARSING BY DEFAULT

Browser is reading the HTML, if it encouters a JS, it will stop parsing
it will not read the rest of the HTML

👉 If we block PARSING, we're ALSO blocking RENDERING, because RENDERING happens AFTER Parsing.

👉 CSS Blocks Rendering

The browse will never render the pixel on the screen if ALL the CSS that is known at that moment was not downloaded and parsed.

Some Basic Performance Opitmization

Here is the Long List => Open to Read 👇
👉 Enable GZIP on text-based files (HTML Static and Dynamic), JS, CSS, JSON and SVG

👉 Make Static Content Expire Late in the FUTURE

👉 Use a CDN for static content (CDN has servers all across over the world => closer to the user => the latencies will be shorter => lead to better user experience)

👉 Consider implementing HTTP/2 and HTTPS

👉 Use cookie-less domain

👉 Reduce cookie size

👉 Reduce Redirects (redirects are expensive)

👉 JavaScript as Dessert => We should DEFER it AS MUCH AS POSSIBLE, it uses the main thread, remove or defer unused code, JS is the most expensive asset that you have in your website

👉 Compress / Obfuscate JS and CSS

👉 Release the Main thread ASAP

👉 Embrace Responsive Images, SVG

👉 Compress Images, Define placeholder size


Advanced Optimizations

Optimizing the FIRST LOAD

➡️ Avoid more than one Roudtrip
➡️ Avoid http to httpS redirect (HSTS - HTTP Strict Transport Security) => can save around 150-200 milliseconds

Hacking LCP

by preloading HTML resources

Help the browser discover resources that are obscure in the document
So then your browser will know that CSS or that web file will be needed even before start rendering the HTML

<link rel="preload" href="style.css" as="style" />

Fetch Priority

<link rel="preload" href="style2.css" as="style" fetchpriority="high" />
<link rel="preload" href="otherimage.png" as="image" fetchpriority="low" />

HTTP Early Hints

Http Early Hints

Optimize Data Transfer

➡️ HTTP/3 - transport protocol over UDP, Reduces latency and connection messages, HTTP/2 interface with TLS
➡️ Use Zopfli (Save 3-8% data transfer with GZIP) but it's 80x slower for compression NOT for decompression
➡️ Brotli (Save 25% data transfer compared with GZIP, check Encoding header)

Optimize Resource Loading

➡️ Use Modern Image Formats (Not just PNG and JPEG) - use SVG for instance
➡️ WebP, AVIF, Zopfl PNG, Guetzli JPEG
➡️ Muted videos instead of GIFs

Squoosh is the open source allow us to convert image

Cache Control, dns-prefetch & preconnect (to warm up the engine)

Lazy loading Images & Fonts

<img loading="lazy" /> <iframe loading="lazy"></iframe>
font-display: optional or swap;

Optimizing Interactions

➡️ We SHOULD NOT doing CLIENT-SIDE RENDERING - it's terible idea for initial load, terible for performance better performance leads to better conversion

➡️ Move HEAVY tasks to WebAssembly

➡️ Stop serving legacy code

➡️ Reactive Web Performance

➡️ Provide a Constistent Experience

➡️ Get Reports from the Browser

Performance APIs

➡️ Performance & Navigation Timing APIs

➡️ Performance Observers

➡️ Animation Frames and Input Pending

➡️ Part of the latest HTML5 spec
➡️ Let us execute code on next frame before paiting it
➡️ It's GUARANTEE to be executed on next frame
➡️ Better than timers (set interval and set time out)
➡️ We should keep code small (< 10ms )

➡️ Request Idle Callback and Script Yielding

➡️ They execute low-priority code before each frame, if there is enough idle time
➡️ It sends an argument where we can query how much time is left before idle time is gone and next frame should start
➡️ We should stop and schedule a new Idle callback if time is zero