How to speed up react app being sent to the client Azure - javascript

In my application i have the client in one folder and the server in another. I successfully deployed the application to azure web apps, this can be found at: https://wulfdevpage.azurewebsites.net/ However, it takes nearly 15 seconds for the page to respond and render the client, (this is just the basic react-app client for now, but ill build this out further soon.) my problem is simply that it takes way to long for the server to respond with the application.
here is my folder structure
--client
- build
// - (other parts of the react app)
--server
- [other folders, like controllers, models etc.]
- server.js //entry point
in my server.js file this is how the build folder is served up.
// Set static folder
const __dirname = path.resolve();
app.use(express.static(path.join(__dirname, "public")));
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "/client/build")));
app.get("*", (req, res) =>
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"))
);
} else {
app.get("/", (req, res) => {
res.send("API is running...");
});
}
This works, but again, it's taking nearly 15 seconds from the initial request to the client reaching my computer to make this work. I know a simple solution would be to just move the client to something like azure static web apps but I really don't want to go this route, I'd rather keep them all in one place for convenience's sake. There simply must be a quicker way to serve up the client.

The major cause of performance of initial load issue is adding too many components into a single bundle file, so it takes more time to loading of that bundle files. To avoid this kind of issue, we need to structure our components in an optimized way.
To solve this react itself has a native solution, which is code-splitting and lazy loading. Which allows splitting bundle files into a smaller size. Refer here
The performance issue fix with some configuration changes. If you haven't done this already, please check below once
Enable HTTP/2
HTTP/2 brings major changes to our favorite web protocol, and many of the changes aim to improve performance and reduce latency on the web
Turn Off the Application Request Routing Cookie
Turn off the routing cookie in the Configuration blade to improve performance and resiliency.
Keep the App Service Always On
To prevent the idle shutdown, you can set the Always On flag in the App Service Configuration blade.
Use local cache
In App Setting create the app with a key of WEBSITE_LOCAL_CACHE_OPTION and a value of Always. You'll then have a d:\home folder pointing to a local cache on the machine and populated with a copy of your site content.
Use App Service diagnostic to fetch more details on the issue
Refer here for more info

Related

Rendering react with node.js in development

I am (very) new to node.js and I am trying to get a development environment started with React.
const express = require('express')
const mongoose = require('mongoose')
const app = express()
// this displays the index.html file
app.use(express.static(__dirname + '/public'));
// trying to see the app.js
app.get('/', (req, res) => {
res.render('app')
})
app.listen(process.env.PORT || 5000);
Right now I am simply trying to be able to view my app.js when I run nodemon. But right now it is only showing the index.html file in the public folder. and when I run npm start it renders both the index.html and the app.js.
I am 100% doing something wrong and am not in my element here. Any help/advice would be appreciated.
My full repo is here for viewing here
Thank you in advance.
Your code is simply serving a static HTML file located in the public directory everytime the user make a GET request to the root (in your case, localhost:5000). It is not interacting with React yet.
Usually when starting a project with React (frontend) and Node (backend), you would create them as separate projects, in separate repositories.
So you could create a React application using a bootstrap such as create-react-app running on PORT 3000 and in another terminal tab, start your NodeJS application in PORT 5000 like in your example. Then, you can call your backend endpoint from your frontend React application, by referencing http://localhost:5000
By doing this, your backend code don't need to serve static files anymore, it can return data such as JSON and make connections to a database for example.
Since your question is not specific enough, you could be talking about server side render. In server side render apps using Node and React, you have a frontend built with React and a Node server that will return the same React code as a string, using the react-dom/server package to help. This is more complex, but basically you will have the same React code on the client AND on the server. There are performance benefits, because the user can see some content rendered right when he enters the page, without having to wait the React bundle (javascript file) to load. If you want to know more about creating a server side render app with React and Node, there is a nice digital ocean tutorial here
If you want to connect your react js project to the node js
In Development
you simply run their server and start it
In Production
You can use sendFile function coming from express.js to run the frontend
https://dev.to/loujaybee/using-create-react-app-with-express

