Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update documentation #1040

Merged
merged 2 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 62 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<p align="center">
<img src="https://user-images.githubusercontent.com/86055112/211430605-733e1e4b-e439-4c68-9256-f9f11f6785a2.png" alt="ngx-prefetch logo" width="200px" height="200px"/>
<br>
<b>Angular builder for prefetching static resources before loading the application.</b>
<b>Angular builder for prefetching resources before loading the application.</b>
<br><br>
<img alt="npm" src="https://img.shields.io/npm/dw/@o3r/ngx-prefetch?color=red">
<img alt="npm (scoped)" src="https://img.shields.io/npm/v/@o3r/ngx-prefetch?color=8B8000">
Expand All @@ -14,51 +14,86 @@
<hr>

## Description
In some cases, it is possible to prefetch the static resources of an application before actually loading the application itself. For example, if the application can be accessed through a static web page or another web application.
In some cases, it is possible to prefetch the resources of an application before actually loading the application itself. For example, if the application can be accessed through a static web page or another web application.

The prefetch builder generates a `ngxPrefetch.js` file that should be included in the HTML page of the entry point. When run, it dynamically [creates `<link>` tags](https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefetching_FAQ) for each static resource (such as JS and CSS files) so that the browser can prefetch them during idle times. This will improve the Page Load Time of the application when it is actually loaded.
The prefetch builder generates a `ngxPrefetch.js` file that should be included in the HTML page of the entry point. When run, it dynamically [creates `<link>` tags](https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefetching_FAQ) for each resource (such as JS and CSS files) so that the browser can prefetch them during idle times. This will improve the Page Load Time of the application when it is accessed for the first time. Then, the browser caching will take over until a new version of the application is deployed or the browser cache is cleared.

