weikee94 / design-patterns

Design Patterns
0 stars 0 forks source link

Render Pattern #18

Open weikee94 opened 1 year ago

weikee94 commented 1 year ago

Web Vitals

| Abbreviation | Full Form | Description | |--------------|----------------------------------|-------------------------------------------------------------------------------------| | TTFB | Time To First Byte | Time it takes for a client to receive the first byte of page content | | FCP | First Contentful Paint | Time it takes the browser to render the first piece of content after navigation | | LCP | Largest Contentful Paint | Time it takes to load and render the page's main content | | TTI | Time To Interactive | Time from when the page starts loading to when it's reliably responding to user input quickly | | CLS | Cumulative Layout Shift | Measures visual stability to avoid unexpected layout shift | | FIP | First Input Delay | Time from when the user interacts with the page to the time when the event handlers are able to run | | Term | Description | |----------------|-------------------------------------------------------------------------------------------------------------| | Compiling | Converting JavaScript into native machine code | | Execution time | The time it takes to execute the previously fetched, parsed, and compiled data | | Hydration | Attaching handlers to a DOM node whose HTML contents were server-rendered, making the component interactive | | Idle | The browser's state when it's not performing any action | | Loading time | The time it takes to fetch the data from the server | | Main thread | The thread on which the browser executes all the JavaScript, performs layout, reflows, and garbage collection | | Parsing | Converting an HTML source into DOM nodes, and generating an AST | | Processing | Parsing, compiling, and executing the previously fetched data | | Processing time| The time it takes to parse and compile the previously fetched data |
weikee94 commented 1 year ago

Client Side Rendering

Render your application's UI on the client ![image](https://github.com/weikee94/design-patterns/assets/13563834/f05c73a7-96f0-492f-8d10-9fac5dc5d349) ![image](https://github.com/weikee94/design-patterns/assets/13563834/50559b87-fcad-4004-bcb1-ca7525d5650a) TTFB: The Time To First Byte can be fast, since the initial HTML does not contain large components. FCP: The First Contentful Paint can occur once the JavaScript bundle has downloaded, parsed, and executed its contents. TTI: The Time To Interactive can occur once the JavaScript bundle has downloaded, parsed, and executed its contents to bind the event handlers to the components. LCP: The Largest Contentful Paint can occur at the same time as the First Contentful Paint, provided there aren't any large components such as large images or videos.
weikee94 commented 1 year ago

Static Rendering