Host static HTML in Azure Web App Service

I'm azure beginner
I've created nodejs service and deployed it to Azure Web App service, it works as expected.
So, I have resource group mars-app and existing Web App service application my-mars-web-app.
Now, I want to add static HTML file, to show it when user goes to root URL https://***.azurewebsites.net/
To achieve it,
I have cloned github repo with client side to azure storage with azure cli help
In cliend code folder, I have tried to run az webapp up -g mars-app -n my-mars-web-app --html, but every time I'm receiving:
The webapp my-mars-web-app is a Linux app. The code detected at '/home/serhii/azure-website' will default to '<module 'os' from '/opt/az/lib/python3.6/os.py'>'. Please create a new app to continue this operation.
Because of above error, I have added index.html to dist diretory in my backend app
app.get('/', function (req, res) {
res.sendfile('dist/index.html');
});
and it works. But I'm not sure it is a good solution
What the best practice to add static HTML files to existing Web App service?
This question may be a dublicate of this question, but it was asked 5 years ago, so maybe something changed.
P.S. I know about Static Web Apps, but it is in preview and I'm interested in more generic solutions.
Thanks in advance
[UPDATE]
Here an article about deploying react app
Why you want to add static HTML files to existing web app services, for update or others?
In my opinon, now that you have used git, you can use continuous deployment.
When you modify your program (add new or modify files), in the Action of github, you will see the program start to deploy again. This should be the best deployment plan.

Next.js : no response when request goes high in server-side rendering page(dynamic routing)

I’m using Next.js and custom server(express js) as Next.js example in GitHub.
I have a page, for example “/post/[id]”, which is using next.js dynamic routing.
The problems is, when the requests for this page goes high, response time goes high too and some times, there are no responses at all.
At this point, memory usage goes high but does not exceed maximum allowed memory.
What did I miss here? Is there any config I should configure?
Is it a Next.js constraint?
Is it a Next.js constraint in a large environment of client requests?
related links’s:
Next.js custom server express
Next.js dynamic routing
Can tell about my experience:
1.check if you correctly pass NODE_ENV
=> const dev = process.env.NODE_ENV !== 'production'
id dev mode next.js tryong to rerender the page from time to time
check where you deploy chain front -> back -> database
maybe you should install nginx
it be able to return prerendered pages before next.js

Issue with routing in react app

I have a web app. Back end with node and front end with React. Setup (simplified) goes like this:
index.js (the server)
client
package.json
The client
Now, the client folder contains a front end web application, its contents are basically same as what you get when you type create-react-app.
Inside client there is a build folder which I created by running npm run build from within the client folder.
Server
Now, the index.js from my main folder acts as the node server, inside it I have a line like:
app.use(express.static(__dirname + "/client/build"));
Using this approach I have merged my node server and a client front end application (located inside client folder). You can see I told the server to serve files from the client/build.
All was working fine, till I encountered this.
If I click a react button in my client app which manually calls my router using say:
this.props.router.push('/listmovies');
it correctly shows the page.
But if I type same page in URL address bar and hit ENTER I get error:
Cannot GET /listmovies
The latter error I am pretty sure comes from node server. Because there is no listener for listmovies in index.js (and there should not be). You see basically I think node is intercepting the call and giving me an error. Whereas in my former case where I called router.push I get a correct page.
I hope I managed to explain my problem. Can someone help how to solve this issue?
You have to make the express application redirect all requests to the main React file so react-router can take over. Something like this below the app.use.
app.get('*', function(req, res) {
res.sendFile(__dirname + '/client/build/index.html')
})
This basically handles all wildcards and points it to the index.html. Mind you if you are also implementing API routes on the express app have them above this wildcard statement because otherwise it will intercept them and treat them as client side react-router routes instead of server-side API routes.

Setting up Express with Angular

