I've inherited a site that uses knockout js and asp.net. The site runs decent after everything has been loaded but the initial load leaves a lot to be desired. Digging through the code there are around 20 models, each one calls an ajax method to get data from the server on page load. There is quite a bit of data being queried from the db which is causing the performance issue as the server sends the js, then the client sends and receives a large amount of data over 20 methods.
I want to handle all of the queries on server side before I send it to the client side, and then load the js models from that data. I am thinking about posting this data in a hidden div on the page as JSON and loading the models from there instead of an ajax call.
My question is, is this best practice? Is there a better way to optimize this scenario?
If you inline the data from the 20 queries in the page response, then the page response time can be significantly prolonged. It will results in the browser having to sit and wait from the previous page or on a boring blank page.
However if you keep the solution as-is then the user will get the page initially much faster, and the data will pop-in when it is ready.
Although the total load time is probably going to be better with the data inlined, the perceived performance from the users perspective is going to be worse. Here is a nice post on the subject: http://www.lukew.com/ff/entry.asp?1797
Another benefit is that you don't have a weakest-link problem in that the page response time will be that of the slowest query. That will be quite severe in query timeout conditions.
Be also aware of issues if one query fails, then you must still inline the successful queries, and also handle the failed query.
I would argue that it is much better to do the queries from the browser.
There are some techniques to consider if you want to have the 20 queries executed more efficiently. Consider using something like SignalR to send all queries in a single connection and having the results also stream back in a single connection. I've used this technique previously with great success, it also enabled me to stream back cached results (from server-side cache) before the up-to-date results from a slow backend service was returned.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am building a mobile app using jquery mobile, jquery and php back-end.
My problem is in certain pages I am sending and receiving multiple ajax requests which are visibly slowing down the performance and causes memory leaks which leads to the crashing of app in low network connections
What are the possible ways of optimizing the ajax requests?
note:- I am sending some ajax requests periodically(like once in a second)
Some ajax are sent based on events
First off, correctly written Ajax code does not leak memory. So, if you actually have a leak, that is likely caused by incorrectly written code, not by using Ajax.
Then, there are a number of optimizations you can consider.
Combine multiple requests to your server into one larger request. This saves roundtrips to the server, saves bandwidth, saves battery and increases performance.
Don't poll every second. Be smarter about how often you poll your server.
Lengthen the polling interval to vary it based on likely activity, switch to "long polling" or switch to a webSocket so you can do server push with no polling.
Analyze what is causing excessive memory consumption and fix bugs or redesign to curtail that. There is no reason that lots of Ajax calls should "leak" memory. It will chew up battery life, but need not leak memory if coded correctly.
Oh, and don't hesitate to pull up some high scale social web apps that already exist, open the debugger, switch to the network tab and study the heck out of what they are doing. You may as well learn from high scale apps that already have solved this issue.
Long Polling Is Better Than Polling
If you poll in a set interval it is probably better if you set a timeout on server-side and wait to return a message until a given number of loops. This makes especially sense for SPA.
However if you poll, you should increase the time intervall with every empty response you get.
Group Requests By Events, Not By Entity
Let's say you poll every 10 seconds, to retrieve new messages. Moreover you poll every 10 seconds to retrieve more notifications. Instead of doing two requests you should only do one ajax request and return one big json response, which you then use to modify DOM elements on the client side.
Use Server-Sent Events Or Sockets If Possible
Sockets or Server-Sent Events will result in much less requests and will only notify you if something actually happened on the server side. Here is a good comparison.
Here are few things you can do
Firstly
Get rid of all the memory leaks. Put your application in to a sandbox and give it the toughest time you can to record any memory leaks. Investigate them and correct your code.
Then
Reduce the number of requests. Carefully research on the best thresholds in your application and only trigger your requests at theses. Try to batch your requests and put them in to a single request whenever possible.
Use GET requests whenever possible. They are comparably simple and would act fast. This step is important for an application which triggers a lot of requests in its operation.
Choose the data format carefully. It could be plain text, JSON or
XML. Figure out the one that have the lowest impact on your
application and switch to that appropriately. Configure your server
to use data compression if possible.
Optimize the server. Use proper Expire or Cache-Control headers
for the content being servers. Use ETags if possible.
Try putting your content on a CDN. This may place the resources in a
geographically closer location to the user and make your application work faster.
Also, If you want to make a chat server or send fast messages to the server, you should use webSockets like socket.io .
There are mainly 3 steps for optimization (minimize) jQuery AJAX calls:
Either pass the done callback function as an argument when calling your function
return the jqXhr object from the function, and assign the done callback
Alternatively switch to using jQuery.ajax() instead, and pass the entire options object
Please refer this link : How to optimize (minimize) jQuery AJAX calls
You can use the cache feature of the Ajax call for this that helps you to get all data in first during the request and stored in cache and from next time no Ajax request happened and data manipulation done using cached data only.
Also, you can only optimize Ajax call request and response time by reducing the amount of data requested and sent while Ajax call. This can be done only by removing unwanted data during Ajax call.
Other than that, all optimization depends on code and database logic. To increase performance and reduce app crashing, optimized code and database logic helps you.
Create variable with ajax callback and use it
Each second you create new xhr request instance, that will be in
memory until done callback executes.Better way is to create new ajax
request on previous ajax complete, that means you will have only one
xhr request instance at time.
After data send to server, clean your object data, for example:
array.length = 0;
object = null;
image.src = "";
file = null;
As #jfriend00 said, Ajax requests don't generate memory leaks issues...
this is what your code probably do!
The best way to do what you need is to open a Socket Layer with your Data Layer Service, so, instead of a polling, you can be notified when a domain-model change occurs.
Checkout at Socket.io...
If you don't want to implement a Socket Layer, I think there aren't many way to increase performances...
One thing that, in addition - of course - to the code improvement operations (refactoring, ecc.), in my opinion, you can do is to implement a "Tail Management System"...
Study how Promises work (es6, jQuery, Q, bluebird)
Create A QueueService, a simple Javascript Class that knows how to serialize all (Ajax) tasks (promises);
Interpose the QueueService between Controllers and Data Layer Access Services
Implement a simple lightweight CacheSystem that prevents unnecessary AjaxRequests!
For my Web apps I'm always wondering, which way is the best to design a proper Web applications with data persistance. For now I design every time a single HTML page, and all the content and the data upload is managed with jQuery AJAX requests based on a RESTful model, to a remote server which takes care of the database. But at the end that make sometimes a lot of AJAX calls, and getting huge amount of data takes sometimes a few seconds, which is not user-friendly.
Is there something like a guideline, or a standard way of developing to design web App ?
I've already looked over the WebWorkers and WebSockets Javascript API, but never used them yet. Does anybody already try it ? Does that allows better performance than AJAX exchanges ?
What is your way of Web App developing ?
This isn't really the place for questions like this, but I will give you a few brief pointers.
AJAX requests shouldn't take long, if they are consistently being slow then the problem is most likely your server-side code and inefficiencies there. Websockets aren't going to give you any benefit over AJAX if your server is slow.
A common design is to load the minimal dataset required for the page to function, AJAXing any other required data to get the page responsive as quickly as possible.
Caching and pre-fetching are great ways to speed up your site, for instance: if you are running a mysql query over and over, run it once and put the results in a caching service like memcached or mongodb with an expiration of an hour (or something) and serve the cached response, this will speed up your server response times. Pre-fetching is anticipating what your user is going to do next and loading that data in the background without any user interaction.
Consider using localStorage or IndexedDB if your users are loading the same data repeatedly
How does scalability match up in these two architectures? (For a web app)
I.E I can see that for MVVM javascript, we have;
Advantages:
-A share of the logical processing required, is executed on the client's browser. So for n requests,
the client browser's take this load from the server n times. (E.G iterating through collections to output HTML)
Disadvantages:
-More requests per user. I.E For the initial dynamic HTML, in Traditional, we have 1 request per user, but in MVVM we may have up to 5 for initial HTML. I.E,
Request 1, use get's initial HTML
Request 2-5, Knockout clients, requests's JSON data, so it can setup lists, and dynamic HTML etc.
No doubt these JSON requests, can be Asyncronous actions, but even so, how badly will this effect load?
When you build a SPA-style app, the advantage is that once the initial page is loaded, the next requests will be smaller requests than usual. After all, you will only be requesting data as opposed to HTML + data.
In terms of the effects on server load, it'll depend on your app. If the bottleneck is in data processing (fetching from db, domain logic, ...) either approach will have more or less the same load, since you have to process the data anyway.
If on the other hand the bottleneck is in the rendering, the client-side approach will be more beneficial since the rendering will be done on the client.
Quick question:
I have a page that makes an AJAX call to my SQL server and receives an XML response. I parse the XML and display the relevant data in a table.
I have a button on the page that is used to display the table data in a simple line graph on a new page. Currently, I just re-query the database and to re-get the data and create a new array object of that data for my graph.
The GET can take up to 2.5 seconds, with the final graph time to render being about 8-9 seconds. I am investigating any alternatives to re-GET'ting the data.
So far I have:
localStorage (HTML5)
php pass me the data instead of querying the DB
jquery plugin (DOMCache)
Any thoughts on this or best practices??
thanks for any input!
You might do best to just make sure the response is cached in your users' browsers. There are a variety of ways to make this happen (variant upon the framework your server is running, browsers that your clients are using, etc etc), but the long story short is that relying upon caching will alleviate you from having to jump through performance hoops by making modifications to your codebase.
IE8+ is actually a kingpin in this area (much as I hate to admit it). Its aggressive caching of ajax responses is usually a serious pain in the arse, but in this case would prove valuable to your scenario.
Edit -
You mentioned SQL Server, so I'm making the assumption that you're running through an ASP.NET middle tier. If that's the case, here's an interesting article on caching ajax requests on the server and the client with the .NET framework.
What is it best to handle pagination? Server side or doing it dynamically using javascript?
I'm working on a project which is heavy on the ajax and pulling in data dynamically, so I've been working on a javascript pagination system that uses the dom - but I'm starting to think it would be better to handle it all server side.
What are everyone's thoughts?
The right answer depends on your priorities and the size of the data set to be paginated.
Server side pagination is best for:
Large data set
Faster initial page load
Accessibility for those not running javascript
Client side pagination is best for:
Small data set
Faster subsequent page loads
So if you're paginating for primarily cosmetic reasons, it makes more sense to handle it client side. And if you're paginating to reduce initial load time, server side is the obvious choice.
Of course, client side's advantage on subsequent page load times diminishes if you utilize Ajax to load subsequent pages.
Doing it on client side will make your user download all the data at first which might not be needed, and will remove the primary benefit of pagination.
The best way to do so for such kind of AJAX apps is to make AJAX call the server for next page and add update the current page using client side script.
If you have large pages and a large number of pages you are better of requesting pages in chunks from the server via AJAX. So let the server do the pagination, based of your request URL.
You can also pre-fetch the next few pages the user will likely view to make the interface seem more responsive.
If there are only few pages, grabbing it all up-front and paginating on the client may be a better choice.
Even with small data sizes the best choice would be server side pagination. You will not have to worry later if your web application scales further.
And for larger data sizes the answer is obvious.
Server side - send to the client just enough content for the current view.
In a practical world of limits, I would page on the server side to conserve all the resources associated with sending the data. Also, the server needs to protect itself from a malicious/malfunctioning client asking for a HUGE page.
Once that code is happily chugging along, I would add "smarts" to the client to get the "next" and "previous" page and hold that in memory. When the user pages to the next page, update your cache.
If the client software does this sort of page caching, do consider how fast your data ages (is likely to change) and if you should check that your cached page of data is still valid. Maybe re-request it if it ages more than 2 minutes. Maybe have a "dirty" flag in it. Something like that. Hope you find this helpful. :)
Do you mean that your JavaScript has all the data in memory, and shows one page a time? Or that it downloads each page from the server as it's needed, using AJAX?
If it's the latter, you also may need to think about sorting. If you sort using JavaScript, you'll only be able to sort one page at a time, which doesn't make much sense. So your sorting should be done on the server.
I prefer server side pagination. However, when implementing it, you need to make sure that you're optimizing your SQL properly. For instance, I believe in MySQL, if you use the LIMIT option it doesn't use the index so you need to rewrite your sql to use the index properly.
G-Man
One other thing to point out here is that very rarely will you be limited to simply paging through a raw dataset.
You might have to search for certain terms in one or more columns you are displaying, and then say sort on a few columns and then give the users the ability to page through this filtered dataset.
In a situation like this you might have to see whether it would be better to have this logic search and/or sort client side or server side.
Another thing to consider is that Amazon's cloud search api gives you some very powerful searching abilities and obviously you'll want to allow cloud search to handle searching and sorting for you if you happen to have your data hosted there.