# Qwik Content Streaming
## Overview
Let's assume you have a slow service that retrieves a Book. How can we stream the content of the page before the Book is retrieved?
## Code
```typescript=
interface Book {
title: string;
author: string;
}
export const onGet = () => {
await delay(2000); // Create artificial delay for a response
return {
title: 'Crossing the Chasm',
author: 'Geoffrey A. Moore',
}
}
export default component$(() => {
const bookResource = useResource<Book>();
return (
<Resource
resource={bookResource}
onPending={() => <span>loading...</span>}
onRejected={(e) => <span>Error: {e}</span>}
onResolved={(book) => <span>{book.title} by {book.author}</span>}
/>
);
});
```
## Server Behavior
During server rendering Qwik will wait for `bookResource` to be resolved before rendering the `onResolved` branch.
## Client Behavior
On client, `<Resource>` will render `onPending` and then once `bookResource` is resolved it will re-render `onResolved` content.
## PROPOSAL: New Streaming Behavior
1. Server can start streaming HTML immediately.
2. When it gets to `<Resource>` the rendering can either:
- Current behavior:
1. wait until `bookResource` is resolved and continue rendering.
- Proposed behavior:
1. wait some time X and if `bookResource` is not resolved by that time (configurable) render the `onPending` branch and continue rendering.
2. When the page is fully rendered, Qwik needs to generated the state of the app in `<script type="qwik/json">`.But now we have a problem, `bookResource` is not yet resolved, so the best we can do is to serialize that `bookResource` is a promise which still has not resolved. So we serialized on-resolved promise reference.
3. We render `</body>`, but NOT `</html>`, instead we keep the connection open and wait for `bookResource` to resolve. At this point the browser can fully render the application and is interactive, but the connection is still open to server.
4. When `bookResource` resolves on the server, the server emits something like this once:
```html
<script>
window.qwikResolvePromise = function(promiseId, data) {
qwikPromiseResolve[promiseId] = data;
}
window.qwikPatchResourceHTML = function(promiseId, html) {
document.
querySelector('[q\\:promise="'+promiseId+'"]').
innerHTML = html;
}
</script>
```
and then this for each resolved promise.
```html
<script>
qwikResolvePromise(
'p9234',
{
title: 'Crossing the Chasm',
author: 'Geoffrey A. Moore'
}
);
qwikPatchResourceHTML(
'r398824',
'<span>Crossing the Chasm by Geoffrey A. Moore</span>'
);
</script>
```
NOTE: that each promise can be used in more than one `<Resource>` so resolving and patching HTML may have one-to-many relationship and require independent functions.
5. Once all of the promises are resolved the server renders `</html>` and closes the connection.
### Benefits
- The above approach basically gives us the ability to render a placeholder for the UI and come back to it once the promise is resolved in a streaming way.
- A non-resolved promise can keep the connection to the client open until the promise resolves.
- From streaming point of view we can stream HTML immediately. If data is not available we can render `loading...` indicator and continue streaming the rest of the content. Once the promise is resolved we can render out a "patch" that goes back and fixes the state as well as.
- The `qwikloader` can resume the application before OR after the streaming ends as in both cases it is in consistent state and can correctly resume.
- The DB request can be triggered immediately without waiting for the data to be resolved.