Skip to content

Commit

Permalink
Update readme.md
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzofox3 authored Apr 17, 2024
1 parent 3afea55 commit 47eeb8f
Showing 1 changed file with 18 additions and 19 deletions.
37 changes: 18 additions & 19 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@

[![install size](https://packagephobia.com/badge?p=tpl-stream)](https://packagephobia.com/result?p=tpl-stream)

``tpl-stream`` is a Javascript template library that supports streaming. You can use it in your server, but not only, to generate html: it works everywhere as long as the runtime
implements [web streams](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream).
``tpl-stream`` is a Javascript template library that supports streaming. It helps to generate HTML in a server environment, but not only. It runs anywhere, as long as the runtime implements [web streams](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream).

It is very small compared to the alternatives and does not require any build step, while providing [very good performances](./benchmark). You will find more details in [this blog post](https://lorenzofox.dev/posts/html-streaming-part-2/)
It is very small compared to the alternatives and does not require a build step, while providing [very good performance](./benchmark). More details can be found in [this blog post](https://lorenzofox.dev/posts/html-streaming-part-2/)

## Installation

You can install from a package manager like [npm](https://www.npmjs.com/) by running the command
The library can be installed from a package manager like [npm](https://www.npmjs.com/) by running the command

``npm install --save tpl-stream``

Or import the module from a CDN:
Or imported from a CDN:

```js
import {render, html} from 'https://unpkg.com/tpl-stream/src/index.js';
Expand All @@ -23,7 +22,7 @@ import {render, html} from 'https://unpkg.com/tpl-stream/src/index.js';

### Basics

You define a template using the ``html`` [tagged template](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates):
A template is defined using the ``html`` [tagged template](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates):

```js
import {html, renderAsString} from 'tpl-stream';
Expand All @@ -34,18 +33,18 @@ const htmlString = await renderAsString(Greeting({name: 'Lorenzofox', classname:

```

when rendered, the html string will be ``'<p class="primary">Lorenzofox</p>'``
Interpolated expressions are automatically escaped (for safety) whether they correspond to a text content or to an attribute.
when rendered, the HTML string will be ``'<p class="primary">Lorenzofox</p>'``
Interpolated expressions are automatically escaped whether they correspond to a text content or to an attribute.

If you wish not to escape a string, you can put it inside an array:
Raw HTML can also be inserted by wrapping the string within an array:

```js
html`<p>${['<span>42</span>']}</p>`
```

### Composition

Combine several templates to compose more complex templates:
Multiple templates can be combined together to create more complex templates:

```js
const Tpl1 = ({title, content}) => html`<h1>${title}</h1><main>${content}</main>`;
Expand All @@ -62,7 +61,7 @@ const htmlString = await renderAsString(Tpl1({

### Conditionals

When using conditional, via ternary expression for example, make sure all the branches are isomorphic(they return the same type): the templates are compiled for optimization and this is based on the interpretation of the first interpolated value:
When using conditional, via ternary expression for example, all the branches should be isomorphic (i.e. return the same type): the templates are compiled for optimisation and this is based on the interpretation of the first interpolated value:

```js
// don't
Expand All @@ -74,8 +73,8 @@ When using conditional, via ternary expression for example, make sure all the br

### Containers

You can interpolate some _containers_: Promise, Iterable(Array), Streams(anything that implements AsyncIterator) or Objects
These containers must contain a template, a string or another container
Interpolation can work on some _containers_: Promise, Iterable(Array), Streams(anything that implements AsyncIterator) or Objects
These containers must contain a template, a string or another container.

```js
html`<ul>${['foo', 'bar'].map(str => html`<li>${str}</li>`)}</ul>`
Expand All @@ -85,8 +84,8 @@ html`<ul>${['foo', 'bar'].map(str => html`<li>${str}</li>`)}</ul>`
html`<p>${Promise.resolve(html`<span>42</span>`)}</p>`
```

Any object container will always be interpreted as a map of attributes (there is no parsing context).
key value pairs whose value is strictly equal to ``false`` are ignored.
An object container is always be interpreted as a map of attributes (there is no parsing context).
key-value pairs whose value is strictly equal to ``false`` are ignored.

```js
html`<button ${{disabled:false, ['aria-controls']:'woot'}}>hello</button>`
Expand All @@ -104,14 +103,14 @@ The ``render`` function takes a template as input and returns a ``ReadableStream
// chunks: ['<p>foo<span>43</span>woot</span>', 'woot'</span></p>]
```

You can also render a template as a string, by awaiting the Promise returned by ``renderAsString`` function
A template can be rendered as a string, by awaiting the Promise returned by ``renderAsString`` function.

## Perceived speed

Note that streaming may also improve the _perceived_ speed as the browser renders the HTML (and eventually fetch some resources) while the server has not fully responded to the request.
This is the behavior you can observe below: the database has an (exagerated) latency of 1s when the server calls it to fetch the blog posts data. On the left side, the server has already started streaming the first part of the HTML and the browser can already render the upper part of the document while the database is still responding.
Streaming may also improve the _perceived_ speed as the browser renders the HTML (and possibly fetching some resources) while the server has not fully responded to the request.
This behaviour can be observed below: the database has an (exaggerated) latency of 1s when the server calls it to fetch the blog posts data. On the left side, the server has already started streaming the first part of the HTML, and the browser can already render the upper part of the document (and fetch the stylesheets and other resources) while the database is still responding.

You can combine libraries such ``tpl-stream`` with techniques like [Out Of Order streaming](https://lamplightdev.com/blog/2024/01/10/streaming-html-out-of-order-without-javascript/) to improve the user experience even further.
This library can be combined with techniques like [Out Of Order streaming](https://lamplightdev.com/blog/2024/01/10/streaming-html-out-of-order-without-javascript/) to improve the user experience even further.



Expand Down

0 comments on commit 47eeb8f

Please sign in to comment.