RETHINKING ANGULAR

ARCHITECTURE & 

PERFORMANCE
MarkPieszak
MarkPieszak
Mark Pieszak
CO-FOUNDER TRILON.IO







Angular Universal Team
NestJS Core Team



Open Source
ASP.NET Core + Angular Universal starter

ASP.NET Core + Vue starter

Angular Azure Application Insights

MarkPieszak
WWW.TRILON.IO
MarkPieszak
ARCHITECTURE
MarkPieszak
MarkPieszak
APP MODULE
Main.ts

platformBrowser()
MODULE
MODULE MODULE
MarkPieszak
APP MODULE
Main.ts

platformBrowser()
MODULE
MODULE MODULE
Bundle 

& 

Deploy
MarkPieszak
APP MODULE
Main.ts

platformBrowser()
MODULE
MODULE MODULE
Request
Response
Bundle 

& 

Deploy
HOW DO 

USERS SEE

OUR APP?
MarkPieszak
MarkPieszak
Loading
Request
Response
MarkPieszak
Request
Response
MarkPieszak
Loading
Request
Response
FAST
INTERACTIVE
RESPONSIVE
IMPROVING THE USER EXPERIENCE
MarkPieszak
PERFORMANCE
MATTERS
MarkPieszak
Walmart saw a 1% increase in revenue for every
100ms improvement in performance.
WHERE DO WE BEGIN?
MarkPieszak
MarkPieszak
> LIGHTHOUSE
MarkPieszak
> ANALYZE

> EXPERIMENT

> AUDIT
THE 

LIGHTHOUSE

GAME
MarkPieszak
MarkPieszak
The Dream
MarkPieszak
Reality
WHAT TOOLS 

CAN WE USE?
MarkPieszak
MarkPieszak
Webpack

Bundle

Analyzer
> ANALYZE
Helps visualize Architecture

Vendor / 3rd party libs
Main bundle
Lazy chunks
MarkPieszak
> WEBPACK BUNDLE ANALYZER
MarkPieszak
Webpack

Bundle

Analyzer
> ANALYZE
SETTING
GOALS
MarkPieszak
Reduce “Main Thread” execution time
Objective:
Minimize main bundle (wherever possible)
- Remove unneeded code & imports from “main” 

- Remove as many third party libs from “main”

MarkPieszak
MarkPieszak
MarkPieszak
FAST
RESPONSIVE
INTERACTIVE
First Initial Paint
Small Bundle payload
TTI ( Time-to-interactive )
TIP: 

Be careful not to abuse or misuse imports here.



>> Import only what you need!

MarkPieszak
# 1 > LAZY-LOADING (ROUTES)
FAST
@({

imports: [
UiButtonModule,

UiModalModule,

UiActionModule,

CommonModule

// ...
]

})
export class OrderModule {}
FAST
# 1 > LAZY-LOADING (ROUTES)
MarkPieszak
ORDER MODULEABOUT MODULE CART MODULE
DATA MODULE
TABLE MODULE
3rd Party Lib
UI-MODAL MODULE
AUTH MODULE AUTH MODULE
DATA MODULE
FAST
# 1 > LAZY-LOADING (ROUTES)
TIP:

Use ngx-quicklink (PreloadingStrategy) 

Preload lazy modules when:

they are VISIBLE & the browser is idle.

Bonus points: 

GuessJS
MarkPieszak
FAST
# 2 > PRELOADING STRATEGIES
TIP:

Dynamically Lazy-Loading Modules & Components
Use tools like: ngx-loadable
MarkPieszak
FAST
# 3 > LAZY LOADING (NON-ROUTABLE)
<ngx-loadable 

module="lazy" 

[show]="show">

</ngx-loadable>
MarkPieszak
TIP:

Defer loading images until visible
Use tools like: ng-lazyload-image
FAST
# 4 > DEFER IMAGE LOADING
<img 

[defaultImage]=“defaultImage” 

[lazyLoad]="image">
MarkPieszak
What about Content 

“Below the Fold”
FAST
MarkPieszak
Original Content
Can we Lazy Load 

this entire Module?
Or maybe just Lazy Load 

all of these images?
FAST
TIP:

Static Assets on a CDN / edge server delivery
ie: Cloudflare

