Day15 Challenge: Understanding View Engine in Angular

Angular uses View Engine as its default rendering engine for views in versions prior to Angular 9. In Angular 9, it switched to Ivy as the new rendering engine. However, understanding View Engine is still useful for legacy Angular applications or when upgrading to newer versions.
In this challenge, you will explore how View Engine works and how to manage components, templates, and change detection in Angular using View Engine.
Objective:
Learn how View Engine works in Angular.
Understand how Angular components are compiled with the View Engine.
Work with templates, change detection, and lifecycle hooks in View Engine.
Explore the differences between View Engine and Ivy.
Use View Engine in Angular 8 or prior versions.
What you’ll need to do:
Set up an Angular 8 or earlier project.
Understand how View Engine compiles Angular components.
Implement and experiment with basic components using View Engine.
Implement change detection to see how it works in View Engine.
Create a simple Angular module and explore how the View Engine works behind the scenes.
Step 1: Set Up the Angular Project
Create an Angular Project: For this challenge, you need to work with an Angular version prior to 9 (Angular 8 or earlier) since Ivy is the default renderer in Angular 9 and above.
First, you can install Angular 8 globally, if not already installed:
npm install -g @angular/cli@8
Now, create a new Angular project:
ng new view-engine-challenge --style=scss cd view-engine-challenge
Verify the Angular Version: Ensure that your Angular project is using version 8 (or earlier) by running:
ng --version
Step 2: Create a Simple Component
Let's create a basic Angular component to experiment with the View Engine.
Generate a Component:
ng generate component home
Modify the
home.component.ts
file to include a simple template and some logic:import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-home', template: ` <h1>Welcome to the View Engine Challenge</h1> <button (click)="changeTitle()">Click to Change Title</button> <h2>{{ title }}</h2> `, styleUrls: ['./home.component.scss'] }) export class HomeComponent implements OnInit { title = 'Hello from View Engine!'; constructor() {} ngOnInit(): void {} changeTitle() { this.title = 'Title Changed!'; } }
Here, we’ve created a simple component with a button that changes the title when clicked.
Add the Component to
app.component.html
:Replace the content of
app.component.html
with thehome
component's selector:<app-home></app-home>
Run the Project:
Run the Angular application and see how the component works:
ng serve
Navigate to
http://localhost:4200
and click the button to change the title.
Step 3: Understanding View Engine's Role in Compilation
How the View Engine Works:
Template Parsing: The View Engine parses the templates and compiles them into a format the browser can understand. In Angular 8, View Engine compiles templates into rendering instructions for the browser (DOM operations). This compilation process involves generating a View and Instructions.
Change Detection: Change detection is one of the core features in Angular. With View Engine, Angular keeps track of the state of the application and compares the current state with the previous one. If the state changes, Angular updates the DOM.
In the previous example, when the
title
is changed by clicking the button, Angular will trigger change detection and update the DOM to reflect the new value.This happens within the component’s view and is triggered by the component’s lifecycle hook.
View Engine and Change Detection:
In Angular, View Engine uses dirty checking for change detection. It checks if the values of the component properties have changed and updates the view accordingly.
ngOnChanges()
: Runs whenever an input property of a component changes.ngDoCheck()
: Runs every time Angular performs change detection on the component.
Step 4: Experiment with Lifecycle Hooks and Change Detection
You can implement and experiment with Angular's lifecycle hooks to see how View Engine triggers change detection:
Modify
home.component.ts
to use lifecycle hooks:import { Component, OnInit, OnChanges, SimpleChanges } from '@angular/core'; @Component({ selector: 'app-home', template: ` <h1>Welcome to the View Engine Challenge</h1> <button (click)="changeTitle()">Click to Change Title</button> <h2>{{ title }}</h2> `, styleUrls: ['./home.component.scss'] }) export class HomeComponent implements OnInit, OnChanges { title = 'Hello from View Engine!'; constructor() {} ngOnInit(): void { console.log('ngOnInit: Component initialized'); } ngOnChanges(changes: SimpleChanges): void { console.log('ngOnChanges: Change detected', changes); } changeTitle() { this.title = 'Title Changed!'; } }
Use
ngOnChanges()
:- The
ngOnChanges()
method is called when an input property of the component changes. Here, since we are not using any input properties, it will not be called directly. However, it’s good practice to have it in case you're using inputs in the future.
- The
Use
ngOnInit()
:- This lifecycle hook is used for component initialization. It’s useful for fetching data or setting up initial values.
Test the lifecycle:
- Run the application again and inspect the console output when clicking the button to see the lifecycle hooks in action.
Step 5: Understand How the View Engine Differs from Ivy
While View Engine was the default rendering engine in Angular until version 8, Ivy is now the default engine from Angular 9 onward.
Key Differences:
Bundle Size: Ivy provides better tree-shaking and a smaller bundle size than View Engine.
Rendering: Ivy introduces more efficient rendering strategies with lazy loading and differential loading.
Debugging: Ivy provides better debugging and error messages.
Backward Compatibility: View Engine and Ivy are compatible, but Angular applications using Ivy benefit from better optimizations.
View Engine is based on a view-based approach (creating and managing views per component), while Ivy introduces a more directive-based approach, resulting in better performance and optimizations.
Step 6: Explore Advanced View Engine Features
You can experiment with the following advanced concepts using View Engine to deepen your understanding:
Directives and Pipes: Implement custom directives and pipes, and see how they interact with the View Engine.
Dynamic Components: Learn how dynamic components are rendered with the View Engine using
ComponentFactoryResolver
.Lazy Loading: Although lazy loading was already possible with View Engine, experimenting with it can provide insight into how Angular improves loading time by splitting code into separate chunks.
Bonus Challenge: Upgrade to Ivy
If you're working with Angular 8 or below, try upgrading your project to Angular 9 to use the Ivy rendering engine. After upgrading, check how the bundle size, performance, and rendering behavior change when using Ivy compared to View Engine.
Understanding View Engine is essential if you're working with legacy Angular projects or upgrading an existing app to Angular 9+ where the Ivy rendering engine is the default.
Ivy Usage in Angular
Ivy is the next-generation rendering engine in Angular, introduced in Angular 9. It improves performance, reduces bundle sizes, and introduces new features for the Angular framework. Ivy is now the default renderer for Angular applications, making it essential for developers to understand its usage and benefits.
Key Features of Ivy
Smaller Bundle Sizes: Ivy generates more efficient code by improving tree-shaking. It only includes the code that is used in your application, which results in smaller JavaScript bundles.
Faster Compilation: Ivy’s ahead-of-time (AOT) compiler has been optimized for faster build times, which improves development productivity.
Improved Type Checking: Ivy performs stricter type checking during the compilation phase, reducing runtime errors and improving the development experience.
Lazy Loading: Ivy enhances lazy loading, allowing better module tree-shaking and more granular loading of components. It helps in loading only the necessary code for a particular view or route.
Simplified Debugging: Ivy generates more readable code, making it easier for developers to debug issues. The generated code is also more aligned with the component structure, making it easier to trace.
Dynamic Component Creation: Ivy provides a more flexible API for dynamic component creation, making it easier to load components at runtime.
How Ivy Affects Angular Applications
1. Enabling Ivy in Angular
Starting with Angular 9, Ivy is enabled by default in new Angular projects. For existing projects, you need to ensure Ivy is enabled in the tsconfig.app
.json
file:
{
"angularCompilerOptions": {
"enableIvy": true
}
}
If you need to disable Ivy for any reason (although it's rare), you can set it to false
.
2. Ivy and the Angular View Engine
View Engine: Prior to Angular 9, Angular used the View Engine for rendering.
Ivy: Starting from Angular 9, Ivy became the default renderer. It replaced View Engine to provide improved performance and features.
Ivy does not require developers to make any significant code changes, but it changes how Angular generates the internal code for the application.
Using Ivy Features
3. Ivy and Template Type Checking
One of the core advantages of Ivy is the improved template type checking. This helps Angular developers identify potential errors earlier in the development process by validating the component's template against its types.
For example, if you are binding a property to a non-existent field, Ivy will give you an error during the build time.
<!-- Example of template type checking error -->
<div>{{ myComponent.nonExistentField }}</div>
4. Ivy's ng-template
and ngIf
Improvements
Ivy optimizes how ng-template
and ngIf
work, ensuring that unused templates are not included in the final build. This results in a smaller footprint for conditional content.
<div *ngIf="isVisible">Content is visible!</div>
In earlier versions, unused code might remain in the bundle even if the condition was false. With Ivy, this conditional content is more efficiently handled.
5. Dynamic Component Loading
Ivy makes dynamic component loading much easier using the ngComponentOutlet
directive. You can create and load components dynamically using this directive.
<ng-container *ngComponentOutlet="dynamicComponent"></ng-container>
You can pass a component dynamically and have Angular instantiate it at runtime.
Ivy's Impact on Performance
Ivy significantly improves application performance, especially in large-scale applications:
Faster Rendering: Ivy introduces a more efficient change detection algorithm that results in faster rendering of components.
Tree Shaking: Unused code is eliminated from the build, making the final JavaScript bundle smaller and faster.
Reduced Memory Usage: Ivy uses fewer resources by reducing the number of objects and internal structures used during the rendering process.
Ivy and Angular Package Format (APF)
The Angular Package Format (APF) is the standard for packaging Angular libraries. Ivy supports a new Ivy-compatible package format, which reduces the size and complexity of libraries. This also improves the compatibility of libraries between Angular versions.
Libraries that are built using the Ivy compiler are smaller and more efficient when included in your project.
Subscribe to my newsletter
Read articles from sunny g directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