With static rendering, the HTML contents are pre-generated at build time. ![image](https://github.com/weikee94/design-patterns/assets/13563834/be2ac897-bed6-4ea5-9713-40c6aab9022c) ![image](https://github.com/weikee94/design-patterns/assets/13563834/ce4a09f5-2fcd-4863-8a0c-1f7c09353251) TTFB: The Time To First Byte can be fast, since the initial HTML does not contain large components. FCP: The First Contentful Paint can occur once the JavaScript bundle has downloaded, parsed, and executed its contents. TTI: The Time To Interactive can occur once the JavaScript bundle has downloaded, parsed, and executed its contents to bind the event handlers to the components. LCP: The Largest Contentful Paint can occur at the same time as the First Contentful Paint, provided there aren't any large components such as large images or videos. | Term | Description | |---------------|-----------------------------------------------------------------------------------------------------------------------| | Cacheability | Pre-rendered HTML files can be cached and served by a global CDN. Users can benefit from quick responses when they request a page, as the request doesn't have to go all the way to the origin server. | | SEO | The HTML content can be rendered by web crawlers with no extra effort. | | Availability | Static is always online. Even if your backend or data source (e.g. database) goes down, your existing pre-rendered page will still be available. | | Backend load | With Static Generation, the database or API wouldn't need to be hit on every request. Page-rendering code wouldn't have to run on every request. | | Dynamic data | If a statically generated page needs dynamic content, for example from an external data source, it needs to fetch this client-side. This can result in a long LCP, and higher server costs. |
weikee94 commented 1 year ago

Incremental Static Regeneration

Pre-render certain pages, and render the other pages on-demand Besides only pre-rendering a subset of pages, we can also automatically invalidate cached pages based on a stale-while-revalidate approach. When a user requests a page that is stale - meaning it's been in cache for longer than the provided number that it should be cached for - a regeneration is triggered in the background. While this is happening, the user gets to see the stale page, but they're able to see the updated content on subsequent requests. ![image](https://github.com/weikee94/design-patterns/assets/13563834/65f6ba59-0393-4ca4-b41e-010cc6899e2a) We can implement Incremental Static Regeneration using Next.js's getStaticProps method in combination with the getStaticPaths method. ``` import { Listings, ListingsSkeleton } from "../components"; export default function Listing(props) { return } export async function getStaticProps(props) { const res = await fetch(`https://my.cms.com/listings/${props.params.id}`); const { listing } = await res.json(); return { props: { listing } } } export function getStaticPaths() { const res = await fetch(`https://my.cms.com/listings?limit=20`); const { listings } = await res.json(); return { params: listings.map(listing => ({ id: listing.id })), fallback: false } } ``` ![image](https://github.com/weikee94/design-patterns/assets/13563834/fe3747eb-151e-419a-9f05-03d4149e574c) TTFB: The Time To First Byte can be fast, since the initial HTML does not contain large components. FCP: The First Contentful Paint can occur once the HTML has been parsed and rendered. LCP: The Largest Contentful Paint can occur at the same time as the First Contentful Paint, provided there aren't any large components such as large images or videos. TTI: The Time To Interactive can occur once the HTML has been rendered, and the JavaScript bundle has been downloaded, parsed, and executed its contents to bind the event handlers to the components.
weikee94 commented 1 year ago

Server Side Rendering

With Server-Side rendering, we can generate HTML on the server (or serverless function) on every request. ![image](https://github.com/weikee94/design-patterns/assets/13563834/e52888b3-04c5-480a-b2b9-0aee4f2321a8) When server-side rendering an application, we need a method to render HTML from our React components on the server, and hydrate the non-interactive HTML on the client. One way to render HTML on the server, is by using the renderToString method. This function returns an HTML string corresponding to the React element. The HTML can then be rendered to the client for a faster page load, and hydrated with the hydrateRoot method on the client. [stackblitz](https://stackblitz.com/edit/nextjs-hpsp3x?file=pages%2Findex.js) ![image](https://github.com/weikee94/design-patterns/assets/13563834/72ac8ec0-2ba8-42e6-bfb4-bf50fd191c1f) TTFB: The TTFB can be slow, since the page still has to be generated on-demand. FCP: The First Contentful Paint can occur once the HTML has been parsed and rendered. LCP: The Largest Contentful Paint can occur at the same time as the First Contentful Paint, provided there aren't any large components such as large images or videos. TTI: The Time To Interactive can occur once the HTML has been rendered, and the JavaScript bundle has been downloaded, parsed, and executed its contents to bind the event handlers to the components.
weikee94 commented 1 year ago

Streaming Server Side Rendering

Generate HTML on every request, sending it down piece by piece ![image](https://github.com/weikee94/design-patterns/assets/13563834/c108daea-c062-4ca5-b103-b080982a4a4a) TTFB: The TTFB can be slow, since the page still has to be generated on-demand. FCP: The First Contentful Paint can occur once the HTML has been parsed and rendered. LCP: The Largest Contentful Paint can occur at the same time as the First Contentful Paint, provided there aren't any large components such as large images or videos. TTI: The Time To Interactive can occur once the HTML has been rendered, and the JavaScript bundle has been downloaded, parsed, and executed its contents to bind the event handlers to the components. | Feature | Description | |----------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------| | Performance regardless of page size | With Streaming SSR, we can have a fast TTFB since the first byte reaches the client soon after rendering starts on the server. This results in a good TTFB for any page of any size. | | Network Backpressure | If the network is clogged and not able to transfer any more bytes, the renderer gets a signal and stops streaming till the network is cleared up. Thus, the server uses less memory and is more responsive to I/O conditions. This enables your Node.js server to render multiple requests at the same time and prevents heavier requests from blocking lighter requests for a long time. As a result, the site stays responsive even in challenging conditions. | | Support | Not all runtimes support HTTP streaming, which is necessary for streaming SSR. |