Skip to content

Commit

Permalink
Added more documentation. Fixes stereobooster#78
Browse files Browse the repository at this point in the history
  • Loading branch information
stereobooster committed Dec 29, 2017
1 parent 964ac66 commit 7d00f96
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 12 deletions.
17 changes: 8 additions & 9 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@

Pre-renders web app into static HTML. Uses headless chrome to crawl all available links starting from the root. Heavily inspired by [prep](https://github.com/graphcool/prep) and [react-snapshot](https://github.com/geelen/react-snapshot), but written from scratch. Uses best practices to get best loading performance.

**Does not depend on React**. The name is inspired by `react-snapshot` and because the initial goal was to enable seamless integration with `create-react-app`. Actually, it works with any technology. Considering to change the name.

## Features

- Enables SEO (google, duckduckgo...) and SMO (twitter, facebook...) for SPA.
- Works out-of-the-box with [create-react-app](https://github.com/facebookincubator/create-react-app) - no code-changes required.
- Uses real browser behind the scene, so no issue with unsupported HTML5 features, like WebGL or Blobs.
- Crawls all pages starting from the root, no need to list pages by hand, like in `prep`.
- With prerendered HTML and inlined critical CSS you will get fast first paint, like with [critical](https://github.com/addyosmani/critical).
- Enables **SEO** (google, duckduckgo...) and **SMO** (twitter, facebook...) for SPA.
- **Works out-of-the-box** with [create-react-app](https://github.com/facebookincubator/create-react-app) - no code-changes required.
- Uses **real browser** behind the scene, so no issue with unsupported HTML5 features, like WebGL or Blobs.
- Does a lot of load **performance optimization**. [Here are details](doc/load-performance-optimizations.md), if you are curious.
- **Does not depend on React**. The name is inspired by `react-snapshot`. Works with any technology.
- npm package does not have compilation step, so **you can fork** it, change what you need and install it with GitHub URL.

Please note: some features are experimental, but prerendering is considered stable enough.
**Zero configuration** is the main feature. You do not need to worry how does it work or how to configure it. But if you are curious [here are details](doc/behind-the-scenes.md).

## Basic usage with create-react-app

Expand Down Expand Up @@ -48,7 +47,7 @@ That's it!
## ✨ Examples

- [Load performance optimization](doc/an-almost-static-stack-optimization.md)
- [recipes](Recipes.md)
- [recipes](doc/recipes.md)
- [stereobooster/an-almost-static-stack](https://github.com/stereobooster/an-almost-static-stack)

## ⚙️ Customization
Expand Down
4 changes: 2 additions & 2 deletions doc/an-almost-static-stack-optimization.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Next problem: Lighthouse complains about render-blocking stylesheets.

## Round 4: Link headers

Next optimisation is pretty trivial and does not require code modification, but it requires the support of custom headers from your hosting. You will need to be able to set `Link` header.
Next optimization is pretty trivial and does not require code modification, but it requires the support of custom headers from your hosting. You will need to be able to set `Link` header.

`react-snap` can generate Link headers in [superstatic](https://github.com/firebase/superstatic) format, like this:

Expand Down Expand Up @@ -243,7 +243,7 @@ File sizes after gzip:

## Round 9: vanilla create-react-app

This is for comparison - original create-react-app without any additional optimisations.
This is for comparison - original create-react-app without any additional optimizations.

🔖 [round-9](https://github.com/stereobooster/an-almost-static-stack/compare/round-8...stereobooster:round-9?expand=1)

Expand Down
20 changes: 20 additions & 0 deletions doc/behind-the-scenes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Behind the scenes

1. copies index.html as 200.html
2. starts local web server with your application (by default uses `/build` as a root)
3. visits `/` or any other pages listed in `include` configuration
4. find all links on the page with the same domain, add them to queue
5. If there is more than one page in the queue it also adds `/404.html` to the queue
6. renders the page with the help of puppeteer
7. waits till there are no active network requests for more than 0.5 second
8. removes webpack chunks, if needed
9. removes styles with blob URLs, if needed
10. recreates text for style tags for CSS-in-JS solutions, if needed
11. inlines critical CSS, if configured
12. collects assets for http2 push manifest, if configured
13. minifies HTML and saves it to the disk
14. if `route` ends with `.html` it will be used as is, otherwise `route/index.html` is used

## Other features

- `react-snap` works concurrently, by default it uses 4 tabs in the browser. Can be configured with `concurrency` option.
66 changes: 66 additions & 0 deletions doc/load-performance-optimizations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Load performance optimizations

## Works out of the box

### Prerendered HTML

`react-snap` prerenders HTML, so the browser can start to render content or download required resources ASAP.

### preconnect for third-party resources

`react-snap` tracks all third-party connections during rendering and will place appropriate preconnect links in the `header`.

### If you are using code splitting feature of Webpack

`react-snap` will remove chunk scripts from the HTML and instead will place preload links in the `header`.

### If you are using CSS-in-JS solution

`react-snap` will prerender all styles and save in the HTML.

## Requires configuration

This is a brief overview of what described in Readme and [recipes](recipes.md).

### inlineCss

With this configuration enabled `react-snap` will inline critical CSS and stylesheet links will be loaded in a nonblocking manner with the help of [loadCss](https://www.npmjs.com/package/fg-loadcss).

### cacheAjaxRequests

If you are doing AJAX requests (to the same domain), `react-snap` can cache this data in the window. Think of it as a poor man's Redux rehydration.

### http2PushManifest

`react-snap` can record all resources (scripts, styles, images) required for the page and write down this data to the JSON file. You can use this JSON file to generate HTTP2 server pushes or Link headers.

### If you are using Redux

Use `window.snapSaveState` callback to store Redux state, so it can be used to rehydrate on the client side.

### If you are using loadable-components

Use `window.snapSaveState` callback to store `loadable-components` state, so it can be used to rehydrate on the client side.

### If you are using Apollo

Use `window.snapSaveState` callback to store `Apollo` state, so it can be used to rehydrate on the client side.

**Caution**: I didn't test this one. If you use it please let me know.

```js
// Grab the state from a global variable injected into the server-generated HTML
const preloadedState = window.__APOLLO_STORE__

// Allow the passed state to be garbage-collected
delete window.__APOLLO_STORE__

const client = new ApolloClient({
initialState: preloadedState,
});

// Tell react-snap how to save state
window.snapSaveState = () => ({
"__APOLLO_STORE__": client.store.getState()
});
```
File renamed without changes.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"typescript": "^2.7.0-dev.20171026"
},
"scripts": {
"toc": "yarn run markdown-toc -i Recipes.md",
"toc": "yarn run markdown-toc -i doc/recipes.md",
"test": "echo \"Error: no test specified\" && exit 1",
"precommit": "prettier --write {*,src/*}.{js,json,css}",
"tsc": "tsc -p ."
Expand Down

0 comments on commit 7d00f96

Please sign in to comment.