If you are developing angular apps or you are owing angular apps or if you are deploying the angular apps then optimizing the deployment is the something which has great importance. Actually there are multiple ways in which you can optimize the angular deployment and one of those is Server Side Rendering (SSR). Angular officially recommends using Server Side Rendering for many reasons and it also provides a mechanism called Angular Universal to make your normal angular app to become compatible with Server Side Rendering.
Table of Contents
What is Server Side Rendering ?
Server Side Rendering is a mechanism by which you can render the client-side or universal app to HTML on the server. That means, you are not directly rendering the app to the browser.
In general, when we hit any web application which is not functioning with SSR, we tend to download the front end directly from server whereas in SSR you don’t directly download the client-side.
In Server Side Rendering, we don’t send lots of JavaScript to the client. This means, in SSR, we only send text and links to the browser and rest everything is handled at server side.
If we say it in one statement then SSR handles all logic, data fetching, templating and routing on the server and not on client side. You can read more here.
How to implement Server Side Rendering in Angular ?
Angular provides a wonderful feature called Angular Universal which can convert our normal angular app to a Server Side Rendering app. This Angular Universal is nothing but setting up a dummy express server in our front end so that we can actually make use of this server and render our application via server. This Angular Universal has made it very easy to implement SSR in our app.
So before implementing Angular Universal I would recommend you to use the latest version of angular so that it does not give any problem while using the commands for Angular Universal.
Here are some easy steps to get to the latest version of angular.
How to update your app to the latest version of angular ?
This looks very easy to many but perhaps this is the most crucial step for developers. Whenever they try to use the update commands, they will end up with lot many errors. They generally use the below command and encounter many errors.
ng update @angular/core@12 @angular/cli@12
If you want to use the above command, you can use but then you may have to manually fix many things. Here I try to make it easy and better. Just check the below steps.
1. Go to your package.json and check how many extra ‘dependencies’ and ‘devDependencies’ you have listed there. If you don’t know, just go here and compare your package.json with this one.
2. Any differences, you see in your version of package.json from the other one, you can park them aside. That means, you can keep the extra dependencies aside and just paste the package.json from here.
3. Now you have most recent versions of dependencies in package.json.
4. Remove ‘node_modules’ folder and also the package-lock.json file from your folder structure.
5. Now install all the dependencies again by below command.
npm install
6. Once you install the dependencies, you will have all the latest versions. Now you should bring all those previous ‘dependencies’ and ‘devDependencies’ here which you have parked aside in step 2.
7. So now you have all the previous dependencies listed, you can install them by using the command given in step 5. That means use npm install again and if you see any errors while installing, you should check the logs and find out which package is actually causing the error. This happens when the packages are not updated by third parties and because of which they are not compatible to align with other dependencies.
8. If you have any dependencies/packages creating issue during installation then you should try to find out an alternative to them. You have to remove those dependencies which are creating issue.
9. Once you have all the dependencies installed, you should run the application using below command.
npm start
Or ng serve
Or use npm run ng serve (If you don't have admin rights)
10. You may still find some issues while compiling the application because the new angular versions always come with some new features and new changes to the implementation so you have to abide by those changes. You can easily do those changes by searching angular official documentation.
11. If you are updating from very old version of angular to latest then you will see lot many errors. In that case, you may follow the recommended approach to update the app i.e. to use the ‘ng update’ command.
Now that we have angular latest version in place, we will add the angular universal dependencies so that we may take advantage of angular universal.
How to use Angular Universal in our angular application ?
So now we are ready to install Angular Universal in our app. If you have not already updated your app to the latest version of angular then please do that so that you don’t find any issues.
We will use a simple command to add all the dependencies of angular universal. This one command will add 4 new files to our folder structure and update 5 other files.
ng add @nguniversal/express-engine
Or npm run ng add @nguniversal/express-engine (If you don't have admin privileges)
After installing, It will look like below.
Now if you want to run your angular universal application, you will have to use below command only.
npm run dev:ssr
Let’s now learn to deploy the angular universal application to NGINX server.
How to deploy your angular universal application with NGINX server ?
It’s time to deploy the angular universal application to NGINX server. For this to happen, we need below things.
1. A hosting server
2. A static IP
3. An NGINX server
So for setting this up, you can follow my previous article by following which you will be able to set up a free AWS EC2 Ubuntu instance with NGINX server and you will also get a free static IP. Here are the highlights of article.
- The article helps you to install an AWS EC2 ubuntu instance with complete steps.
- The article also articulates ‘How to connect to AWS EC2 Linux (Ubuntu) Server using RDP Client?’ but you can skip that.
- Article also illustrates ‘How to set up a MEAN app to EC2 ubuntu server’. If you are using an application without a backend and a database then you must skip ‘Install packages for back-end’ and ‘How to install and set up MongoDB in Ubuntu NGINX Server’.
- At the end of this article, you must have an angular application deployed to Ubuntu NGINX server with https.
Once you are done with this, you can follow the further steps. I am considering that, you have already converted your angular app to angular universal, you have an nginx server set up with SSL certificates and you have also cloned your angular universal application to the /var/www/html/front-end. Here you will see some changes to the previous article. Please follow these steps directly in putty terminal.
1. We will create a new build now. So use the below command.
cd /var/www/html/front-end
sudo npm run build:ssr
This will generate a dist folder with two sub folders, ‘browser’ and ‘server’. We will render our application using main.js file inside ‘server’ folder. Please note that this build will have the most optimized version of your code.
2. We will change the NGINX server configuration so that our app can render from server side. Go to the site configuration file by following below commands.
cd /etc/nginx/sites-available
ls
sudo vim <your-site-name> (Write the name of your config file which you get from 'ls' command)
Change the file like below.
#http
server {
listen 80;
listen [::]:80;
server_name <your-site-name>.com www.<your-site-name>.com;
return 301 https://$server_name$request_uri;
}
#https
server {
listen 443;
ssl on;
ssl_certificate /var/www/html/ssl/bundle.crt;
ssl_certificate_key /var/www/html/ssl/server_private.key;
server_name *.<your-site-name>.com;
access_log /var/log/nginx/nginx.vhost.access.log;
error_log /var/log/nginx/nginx.vhost.error.log;
root /var/www/html/<location-of-your-browser-folder-inside-dist-folder-where-index.html-is-listed>;
index index.html index.htm;
location / {
try_files $uri $uri/ /index.html?$args;
proxy_pass http://localhost:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /api/ {
proxy_pass http://localhost:4000/;
}
location = /favicon.ico {
access_log off;
log_not_found off;
}
location = /robots.txt {
access_log off;
log_not_found off;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}
3. Now go to the root folder by using below command.
cd /var/www/html/front-end
4. Install ‘forever’ for running the application even when the terminal is closed. I am using ‘forever’ because ‘pm2’ has lot of issues.
sudo npm install -g forever
5. Run the application like below.
forever start <location-of-the-main.js-file-located-inside-server-folder-of-dist>
e.g. forever start dist/............../main.js
This way, you will be able to run the angular universal application. You can check your app at your domain. Also if you want to use the gzip compression for your application to speed up the performance, you can check below.
How to use gzip compression in an angular universal app
Generally, there are two ways to use gzip compression. The first is to do gzip compression at front-end and keep the zipped files at server so that server can render compressed files and second way is to allow server to compress the files and then render. The first way is better and is called static compression. Static compression is much faster than dynamic compression (On the fly server compression). Let’s learn it step by step.
Below steps are for angular front-end application and you should not follow them directly at server.
1. Install gzipper in your angular universal app by using below command.
npm install -s gzipper
2. Go to your package.json file and under “scripts”, change the command like below.
"build:ssr": "ng build --configuration production && gzipper compress ./dist && ng run <app-name>:server",
Now create a build at server again.
cd /var/www/html/front-end
sudo npm run build:ssr
Now if you check your ‘browser’ folder inside ‘dist’ folder, you will see zipped files along with normal bundle files. Let’s now change the nginx configuration in server. You will have to go to nginx config file like below and make changes.
vi /etc/nginx/nginx.conf
Under this file, you have gzip section already. Go there. It will be like below.
gzip on;
#gzip_vary on;
#gzip_proxied any;
#gzip_comp_level 6;
#gzip_buffers 16 8k;
#gzip_http_version 1.1;
#gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
You should change it like below. Remove hash from all the statements and add ‘gzip_static on;’
gzip on;
gzip_static on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
Save it and that’s it. Restart the NGINX server.
sudo /etc/init.d/nginx restart
That’s pretty much it. If you have any further questions, please ask them in comment section.
Aside from being an engineer, I am a software developer, an enthusiastic musician, a regular reader and a hobbyist writer. I love traveling, exploring new places and, of course, playing games (all sorts).