Showing posts with label node.js apps. Show all posts
Showing posts with label node.js apps. Show all posts

Tuesday, June 8, 2021

Tips And Tricks To Make Your Node.js Web App Faster

 

Tips And Tricks To Make Your Node.js Web App Faster



Whenever we think about developing a web app, Javascript is the only language that comes to the mind. As per the stack report, Javascript is a popular programming language for web app development because it is easy to learn and works well when combined with other languages and can be used to build various apps. But with the latest trends, market competition increases and businesses are looking for the tools, technologies and  frameworks that allow them to hold a tight grip on various operating platforms with a single solution. Many organizations find Node.js a perfect solution for server-side development to meet the continuous need for apps that can run seamlessly and carefully on all platforms. But working on a Node.js project is not simple. If you may have experienced the issues regarding speed. Here we discuss some tips that are known to speed up your Node.js web application development tremendously. So, let’s see each of them one by one.

Know the amazing new features of Node.js 16 at- What’s New In Node.js 16?

Tips And Tricks To Make Your Node.js Web App Faster-

1. Limited Use Of Synchronous Functions-

Since Node.js is designed with single thread architectures and asynchronous coding is heavily used in Node.js to ensure non-blocking operational flow. With the availability of various synchronous components, it would block the applications and show down the app performance. Asynchronous coding lets you use queues to monitor workflow, allowing you to append extra tasks and add additional callbacks without blocking the main thread. While you are using the Asynchronous methods, in some cases, it is feasible to find your web page making some blocking calls. Don’t worry! This is common when you use third-party modules. So, you need to keep an eye on libraries and try to avoid them dominating synchronous calls.

2. Run In Parallel-

To deliver the HTML page for any dashboard, the node.js application needs to retrieve a lot of data for the dashboard. You need to make multiple internal API calls to fetch different data. When delivering the dashboard you may execute following hypothetical calls:

The user profile – getUserProfile().
The site list – getSiteList().
Subscriptions – getSubscriptions().
currnet site – getCurrentSite().
Notifications – getNotifications().

Basically, it needs to retrieve the data from user browsing session to verify they’re logged in and it needs to pull in data about the user and site for the dashboard. So as to retrieve this data, app needed to make some calls to internal API functions. Some of them could take up to 2 seconds to complete. Every request was made by a separate express middleware, means they were running in series. Each request would wait for previous one to complete before starting.

As node.js is well suited to run multiple asynchronous functions in parallel, and various internal API requests didn’t depend on each other, here come the parallelism- fire off all requests at once and then continue once all they’ve completed. 

You can do something like this:

