Posted onEdited onInbrowser Symbols count in article: 386Reading time ≈1 mins.
Introduction
Reflow and repaint are two important concepts in the browser rendering process. Understanding them can help us optimize the performance of our web pages.
Reflow
Reflow is the process of recalculating the position and size of all elements in the DOM tree. When the layout of the page changes, the browser needs to reflow the page to recalculate the position and size of all elements. The following changes can trigger a reflow:
Resizing the window
Changing the width or height of an element
Changing the padding, margin, or border of an element
Changing the font size of an element
Changing the position of an element
Repaint
Repaint is the process of updating the pixels on the screen. When the layout of the page changes, the browser needs to repaint the affected elements to update the pixels on the screen. The following changes can trigger a repaint:
Changing the background color of an element
Changing the text color of an element
Changing the visibility of an element
Changing the opacity of an element
Changing the z-index of an element
How Browser render pages
The browser rendering process consists of several steps:
Parse HTML: The browser parses the HTML code and creates a DOM tree.
Parse CSS: The browser parses the CSS code and creates a CSSOM tree.
Combine DOM and CSSOM: The browser combines the DOM tree and CSSOM tree to create a render tree.
Layout: The browser calculates the position and size of all elements in the render tree.
Paint: The browser paints the pixels on the screen based on the render tree.
Composite: The browser combines the painted pixels to create the final image on the screen.
In the process of rendering a web page, the browser may need to trigger reflows and repaints to update the layout and appearance of the page.
Reflow: Recalculating the position and size of all elements in the DOM tree.
Repaint: Updating the pixels on the screen.
Reflow will trigger repaint, but repaint does not necessarily trigger reflow.
Posted onEdited onInangular Symbols count in article: 389Reading time ≈1 mins.
What is Angular Router Guard?
Router Guard is a feature in Angular Router that allows you to run some code before the route is activated. It can be used to protect routes from unauthorized access, redirect users to a login page, or perform any other action before the route is activated.
canActivate
Use case: Only allow authenticated users to access the /product page, otherwise redirect them to the login page.
isAuthenticated() { // Put authentication logic here returnfalse; } }
canActivateChild
Similar to canActivate, but it is used to protect child routes. In the following example, only authenticated users can access the child routes of the /product page.
Posted onEdited onInangular Symbols count in article: 361Reading time ≈1 mins.
This post will show you how to style the active link in Angular Router with routerLinkActive and routerLinkActiveOptions.
routerLinkActive
routerLinkActive is a directive that adds a CSS class to the element when the link’s route becomes active.
We set a class name active to the active link, and apply a red background color to the active link. When user click the home or about link, the background color of the active link will change to red.
routerLinkActiveOptions is an input property of routerLinkActive directive that allows you to set the options for the active link. It provides a finer-grained control over the behavior of the active link.
Let’s take a look at the definition of routerLinkActiveOptions:
With this settings, when user input /home#section1 in the browser, the home link will not be active, since the fragment is not exactly the same as the link’s fragment.
You can also config the matrixParams, queryParams, and paths in the IsActiveMatchOptions object to control the active link behavior.
Downgrade the JDK version to previous version, for example jbr-17.
The reason that old version still not work is because after upgrade Android Studio to LadyBug, it automatically set Java 21.0.3 and Gradle 8.0. Even if you downgrade the Android Studio, the settings still remain the same. So you need to manually change the settings to make it work.
Posted onEdited onInandroid Symbols count in article: 110Reading time ≈1 mins.
Introduction
There are two types of SDK location in Android, global SDK location which is used by all projects and project SDK location which is used by a specific project.
Global SDK Location
In Android Studio, open File | Settings | Languages & Frameworks | Android SDK. Here you can see the global SDK location.
Project SDK Location
Open Android Studio, go to File -> Project Structure -> SDK Location. Here you can see the project SDK location.
If your project has file local.properties, you can specify the project SDK location by adding sdk.dir=/path/to/android/sdk in the file. For example:
Posted onEdited onInjavascript Symbols count in article: 282Reading time ≈1 mins.
A question from stackoverflow
The following code does not work, do you know why? When you run the code, you will got the error TypeError: Cannot read properties of undefined (reading 'navigate').
Reason: Code executed by setTimeout() is called from an execution context separate from the function from which setTimeout was called. The usual rules for setting the this keyword for the called function apply, and if you have not set this in the call or with bind, it will default to the window (or global) object, even in strict mode. It will not be the same as the this value for the function that called setTimeout. - From MDN- The this problem for setTimeout
That means router is undefined in gotoProduct function. The reason is that this in gotoProduct function is not the instance of AppComponent. It is the instance of Window object.
How to fix it?
Use Arrow function
Arrow function doesn’t have its own this binding, it will inherit the this from the parent scope. So, you can use arrow function in setTimeout function to keep the context of the parent scope.
1 2 3
setTimeout(() => { this.gotoProduct(); }, 1000);
Use bind
You can also use bind function to bind the this to the gotoProduct function.
1
setTimeout(this.gotoProduct.bind(this), 1000);
Conclusion
Becareful when using setTimeout function in Angular. Always use arrow function in setTimeout function to keep the context of the parent scope.
HostListener is a more powerful way to listen for events because it allows you to listen for events on any element, not just the element that the HostListener is attached to. For example, you can listen for the events from document or window object.
Posted onEdited onInangular Symbols count in article: 747Reading time ≈3 mins.
Introduction
In this article, we will explore the Angular Module Federation feature in depth. Please read the first article in this series to get a basic understanding of Module Federation.
remoteEntry.js
Each time you call loadRemoteModule, Angular will fetch the remoteEntry.js file first from the remote server. What is this file? Let’s take a look at the remoteEntry.js file in the remote project.
You can find the remoteEntry.js file in the dist folder of the remote project. The file is generated by the ModuleFederationPlugin in the webpack configuration. But the file under the dist folder is minimized and hard to read. You can read it on Chrome network tab when you call loadRemoteModule.
This file is very large and contains lots of code, you can scroll down to the bottom or search container entry to find key part.
remoteEntry.js mainly contains the following information:
1. The list of modules that are exposed by the remote project.
In the following example, the remote project exposes a module named ./Component from its ./projects/mfe1/src/app/product/product.component.ts file.
remoteEntry.js is a file that contains the list of modules that are exposed by the remote project.
Angular fetches the remoteEntry.js file first before loading the remote module.
The remoteEntry.js file is generated by the ModuleFederationPlugin in the webpack configuration.
shell/host project does not have a remoteEntry.js file.
loadRemoteModule
How loadRemoteModule works in Angular Module Federation? Let’s take a look at the source code of the loadRemoteModule function in the @angular-architects/module-federation package.
The entry point is from the router file, we call loadRemoteModule function to load the remote module. The loadRemoteModule function is defined in the load-remote-module.ts file in the @angular-architects/module-federation package.
Here is the source code of the loadRemoteModule function from webpack:///node_modules/@angular-architects/module-federation-runtime/fesm2022/angular-architects-module-federation-runtime.mjs
We can see that it uses the import function to load the remoteEntry.js file. The import function is a dynamic import function that fetches the remoteEntry.js file from the remote server. After loading the remoteEntry.js file, it calls the initRemote function to initialize the remote container. This container is used to get the remote module later.
After loading the remoteEntry.js file, then it calls lookupExposedModule function to get the module from the remote project.
Posted onEdited onInangular Symbols count in article: 267Reading time ≈1 mins.
Constructor vs ngOnInit
What’s the difference between constructor and ngOnInit in Angular? constructor is a TypeScript class constructor while ngOnInit is an Angular lifecycle hook called by Angular to indicate that Angular is done creating the component. a common question is when to use constructor and when to use ngOnInit?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
import {Component, OnInit} from'@angular/core';
@Component({ selector: 'app-product', standalone: true, imports: [], templateUrl: './product.component.html', styleUrl: './product.component.scss' }) exportclassProductComponentimplementsOnInit { constructor() { // What should be done here? } ngOnInit() { // What should be done here? } }
constructor is used to initialize the class properties, but it’s not the right place to do any initialization that depends on Angular services or inputs. ngOnInit is the right place to do such initialization.
ngOnInit is an Angular lifecycle hook that is called after Angular has initialized all data-bound properties of a directive. It’s the right place to put initialization logic that depends on Angular services or inputs.