File Compression (css, html, js)
At a minimum: GZIP
Ideally: Brotli
Outperforms Gzip
JS files ~14% smaller
MarkPieszak
COMPRESSED

Response
FAST
# 5 > CDN & COMPRESSION
MarkPieszak
PROS
• SEO, Social-media previews, non-JS crawl-able
• Faster “initial paint”

CONS
Slower TTI ( Time-to-interactive )
aka: Angular Universal
# 6 > SERVER-SIDE RENDERING (SSR)
FAST
MarkPieszak
Loadin
Time
Initial “Paint” Fully Bootstrapped App
> CLIENT-SIDE RENDERING (CSR)
FAST
MarkPieszak
Time
> SERVER-SIDE RENDERING (SSR)
Initial “Paint” Fully Bootstrapped App
FAST
MarkPieszak
Loading
FAST
INTERACTIVE
Click / Scroll / all functioning ( esp during SSR )
TIP:

Make sure your Initial SSR “User Experience” 

is still fairly interactive.
INTERACTIVE
# 1 > SSR - ENSURE INTERACTIVITY
MarkPieszak
> SSR - ENSURE INTERACTIVITY
INTERACTIVE
Time
Initial “Paint” Fully Bootstrapped App
Mind the “gap”Can users interact ?
MarkPieszak
> EXPERIMENT
Use <a [routerLink]> 

over (click)=“”
events for the most 

important navigation
INTERACTIVE
MarkPieszak
> EXPERIMENT
Can we setup a [routerLink] navigation 

to a menu”-like Route page ?
INTERACTIVE
MarkPieszak
> EXPERIMENT
Scroll Functionality
Can the user still scroll and see at least 

SOME important information
INTERACTIVE
Two types of SSR



Run-time: Dynamic
Angular Server-Side Rendering (SSR) # 1 ( continued )
INTERACTIVE
/products
Request
Response
Serialize App
Hit API
Two types of SSR



Build-time: Pre-rendering
Angular Server-Side Rendering (SSR) # 1 ( continued )
INTERACTIVE
/products
Request
Response
Products.html
TIP:

Opt for Pre-rendering routes (over Dynamic SSR)
wherever possible for faster responses.
Cache Pre-Rendered HTML 

(File Storage / MemCache / Redis) where possible
Angular Server-Side Rendering (SSR) # 1 ( continued )
INTERACTIVE
Angular Server-Side Rendering (SSR) # 1 ( continued )
INTERACTIVE
TIPS & TRICKS: 

You can setup all 3 types of rendering



Pre-rendering

app.get(SomeRoutes) => res.send( prerenderedHtml )



Dynamic SSR

app.get(OtherRoutes) => await renderModuleFactory()



Client-Side Rendering (CSR)

app.get(*). => res.send( originalIndexHtml )
# 1 ( continued )
Angular Server-Side Rendering (SSR)
MUST HAVE:

Transfer (re-use) Http responses between SSR => CSR
TransferHttpCacheModule from 

@NgUniversal/Common

TIP:

Keep your API calls “lean” to not send too much
payload data down with the Html
INTERACTIVE
MarkPieszak
Loading
FAST
RESPONSIVE
Fast Web/Tablet/Mobile versions
Usable even with slow (or zero) internet
MarkPieszak
TIP:
Setup a Service Worker

Cache assets (JS/CSS/HTML/images) to 

speed up subsequent page loads
RESPONSIVE
# 6 > PWA (PROGRESSIVE WEB APP)
FIND THE RIGHT BALANCE
MarkPieszak
Loading
FAST
RESPONSIVE
INTERACTIVE
Request
Response
> REMEMBER WHAT MATTERS
MarkPieszak
THE
USER

EXPERIENCE
Keep that MAIN bundle small
Move whatever functionality you can out of AppModule /
main.bundle
Try to keep NgModules lean / compact
Be intentional with imports
MarkPieszak
>>> IN CONCLUSION
Lazy-Load sections of your app - when visible
Images
Modules
Components

If you’re doing SSR
Remember to maintain some functionality during the
first initial paint
MarkPieszak
>>> IN CONCLUSION
MarkPieszak
Angular Performance Checklist
> ADDITIONAL RESOURCES
by: Minko Gevchev
Why it's tricky to measure Server-side Rendering performance
by: David East
THANK 

YOU !
@MarkPieszak

Rethinking Angular Architecture & Performance