Skip to content

Commit 0b4552f

Browse files
Merge pull request #15 from push-based/fix-readme
fix: use proper readme
2 parents 7d29750 + 252312d commit 0b4552f

File tree

1 file changed

+172
-47
lines changed

1 file changed

+172
-47
lines changed
Lines changed: 172 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,212 @@
11
# ngx-fast-svg
22

3-
---
3+
Fast SVG's for Angular powered by browser native features with best performance practices and DX in mind.
44

5-
#### Fast SVG's for Angular powered by browser native features with best performance practices and DX in mind
5+
## Why another SVG lib for Angular?
66

7-
<!-- toc -->
7+
Current implementations of SVG handling in the Browser lacks of awareness of performance.
88

9-
- [Fast SVG's for Angular powered by browser native features with best performance practices and DX in mind](#fast-svgs-for-angular-powered-by-browser-native-features-with-best-performance-practices-and-dx-in-mind)
9+
This library covers next aspects that developers should consider for their projects:
1010

11-
<!-- tocstop -->
11+
- Image loading performance
12+
- Initial rendering performance and runtime performance
13+
- SVG reusability
14+
- Optimized bundle size
15+
- SSR
1216

13-
# Why another SVG lib for Angular?
17+
## Getting started
1418

15-
Current implementations of SVG handling in the Browser lacks of awareness of performance.
19+
### Install
1620

17-
There are several things not considered in most of the existing projects:
21+
```bash
22+
npm install @push-based/ngx-fast-svg --save
23+
# or
24+
yarn add @push-based/ngx-fast-svg
25+
```
1826

19-
- SSR
20-
- bundle size
21-
- DOM size
22-
- Lazy loading
23-
- SVG structure reusability
24-
- Initial rendering performance
25-
- Runtime performance of updates
27+
### Setup
2628

27-
We will walk through all the different scenarious in detail later.
28-
To get a quick overview we will list a comparison table:
29+
**app.module.ts**
2930

30-
| Library | SSR | Lazy loading | Hydration | Reusability of SVG DOM | Optimized render performance | Size |
31-
| ---------------- | ---------- | ---------------- | --------- | ---------------------- | ---------------------------- | -------- |
32-
| ngx-fast-svg | `easy` | browser natively | βœ”οΈ | βœ”οΈ | βœ”οΈ | 1.52 KB |
33-
| font-awesome | `hard` | ❌ | βœ”οΈ | βœ”οΈ | ❌ | 64.75 KB |
34-
| ant | `moderate` | ❌ | βœ”οΈ | βœ”οΈ | ❌ | 24.38 KB |
35-
| material | `easy` | ❌ | βœ”οΈ | βœ”οΈ | ❌ | 16.92 KB |
36-
| angular-svg-icon | `moderate` | ❌ | βœ”οΈ | βœ”οΈ | ❌ | 1.54 KB |
37-
| ionic | `moderate` | ❌ | βœ”οΈ | βœ”οΈ | βœ”οΈ | 1.44 KB |
31+
```typescript
32+
// ...
33+
import { FastSvgModule } from '@ngx-fast-svg';
3834

39-
**SSR**
40-
Server Side Rendering is working. The depending on how easy it is to set it up we distinguish between `easy`, `moderate`, `hard`.
35+
@NgModule({
36+
declarations: [AppComponent],
37+
imports: [
38+
FastSvgModule.forRoot({
39+
url: (name: string) => `path/to/svg-assets/${name}.svg`,
40+
})
41+
]
42+
providers: [],
43+
bootstrap: [AppComponent]
44+
})
45+
export class AppModule {}
46+
```
4147

42-
**Lazy loading**
43-
We refer to lazy loading as on demand loading of SVG files based on their visibility in the viewport.
48+
### Usage in the template
4449

45-
**Hydration**
46-
Is the process of taking over the SSR HTML and state of the app on the client side.
47-
This can happen in a destructive way (deleting all present HTML and regenerate it from JS) on in a non-destructive way (reusing the existing DOM).
50+
```html
51+
<fast-svg [name]="svgName" [size]="svgSize"></fast-svg>
52+
<!-- OR -->
53+
<fast-svg [name]="svgName" [width]="svgWidth" [height]="svgHeight"></fast-svg>
54+
```
4855

49-
**Reusability of SVG DOM**
50-
Reusability means that we maintain the content of an SVG, meaning its inner DOM structure `g`, `path` or other tags in one place and reuse them in many different places.
56+
### Advanced usage
5157

52-
**Optimized render performance**
53-
To display (render) SVGs the browser takes time. We can reduce that time by adding a couple of improvements.
58+
#### Providing additional options
5459

55-
# Install
60+
During setup phase you can provide additional optional settings such as:
5661

57-
```bash
58-
npm install @push-based/ngx-fast-svg --save
59-
# or
60-
yarn add @push-based/ngx-fast-svg
62+
```typescript
63+
defaultSize?: string;
64+
suspenseSvgString?: string;
65+
svgLoadStrategy?: Type<SvgLoadStrategy>;
6166
```
6267

63-
# Setup
68+
`svgLoadStrategy` can be any injectable class that has `load` method that accepts url and returns observable string:
69+
70+
```typescript
71+
@Injectable()
72+
export abstract class SvgLoadStrategy {
73+
abstract load(url: string): Observable<string>;
74+
}
75+
```
6476

6577
**app.module.ts**
6678

6779
```typescript
6880
// ...
69-
import { FAST_SVG_PROVIDERS } from './ngx-fast-svg-ssr/movie.icon.provider';
70-
import { FastSvgModule } from '@ngx-fast-icon';
81+
import { FastSvgModule } from '@ngx-fast-svg';
82+
import { loaderSvg } from './assets';
83+
import { HttpClientFetchStrategy } from './fetch-strategy';
7184

7285
@NgModule({
7386
declarations: [AppComponent],
7487
imports: [
75-
BrowserModule,
7688
FastSvgModule.forRoot({
77-
89+
url: (name: string) => `path/to/svg-assets/${name}.svg`,
90+
defaultSize: '32',
91+
suspenseSvgString: loaderSvg,
92+
svgLoadStrategy: HttpClientFetchStrategy
7893
})
7994
]
8095
providers: [],
8196
bootstrap: [AppComponent]
8297
})
83-
export class AppModule {
98+
export class AppModule {}
99+
```
84100

101+
#### SSR Usage
102+
103+
You can provide your own SSR loading strategy that can look like this:
104+
105+
```typescript
106+
@Injectable()
107+
export class SvgLoadStrategySsr implements SvgLoadStrategy {
108+
load(url: string): Observable<string> {
109+
const iconPath = join(process.cwd(), 'dist', 'app-name', 'browser', url);
110+
const iconSVG = readFileSync(iconPath, 'utf8');
111+
return of(iconSVG);
112+
}
85113
}
114+
```
86115

116+
And then just provide it in you server module.
117+
118+
**app.server.module.ts**
119+
120+
```typescript
121+
@NgModule({
122+
declarations: [],
123+
imports: [
124+
AppModule,
125+
ServerModule,
126+
ServerTransferStateModule,
127+
FastSvgModule.forRoot({
128+
svgLoadStrategy: SvgLoadStrategySsr,
129+
url: (name: string) => `assets/svg-icons/${name}.svg`,
130+
}),
131+
],
132+
providers: [],
133+
bootstrap: [AppComponent],
134+
})
135+
export class AppServerModule {}
87136
```
137+
138+
## Features
139+
140+
### :sloth: Lazy loading for SVGs
141+
142+
Lazy loading is referring to loading resources only if they are visible on screen. Like lazy loading imgs.
143+
It can be implemented natively over loading attribute or over viewportobserver.
144+
This library supports lazy loading for SVGs using purely browser native features.
145+
146+
- We display an empty SVG at the beginning. Invisible and without dimensions.
147+
- On View init the size is applied even if no svg is loaded to avoid flickering in dimensions.
148+
- A suspense svg is displayed at the same time to reduce visual flickering.
149+
- We use an img element here to leverage the browsers native features:
150+
- Lazy loading (loading="lazy") to only load the svg that are actually visible
151+
- The image is styled with display none. this prevents any loading of the resource ever.
152+
on component bootstrap we decide what we want to do. When we remove display none it performs the browser native behavior.
153+
154+
### :floppy_disk: Caching
155+
156+
We use a DOM caching mechanism to display svg over the 'use' tag and an href attribute.
157+
When the browser loaded the svg resource we trigger the caching mechanism.
158+
159+
`re-fetch -> cache-hit -> get SVG -> cache in DOM`
160+
161+
Cached SVG elements can be reused in multiple places places and support different stylings.
162+
163+
### :rocket: Optimized for performance
164+
165+
This library leverages best performance practices:
166+
167+
- Component is styled with `content-visiblity: auto;` and `contain: content;`. It makes instances outside of viewport completely excluded from browser style recalculation process.
168+
- Cache is stored in a tag which is not processed by the browser.
169+
- We use native browser `fetch` which is not patched by `zone.js` and is on average 2.5 times faster than fetching over `HTTPClient`.
170+
171+
### πŸ€– SSR Support
172+
173+
This library also Supports lazy loading with SSR and http transfer cache.
174+
If SSR load svgs on server => ends up in DOM cache and ships to the client.
175+
176+
## Comparison
177+
178+
Here's library comparison with other popular SVG solutions.
179+
180+
| Library | SSR | Lazy loading | Optimized render performance | Size |
181+
| ---------------- | ---------- | ---------------- | ---------------------------- | -------- |
182+
| ngx-fast-svg | `easy` | browser natively | βœ”οΈ | 1.52 KB |
183+
| font-awesome | `hard` | ❌ | ❌ | 64.75 KB |
184+
| ant | `moderate` | ❌ | ❌ | 24.38 KB |
185+
| material | `easy` | ❌ | ❌ | 16.92 KB |
186+
| angular-svg-icon | `moderate` | ❌ | ❌ | 1.54 KB |
187+
| ionic | `moderate` | ❌ | βœ”οΈ | 1.44 KB |
188+
189+
<!-- | Library | SSR | Lazy loading | Hydration | Reusability of SVG DOM | Optimized render performance | Size |
190+
| ---------------- | ---------- | ---------------- | --------- | ---------------------- | ---------------------------- | -------- |
191+
| ngx-fast-svg | `easy` | browser natively | βœ”οΈ | βœ”οΈ | βœ”οΈ | 1.52 KB |
192+
| font-awesome | `hard` | ❌ | βœ”οΈ | βœ”οΈ | ❌ | 64.75 KB |
193+
| ant | `moderate` | ❌ | βœ”οΈ | βœ”οΈ | ❌ | 24.38 KB |
194+
| material | `easy` | ❌ | βœ”οΈ | βœ”οΈ | ❌ | 16.92 KB |
195+
| angular-svg-icon | `moderate` | ❌ | βœ”οΈ | βœ”οΈ | ❌ | 1.54 KB |
196+
| ionic | `moderate` | ❌ | βœ”οΈ | βœ”οΈ | βœ”οΈ | 1.44 KB | -->
197+
198+
**SSR**
199+
Server Side Rendering is working. The depending on how easy it is to set it up we distinguish between `easy`, `moderate`, `hard`.
200+
201+
**Lazy loading**
202+
We refer to lazy loading as on demand loading of SVG files based on their visibility in the viewport.
203+
204+
<!-- **Hydration**
205+
Is the process of taking over the SSR HTML and state of the app on the client side.
206+
This can happen in a destructive way (deleting all present HTML and regenerate it from JS) on in a non-destructive way (reusing the existing DOM).
207+
208+
**Reusability of SVG DOM**
209+
Reusability means that we maintain the content of an SVG, meaning its inner DOM structure `g`, `path` or other tags in one place and reuse them in many different places. -->
210+
211+
**Optimized render performance**
212+
To display (render) SVGs the browser takes time. We can reduce that time by adding a couple of improvements.

0 commit comments

Comments
Β (0)