I can setup Angular in my web app using ASP/Visual Studio rather easily, but I want to get into the Node world, more specifically Express. I'm not truly understanding a basic route handler for Express, that will support the paradigms that Angular has.
For example, when setting up an Express file, there's a million examples, but almost all of them use Jade for templating, and I'm against Jade's syntax and have no desire to utilize it.
So far, I have this for my Express server (I have commented out some questions regarding my decisions made so far):
var express = require('express'),
path = require('path');
var app = express();
var env = process.env.NODE_ENV || 'development';
// 1) Is this really necessary if I'm going to utilize Angular routing for views?
app.set('views', path.join(__dirname, '/app/views'));
app.use(express.static(__dirname + '/public'));
// 2) I'm assuming this is the desired pattern for utilizing Angular.
// A catch-all handler that serves up an html file, which will then
// hand off the rest of the routing to Angular?
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/index.html'));
});
const PORT = 3000;
app.listen(PORT);
console.log('Listening on port: ' + PORT);
The questions I have are:
Is app.set('views', ...) necessary in an Angular app through Express or is it really intended for a Jade/EJS templating workflow? If it's useful to Angular, what path should I point it to? My Angular views? Or just the static html file that will serve as the container to all angular views?
I'm assuming app.use(express.static(...)) is still needed for ensuring Express can serve up public static resources, like css/javascript.
Is an app.get('*', ...) { res.sendFile('path/to/index.html') } route handler the accepted pattern for serving up one html file, which will contain all necessary Angular usage?
For Angular, is it normal to only have one html file for the entire of your application, and then just use Angular's routing and controllers/views to handle the rest?
Is app.set('views', ...) necessary in an Angular app through Express or is it really intended for a Jade/EJS templating workflow? If it's useful to Angular, what path should I point it to? My Angular views? Or just the static html file that will serve as the container to all angular views?
If you need to render a view on the server side and then send it to the client, you need this. Otherwise (in your case) no. You can just send the file to the user or generate a user-specific output based on the parameters that user has sent to the server. It could be anything, HTML file, json or just simple text.
I'm assuming app.use(express.static(...)) is still needed for ensuring Express can serve up public static resources, like css/javascript.
You are right. If you need to serve the static content as well, the best way is to use express.static, however you can catch the requests and serve the content by yourself.
Is an app.get('*', ...) { res.sendFile('path/to/index.html') } route handler the accepted pattern for serving up one html file, which will contain all necessary Angular usage?
If for each and every other requests that the previous routes didn't catch, you need to send the exact same file, yes it is fine.
Remember if you need to serve other HTML files as templates and they are not in the same directory as you pointed in express.static to, the client could not have access to html files. I'll discuss it in a bit.
However, I believe it is a good practice to define all the routes and not just put a * to catch them all. It is better to define a pattern at least, it would be easier to maintain the code later on.
For Angular, is it normal to only have one html file for the entirety of your application, and then just use Angular's routing and controllers/views to handle the rest?
Depends on your application. In most of the cases yes.
I've done several big angular projects, I only have one route that actually serves the main html file, and one that serves static files (pictures, js, css). I also have a route that points to the templates directory which should be served as static contents. Those are the templates that AngularJS need to work with.
For the communication between your angular app and the server, you'll probably need other routes as well. You could create RESTful API end-points to create a communication layer for the client and the server.
I usually have these two lines in the server code to keep the all the templates in the same folder. It makes it easier to manage and define work flows:
app.use(express.static(path.join(__dirname, 'public')));
app.use('/templates', express.static(path.join(__dirname, 'templates')));
For communication between the server and the client:
app.post('/login', function (req, res) {
// deal with login information ...
res.send({
done: true,
errors: []
});
});
app.post('/search', function (req, res) {
// do the search ...
res.send({
done: true,
results: []
});
});
Remember if you use * at some point in your app, the other routes that you defined after that, will never catch the request.
And
I'm against Jade's syntax and have no desire to utilize it.
Yes, me too! But there are other options as well, I personally prefer ejs. If you are using express-generator you can just pass -e switch and it'll create everything compatible with ejs.
$ express -e
Also, take a look at here.

Categories