## Prerequisites
A prerequiste for the script is to have [Angular Service Worker](https://angular.io/guide/service-worker-intro) enabled as it is using the `ngsw.json` from the production build folder that is generated by the Angular Service Worker. Therefore it will be ran after the build prod.
A prerequisite for the script is to have [Angular Service Worker](https://angular.io/guide/service-worker-intro) enabled as it is using the `ngsw.json` from the production build folder that is generated by the Angular Service Worker. Therefore, it will be run after the build prod.

## Install

```shell
npm install -D @o3r/ngx-prefetch
```
OR
```shell
ng add @o3r/ngx-prefetch
```
> **NOTE:** This library is following the Angular release cycle. For instance, if you are using Angular 13, use a 13.x version of the library:
>
> ```shell
> npm install -D @o3r/ngx-prefetch@13
> ```
> OR
> ```shell
> ng add @o3r/ngx-prefetch@13
> ```

## Builder options
- `targetBuild` **Mandatory** The target build where prefetch should be applied. Used for identifying the `outputPath` of the build.

- `resourceTypes` An object describing the resource types that should be prefetched.
## Get started

- `crossorigin` Flag that sets crossorigin attribute on links. If true it will be set for all prefetched resources.
1. By running the `ng add` command above, the following lines should have been added to the application's `angular.json`:

- `production` Flag for creating a production (minified) version of the js file or a development one.
```json
"generate-prefetch": {
"builder": "@o3r/ngx-prefetch:run",
"options": {
"targetBuild": "app-name:build:production"
}
},
```

- `staticsFullPath` By default the prefetched resources are hosted next to the `ngxPrefetch.js` file, on the same server. If it is not the case, you can configure the full path of the resources that will be prefetched. (ex: https://my-web-app.com/path/to/my-app/). It is also possible to set this value by runtime. Instead of setting it in the Builder's options, you can search and replace for `{STATICS_FULL_PATH}` on the server side in order to inject a path.
## Usage
> **NOTE:** Additional configuration can be added to the `angular.json` (builder options are described below with an example of full configuration).

[`package.json`]
2. Then, add a command to the `package.json` to run `generate-prefetch`:

```json
...
"build:prod": "ng build --prod && yarn run generate:prefetch",
"generate:prefetch": "yarn app-name:generate-prefetch",
...
"generate:prefetch": "ng run app-name:generate-prefetch"
```

[`angular.json`]
3. Run the `ng build` command with the `production` configuration.
The default configuration of the build command should be `production`, otherwise it should be specified:

```json
"generate-prefetch": {
"builder": "@o3r/ngx-prefetch:run",
"options": {
"targetBuild": "my-app:build:production"
}
},
...
"build:prod": "ng build --configuration production",
...
```

4. Run the previously defined `generate:prefetch` command.

## How it works

Please refer to the details on how the ngx-prefetch works [here](docs/HOW_IT_WORKS.md).

## Builder options
- `targetBuild` **Mandatory** The target build where prefetch should be applied. Used for identifying the `outputPath` of the build.

- `resourceTypes` An object describing the resource types that should be prefetched. The valid values for the type of content can be found [here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attributes).

- `crossorigin` Flag that sets the crossorigin attribute on links. If true it will be set for all prefetched resources.

- `production` Flag for creating a production (minified) version of the js file or a development one.

- `staticsFullPath` By default the prefetched resources are hosted next to the `ngxPrefetch.js` file, on the same server.
If this is not the case, you can configure the full path of the resources that will be prefetched (ex: https://my-web-app.com/path/to/my-app/).
It is also possible to set this value at runtime. Instead of setting it in the Builder's options, you can search for `{STATICS_FULL_PATH}` and replace it on the server side in order to inject a path.

- `localizationPattern` Pattern for the relative path of the localization file. By default, the pattern corresponds to the JSON file in a folder called localizations: `"/localizations/${language}.json"`.
If the localization pattern contains the `${language}` variable, the language value must be set (as explained [here](docs/HOW_IT_WORKS.md#localization)), and it will be replaced by the server.

### Example of full configuration

[`angular.json`: full configuration]

```json
Expand All @@ -75,17 +110,8 @@ npm install -D @o3r/ngx-prefetch
},
"crossorigin": true,
"production": false,
"staticsFullPath": "https://my-web-app.com/path/to/my-app/"
"staticsFullPath": "https://my-web-app.com/path/to/my-app/",
"localizationPattern": "/localizations/${language}.json"
}
},
```

## Versioning

This library is following the Angular release cycle. Angular 13 and onwards is supported.

For instance, if you are using Angular 13, use a 13.x version of the library:

```shell
npm install -D @o3r/ngx-prefetch@13
}
```
54 changes: 54 additions & 0 deletions docs/HOW_IT_WORKS.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a link from the main readme to this doc?

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# How ngx-prefetch works

After adding a service worker to your project, as specified in the [prerequisites](../README.md#prerequisites), the modifications include
the creation of a service worker configuration file called `ngsw-config.json`, which specifies the caching behaviors.
Then the build process creates the manifest file `ngsw.json` in the `dist` folder using information from `ngsw-config.json`.

## Create Angular CLI builder

Before all, if the mandatory options are provided and verified, the production output folder is retrieved.
Then the creation of the builder consists of four steps:

1. The first step is to read the `ngsw.json` file. This allows to create an array of resources based on the asset groups that have the `installMode` set to `prefetch`.
2. The second step is to read the prefetch [Mustache](https://mustache.github.io/) template file. This template is rendered in JavaScript using the object of variables that is passed as a parameter.
3. The third step is to write the prefetch JS script using the previous template.
4. The fourth step is to create a Compiler by bundling the JS file for usage in a browser using [webpack](https://webpack.js.org/).

When this compiler is run successfully, a new file `ngxPrefetch.js` is created in the production output folder.

## ngxPrefetch.js file

### Static content

The `ngxPrefetch.js` file contains a list of static resources that the Angular service worker should cache based on the `ngsw-config.json` file.
The path where these resources are hosted can be defined in the [builder options](../README.md#builder-options) otherwise the default path is next to the `ngxPrefetch.js` file, on the same server.

### Localization

In addition to the static content, the localization file can be prefetched in order to have the language information while performing the prefetch.

It is possible to set the language value at runtime by searching for `{LANG}` and replacing it on the server side.
Then the `localization pattern` can be set in the [builder options](../README.md#builder-options) to get the relative path of the localization file.

### Dynamic content

Dynamic content can also be prefetched in order to override some static content if wanted.
There are two placeholders that can be replaced in the server:
- `{DYNAMIC_CONTENT_PATH}`: the path where the dynamic resources are hosted (`"mydynamiccontentpath"` for example)
- `{DYNAMIC_CONTENT_FILES}`: the path of the dynamic content files relative to the dynamic content path (expects a format like the following example: `["relativePath/myfile1", "relativePath/myfile2"]`)

### Link elements in header

For each static resource of type `string`, a step is implemented to check if this same resource is present in the dynamic content.
If this is the case, the full path of the static resource is overridden by the dynamic full path.
Then, a link is appended to the html header of the webpage with the following properties:
* A relationship (`rel`) of type `prefetch`
* The type of content being loaded (`as`) if possible
* Possibly the `crossorigin` attribute to indicate whether CORS must be used when fetching the resource
* The URL of the linked resource (`href`)

Below is an example of the appended link:

```html
<link rel="prefetch" as="type-of-content" crossorigin href="url-of-linked-resource">
```
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export default createBuilder<PrefetchBuilderSchema>(async (options, context): Pr
if (err || stats.hasErrors()) {
resolve({
success: false,
error: `Webpack tanspilation failed. ${err || stats.hasErrors()}`
error: `Webpack transpilation failed. ${err || stats.hasErrors()}`
});
} else {
resolve({
Expand Down
Loading