function runInParallel() { 
async.parallel([
getUserProfile,
getSiteList,
getSubscription,
getCurrentSite,
getNotifications
], function(err, results) {
  //This callback runs when all functions complete });
}

3. Use Caching-

If you are fetching data that doesn’t change frequently, you may cache itto improve performance. For instance, following snippet fetched the latest posts to display on a view:

var router = express.Router();
router.route('/latestPosts').get(function(req, res) {
  Post.getLatest(function(err, posts) {
    if (err) {
      throw err;
    }
    res.render('posts', { posts: posts });
  });
});

If you don’t publish blog posts frequently, you can cache the posts array and clear the cache after interval. For instance, you can use redis module to do this. For that, you need to have Redis installed   on your server. Then you can use a client called node_redis to store key/value pairs. This snippet shows how we can cache the posts:

var redis = require('redis'),
    client = redis.createClient(null, null, { detect_buffers: true }),
    router = express.Router();
router.route('/latestPosts').get(function(req,res){
  client.get('posts', function (err, posts) {
    if (posts) {
      return res.render('posts', { posts: JSON.parse(posts) });
    }
    Post.getLatest(function(err, posts) {
      if (err) {
        throw err;
      }
      client.set('posts', JSON.stringify(posts));    
      res.render('posts', { posts: posts });
    });
  });
});

Thus, first of all we check if the posts exist in the Redis cache. If so, we deliver the posts array from cache. Otherwise, we retrieve the content from DB and then cache it. And after an interval we can clear the Redis cache so as to fetch the new cache.

4. Use GZip Compression-

Enabling the gzip compression can hugely impact the performance of web apps. When a gzip compatible browser requests for some resource, the server can compress the response before sending it to the browser. If you don’t use gzip for compressing static resources it may take more time to fetch for the browser. In Express app, you can use built-in express.static() middleware to provide the static content. Also, you can use middleware compression and provide the static content. Here, is a code snippet that shows how to do it:

var compression = require(‘compression’);
app.use(compression()); //use compression
app.use(express.static(path.join(_dirname, ‘public’)));

5. Make Use Of Client Side Rendering When Possible-

Because of the client-side MVC/MVVM frameworks like Ember, Meteor, and AngularJS eases the creation of single page applications. Rather than, rendering on the server side you will only expose APIs that send JSON responses to the client. On the client side, you can use a framework to consume the JSON and display on the UI. Sending JSON from server can save bandwidth and so improve speed because you don’t send layout markup with every request. Instead you just send simple JSON that is then rendered on the client side.

6. Use Standard V8 Functions-

Various operations on collections like reduce, map and forEach are not supported by all browsers. To solve the browser compatibility issues you can use some client side libraries on the front end. With Node.js you can use built-in functions for manipulating collections on server side.

7. Use nginx In Front Of Node-

Nginx is a lightweight server used to reduce load on your Node.js server. Rather than serving static files from Node, you can configure nginx to provide static content. You can also set up nginx to compress the response using gzip so that the response size is small. Hence if you’re running a production app you may need to use nginx to improve the speed. 

8. Minify And Concatenate JavaScript-

Your web app speed can be improved by minifying and concatenating various JS files into one. When the browser encounters a <script> element the page rendering is blocked until the script is fetched and executed. For instance, if a page includes six Javascript files, the browser will make six separate HTTP requests to fetch those. Performance can be improved to great extent by minifying and concatenating those six files into one. Similar applicable to CSS files also. You can use a build tool such as Gulp/Grunt to minify and concatenate asset files.

9. Optimize Queries-

Consider that you have a blogging app that shows the latest posts on the home page. You may write something like this to fetch data using Mongoose:

Post.find().limit(10).exec(function(err, posts) {
  //send posts to client
});

But, the issue is find() function in Mongoose fetches all fields of object and there might be some fields in the Post object that are not needed on the homepage. For example, comments field holds a comments array for a specific post. If you’re not showing the comments, you can exclude it while fetching. And this will improve the speed. We can optimize the above query with-

Post.find().limit(10).exclude('comments').exec(function(err, posts) {
  //send posts to client
});

10. Don’t Store Too Much In Sessions-

In an Express web app, the session data is stored in memory. When you store huge amounts of data in the session, it adds significant overhead to the server. Hence, you can switch to some other type of storage to keep session data or try to reduce the amount of data stored in session. For instance, when users log into an app, you can store their id in the session rather than storing the entire object. Consequently, on each request you can recover the object from the id. You may also need to use MongoDB or Redis to store session data.

Wrap Up-

Most of the web development companies and freelancers uses Node.js to build great web apps. Knowing the above tips and tricks will help you to improve the performance of Node.js web app. There can be some other tips too. If you are also thinking develop web app with Node.js, then you must know these tips. You can hire Node.js developers of Solace team for effective web app development. Connect with Solace and get a free quote for web app development. We will be happy to help you.


Wednesday, April 7, 2021

Node.js Best Practices To Follow In 2021



Even though only 12 years old, Node.js has emerged to be one of the most popular web development frameworks in the last decade. Built on Chrome’s V8 JavaScript engine, Node.js projects are easy to start. Being an asynchronous event-driven JavaScript-based runtime, Node.js is widely used for building lightweight and scalable network-driven applications. Node.js apps can be scaled-up easily in both directions- horizontal and vertical. Node.js apps are used for both client-side and server-side applications. It has an open-source JavaScript runtime environment/model which provides single module caching. Here we’ll see some of the best practices for Node.js development.

With these best practices, app automatically is able to minimize Javascript runtime errors and turn it to high performing, robust node.js apps and node processes. Knowing the important JavaScript concepts will help every Node.js programmer to develop a high performing Node.js app. You can know these javascript concepts at- 10 JavaScript concepts every Node.js programmer must master.

Node.js Best Practices To Follow In 2021-

1. Take A Layered Approach-

Node.js frameworks lets you to define route handlers as callback functions that are executed when a client request is received. With the amount of flexibility that these frameworks provide, it might be enticing to define all business logic directly inside those functions. If you start in this way, you’ll get to know that things can quickly escalate and before you know it,  your petite server routes file can turn into a clunky, unwieldy and messy blob of code that is difficult to read, maintain and unit test. Hence it is good to implement the ‘separation of concerns’ programming principle. According to this, we should have different modules to address different concerns pertinent to our app. For server side apps, different modules should take the responsibility of catering to different aspects of processing a response for client request. Usually, this is likely to unfold as-

Client request, business logic + some database manipulation- returning the response. These aspects can be handled by programming three layers as shown below-

Controller layer-

In this module of code, API routes are defined. Here you define only your API routes. In route handler functions, you can deconstruct the request object, select the important data parts and send them to the service layer for processing.

Service layer-

Here business logic lives. It contains a set of classes and methods that take singular responsibility and are reusable. Service layer allows you to effectively decouple the processing logic from where the routes are defined.

Data Access Layer –

This layer can take up the responsibility of talking to database-fetching from, writing to and updating it. All SQL queries, database connections, models, ORM should be defined here. 

Three layer setup serves as a reliable scaffolding for most Node.js apps, which makes your apps easy to code, maintain, debug and test. 

2. Use npm For A New Project-

Npm init will generate a package.json file for project which shows all the packages/node apps of npm install has the information of your project.

$ mkdir demo-node app
$ cd demo-node app
$ npm init –yes

Now, you have to specify an engine’s key with currently installed version of node (node -v): 

"engines": {
  "node": "10.3.16"
}

3. Use Linting Packages-

There linting tools available, ESLint is one that most popular linting package that is used to check possible errors in code and also check code styles to meet best practices standards. It detects issues to any code patterns that could lead to any security threats and possible app-breaking that could occur in the future. There are some tools available that automatically format code and put it in a more readable way. It also resolves minor syntax errors like adding semicolons at the end of each statement etc.

Know the best Node.js packages to improve developer productivity at- 15 Essential Node.js Packages To Improve Developer Productivity.

4. Proper Naming Conventions For Constants, Variables, Functions, And Classes-

You should use all constants, functions, variables and class names in lowercase when we declare them. Also, you should not use any short forms rather than using only full forms that easily understandable by everyone using it. You should use underscore between two words.

Code Example-

//for class name we use Uppercase
class MyClassExample {}
// Use the const keyword and lowercase
const conf = {
Key: ‘value’
};
// for variables and functions names use lowercase
let variableExample = ‘value’;
function foo() {}

5. Use Of Strict Equality Operator (===) –

Use strict equality operator === rather than weaker abstract equality operator = ==, == will convert two variables to a common type then compare them while === doesn’t type case variables, and ensures that both variables are of the same type and equal.

Example-

null == undefined //true
true == ‘true’ //false
False == undefined //false
“ == ‘0’    //false
False == ‘0’   //true
0 == ‘0’       //true
‘\t\r\n’ == 0  //true
0==”      //true
False == null    //false

Above statements will return false when === is used.

Know more at- https://solaceinfotech.com/blog/node-js-best-practices-to-follow-in-2021/

Tuesday, September 8, 2020

A Guide To Develop Real Time Apps With Node.js


We have been using lots of mobile applications to carry out day to day tasks. So building applications that users can interact with in real-time has become a standard for many developers. The applications that today we use whether they are mobile, web or desktop apps have at least one real time feature. Mostly real-time messaging and notifications are the commonly used real-time features that we use in applications. 

What Do Real Time Applications Do?

As mentioned before, real time applications functions within a time frame the user feels it is occurring in real time. Within real-time applications or real-time computing, the latency is set under a defined value, typically estimated in seconds.

Know the important points to consider while developing real time apps at- What To Consider While Developing Real Time Applications?

Role Of Node.js In Real-Time Applications-

Node js helps with its non-blocking I/O and event-driven features to the applications where speed and scalability are constant focus. Nodejs gives continuous two-way connections to applications like social media, forums, ad servers, or stock exchange software.

1. Reusing And Sharing-

Nodejs supports microservices architecture and it allows developers to reuse the library code package and share it in various projects. It not only saves development time and increases productivity.

2. Scalable And Rapid-

As Node Js is javascript based, it executes rapidly like JS. So an application with event loop easily handles multiple client requests.

3. Event Based Server-

Real time apps handles a large number of real-time users. Node.js development supports response based on the event-driven server that supports non-blocking functioning.

4. Proxy Server-

Node js will be your best choice where intermediary administrations are necessary. To use node.js server as a proxy server, a developer needs to add a code of 20-line, and your application will turn into an ideal fit to support streaming information from numerous sources.

5. SEO Friendliness-

The backend rendering by Node.js gives the website more visibility and engagement too. The applications get more speed and user experience as well as a get performance that is required to rank according to SEO prospects defined by Google.

Building A Real-Time Chatroom With Node.js-

Here we’ll see how to build a simple chatroom that users can use to communicate  with connected users. With this, multiple users can connect to the chatroom and users can send messages that will be visible to all users connected to the chatroom.

Features of simple chatroom-

  • Change the username of the user
  • Send messages
  • Show if another user is currently typing a message

Application Environment Setup-

  1. Create directory
  2. Run the npm init to set up package.json file.

Install Dependencies-

Here we’ll use express, ejs, socket.io and nodemon packages to build app.

  • Ejs- It is a well known JS template engine

Command to install ejs- npm install express ejs socket.io –save

  • Nodemon- This package restarts the server every time we make any change to the application code. Due to the use of Nodemon you don’t need to manually stop and start the server every time when you make change. Command to install Nodemon
npm install nodemon --save-dev

Add a start script to your package.json file to start the application with nodemon. 

"scripts": {
"start": "nodemon app.js",
 },

Use the following command to start app-

npm run start

Set Up The Application Structure-

With all the Dependencies that will need for this project installed, build app project structure. For this, you have to create some directories. Get that done so that your app structure look like

|--app.js
|--views
|--node_modules
|--package.json
|--public
|--css
 |--js
  • app.js: file we will use to host our server-side code
  • views: folder containing the views (ejs)
  • node_modules: where we installed our dependencies
  • package.json npm configuration file
  • public: directory we will use to store our assets, like css files, javascript files (for the client side), and images.

Step 1: Build Server-

It is necessary to get express up and run. For this open app.js file and paste the code as follows:

const express = require('express')
const socketio = require('socket.io')
const app = express()
app.set('view engine', 'ejs')
app.use(express.static('public'))
app.get('/', (req, res)=> {
    res.render('index')
})
const server = app.listen(process.env.PORT || 3000, () => {
    console.log("server is running")
})

Now start working on the sockets.io initialization. Add the following code at the end of app.js file.

//initialize socket for the server
const io = socketio(server)

io.on('connection', socket => {
    console.log("New user connected")
})

If you now run your server with npm start you will have the option to receive new socket connections. So let’s build a front-end.

Step 2: Build Front-End-

Create a template in views folder, and for this create index.ejs file and paste the below code:

<head>
    <title>Simple realtime chatroom</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        <div class="title">
            <h3>Realtime Chat Room</h3>
        </div>
        <div class="card">
            <div class="card-header">Anonymous</div>
            <div class="card-body">
                <div class="input-group">
                    <input type="text" class="form-control" id="username" placeholder="Change your username" >
                    <div class="input-group-append">
                        <button class="btn btn-warning" type="button" id="usernameBtn">Change</button>
                    </div>
                </div>
            </div>
            <div class="message-box">
                <ul class="list-group list-group-flush" id="message-list"></ul>
                <div class="info"></div>
            </div>
            <div class="card-footer">
                <div class="input-group">
                    <input type="text" class="form-control" id="message" placeholder="Send new message" >
                    <div class="input-group-append">
                        <button class="btn btn-success" type="button" id="messageBtn">Send</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
    <script src="/js/chatroom.js"></script>
</body>
</html>

Note how we have included the script of the client-side socket.io library and the custom javascript file we are going to use in this code.

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
<script src="/js/chatroom.js"></script>

We have added a button with ID messageBtn to send a new message and button with ID usernameBtn to submit new username. All user messages will appear in the unordered list with ID message-list. If a user is typing a message, it will appear inside the div with class info. Now the buttons are static. Let’s connect the front-end to the server.  Create a new Javascript file named chatroom.js inside the js folder of the public directory. Inside Javascript file, we have to connect the socket from front-end.

(function connect(){
    let socket = io.connect('http://localhost:3000')
})()

Step 3: Send Message-

Now we implement the send message feature. First, we will set up the front-end to emit a new_message event when a new message is submitted. Since the client-side should also be configured to get new messages other users send from the server, the application should also listen to receive_message events on the front-end and show the new message on the web page properly.

We can get done both these tasks using the following code-

let message = document.querySelector('#message')
let messageBtn = document.querySelector('#messageBtn')
let messageList = document.querySelector('#message-list')
messageBtn.addEventListener('click', e => {
    console.log(message.value)
    socket.emit('new_message', {message: message.value})
    message.value = ''
})
socket.on('receive_message', data => {
    console.log(data)
    let listItem = document.createElement('li')
    listItem.textContent = data.username + ': ' + data.message
    listItem.classList.add('list-group-item')
    messageList.appendChild(listItem)
})

Each time the receive_message event occurs on the client side, we change our DOM to deliver the message into the screen. On the back-end side, when you receive a new_message event, you have to emit a new event to all clients. For this, use io.sockets.emit().

Change connection event in app.js file as follows:

io.on('connection', socket => {
    console.log("New user connected")
    socket.username = "Anonymous"
    socket.on('change_username', data => {
        socket.username = data.username
    })
    //handle the new message event
    socket.on('new_message', data => {
        console.log("new message")
        io.sockets.emit('receive_message', {message: data.message, username: socket.username})
    })
})

At the time of handling new_message event, server emits a receive_message event to connected users.  This event is received received by all users connected to the server, so that new messages are displayed on their chatroom interfaces.

Step 4: I’m typing-

For this, we add new event listener to the message input box to emit typing event when a keypress occurs. As keypress occurs on the message input box, it indicates user is typing a message, the typing event tells server that user is typing a message. The client side also listens to typing events emitted by the server to know whether another user is typing a message and show it on the UI.

Inside the connect function in chatroom.js, we add the following code.

let info = document.querySelector('.info')
message.addEventListener('keypress', e => {
    socket.emit('typing')
})
 
socket.on('typing', data => {
    info.textContent = data.username + " is typing..."
    setTimeout(() => {info.textContent=''}, 5000)
})