https://github.com/grommett/fastify-chunk-view
A Fastify plugin for sending HTML to the client as soon as it becomes available.
https://github.com/grommett/fastify-chunk-view
fastify progressive-html progressive-rendering pssr
Last synced: about 1 month ago
JSON representation
A Fastify plugin for sending HTML to the client as soon as it becomes available.
- Host: GitHub
- URL: https://github.com/grommett/fastify-chunk-view
- Owner: grommett
- License: mit
- Created: 2021-12-28T21:56:50.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2022-06-03T14:31:03.000Z (about 4 years ago)
- Last Synced: 2025-04-18T17:47:47.138Z (about 1 year ago)
- Topics: fastify, progressive-html, progressive-rendering, pssr
- Language: JavaScript
- Homepage:
- Size: 363 KB
- Stars: 0
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Chunk View


A [Fastify](https://www.fastify.io/) plugin for sending HTML content to the client as soon as it becomes available.
## Why
This plugin is ideal for situations where you have static content that can be served immediatley and async content that will arrive later. For example, a product list page where the header, styles and hero image can be sent right away while you grab the products from an API.
## Install
```js
npm i fastify-chunk-view --save
```
## Usage
`fastify-chunk-view` supports ESM and CommonJS
### ESM
```js
import fastifyChunkView from 'fastify-chunk-view';
```
### Common JS
```js
const fastifyChunkView = require('fastify-chunk-view');
```
The `fastify-chunk-view` plugin takes an array of chunks and sends them to the client in that order. A chunk can be:
- A `string`
- A `function` that returns a `string`
- An `async function` that returns a `string`
- A `Readable` stream
Have a look or run the `examples` folder in this repo for more details. Here's a silly example to illustate:
```js
fastify.get('/', (_req, reply) => {
reply.chunkView([
'
test chunk 1
',
'test chunk 2
'
]);
});
```
In the example above each chunk is pushed into the `reply`'s read stream in order.
An example of the ecommerce use case mentioned above:
```js
fastify.get('/', (_req, reply) => {
reply.chunkView([
// Sent to client immediately
'
',
productList, // Sent after the list is retrieved
footer,
''
]);
});
async function productList() {
const products = await getProducts();
return `
- ${product.name} `).join('')}
${products.map(product => `
}
function getProducts() {
return new Promise(resolve => {
setTimeout(() => {
resolve([{ name: 'Product 1' }, { name: 'Product 2' }, { name: 'Product 3' }]);
}, 1000);
});
}
function footer() {
return `${new Date().toLocaleDateString()}`;
}
```
You probably wouldn't use the same strings over and over in your routes. This plugin also lets you use [`Readable`](https://nodejs.org/api/stream.html#readable-streams) streams.
Building on the product list example above:
```js
fastify.get('/', (_req, reply) => {
const startHTML = fs.createReadStream('start.html');
const endHTML = fs.createReadStream('end.html');
reply.chunkView([
startHTML,
productList,
footer,
endHTML
]);
});
async function productList() {
const products = await getProducts();
return `
- ${product.name} `).join('')}
${products.map(product => `
}
function footer() {
return `${new Date().toLocaleDateString()}`;
}
```
## Further Reading
- [The Lost Art of Progressive HTML Rendering](https://blog.codinghorror.com/the-lost-art-of-progressive-html-rendering/)
- [Rediscovering Progressive HTML Rendering with Marko](https://tech.ebayinc.com/engineering/async-fragments-rediscovering-progressive-html-rendering-with-marko/)
- [Progressive Rendering — The Key to Faster Web](https://medium.com/the-thinkmill/progressive-rendering-the-key-to-faster-web-ebfbbece41a4)