I have been designing an ASP.Net 4.0 Web Forms application using SQL2008R2 for the database; This is an intranet application which is being used by 30 or so users concurrently; the users experience some performance issues, and I have noticed that postbacks
take a long time, to the point where users re-submit pages because they think that the application didn't register the original submission.
Being a somewhat novice programmer in ASP.Net, I am mostly sure that most of the delay is due to bad coding; one such example which I hope you can help me go through is a page which is used for the users to create an order; I am initially populating the
customer dropdown listbox with some 2000 customer names and below that, the user has two more dropdown listboxes, one for the category of products and then one for the product itself; so by selecting a category, a db call is made to fetch the products of that
category to the second dropdown list. An additional drodown list is filled by the employee names in selecting the employee to handle the order; So in loading the page, I have a number of db calls, some of them carrying a lot of data.
I noticed that in changing categories, a few seconds pass before the second dropdown is populated. I would appreciate any input as to whether this kind of programming is correct (oe whether there are techniques to use to enhance performance, like caching?).
Also I would appreciate if you could point out a few pointers in detecting bottlencks and performance hogs.
2000 items in a listbox is a lot. If your other drop downs have similar counts, this would definitely be an issue. Could you replace this with maybe a lookup or search instead?
I would definitely look at caching the DB results if that is an option for you. If you cache those you would see a huge performance increase, but of course the trade off is stale data in the cache. When using cache its a good idea to have solid business
rules in place for what is cached and how long, as well as setting people's expectations that the data may be stale for a certain time frame.
"Sometimes, it is more important to have the right problem than the best solution."
It's probably not a good idea to have drop downs with that much information. Besides the performance hit, it's not very user friendly. Look to present this data a different way like in a search box or even better an autocomplete.
Also you said users are resubmitting pages because they take a while. If you have steps that will take some time, make sure you present the user with a waiting icon and temporary disable any submit buttons. This will make sure they don't resubmit and are
aware that the process is expected to take a little time.
I am initially populating the customer dropdown listbox with some 2000 customer names
Been there! ...and it really slows down the rendering of the page because of all the items that have to be added to it. The solution? Use a jQuery AutoComplete ComboBox with a wired up .ashx custom handler that will make asyncronous calls in the background
to gather items while the user types. Super slick. Downside to it you might ask? A bit more complex (only initially when learning) that just binding to a dropdown. When I started using these the size of my page went down drastically where DDLs were getting
bloated. Check out the following for some great information on implementing this:
As well as the excellent suggestions you have received so far, if the content of the page and/or drop down is not changing or changing by parameter you could use partial page caching to improve performance.
thanks for all the input; I have gine through some documentation regarding performance optimization techniques, but admidetly I can only follow some of it and implemented Output Caching, Caching on some business objects and changed all var declarations in
type declarations (explicit); a couple of things I saw was to use the application object for caching; is this the same as the Web.Caching Cache object? Also, I have developed and am using some user web controls, having a web tab control each of the tabs with
a number of controls and each with datasources retrieving data from the database. Is there a way for me to consolidate all my queries (e.g. list of users to select a resposnibel person, list of other projects running so as to display on a web scheduler control,
list of comments for the project, list of audit events, etc) so as to receive them through a single SqlConnection? The way the application is currently allows each of these objects to call down to a DAL equivalent of each object which in turn uses a provider
model to call a using type Sql stored procedure and retrieve and process the reader returning back objects. I have taken this architecture from a textbook as I thought it was a separation of layers and thus good maintenability.
I saw was to use the application object for caching; is this the same as the Web.Caching Cache object?
Yes, although you should now prefer to use the cache class in the System.Runtime.Caching namespace instead as that will receive enhancements going forwards whereas the one in the System.Web.Caching may not. See
http://deanhume.com/Home/BlogPost/object-caching----net-4/37 for further details.
MCSD, MCPD, MCTS
Marked as answer by cloucas on Nov 25, 2011 04:30 PM
Going through my project page code for an entire day, I have discovered (no surpises) that I was calling the database more than 10 times on a page load, to retrieve all the users' profiles, pay rates, etc. I have moved all that in the Application object
on application start event of the Global.asax. I have also replaced a number of heavy 3rd party controls with AJAX toolkits controls for simple cases where the extra functionality was not required so as to make the page lighter.
Although I have not yet minimosed the number of SQL calls, I am already starting to see a performance improvement, motivating me to keep at it.
Going through the code a couple of questions came up, which I would like to post here for your expert consultation:
1. In reading the project object, that has as members List<ProjectResources>, List<ProjectEvents>, etc, so the Data Access Layer provider actually makes a number of Sql connections to retrieve a single object instance; can this be consolidated into a single
connection?
2. Going one step further, after I load the project object I keep it in session and bind page controls on the object for further manipulation; a user may add or remove a resource, or change the project's priority, etc; in such cases where for instance the
project's status is changed, I am calling a Project class's static method essentially calling an SQL update in the database, while at the same time updating the project's status in Session. Is this a good way of doing this or should I just change the object's
properties and then save all changes at the end? That will mean that the user will not be receiving prompt feedback until a number of changes are applied.
1. In reading the project object, that has as members List<ProjectResources>, List<ProjectEvents>, etc, so the Data Access Layer provider actually makes a number of Sql connections to retrieve a single object instance; can this be consolidated into a single
connection?
You can by making a 'chunky' call to the database in which more data is being brought back all at once. This has a trade off and requires bloating the stored procedures, TSQL, etc. but if it makes sense and is logical then you can go down that road. For
example 'GetAllProjectData' as opposed to all the individual calls to get data of the 'project' type nature.
cloucas
2. Going one step further, after I load the project object I keep it in session and bind page controls on the object for further manipulation; a user may add or remove a resource, or change the project's priority, etc; in such cases where for instance the
project's status is changed, I am calling a Project class's static method essentially calling an SQL update in the database, while at the same time updating the project's status in Session. Is this a good way of doing this or should I just change the object's
properties and then save all changes at the end? That will mean that the user will not be receiving prompt feedback until a number of changes are applied.
It depends on the type of app, but I usually do not persist the data to the database until the entire 'process' (however that is defined in your app) is complete. This however is not a hard and fast rule. If you were doing a shopping cart, you might want
to save the data as the user moves along so they don't loose their shopping cart, etc. if their browser closed or left the site. It just depends on how important it is for that data to be maintained in between user actions/postbacks and available back to the
user. Yes, calling the database to save the data is more resource intensive than only persisting in session, but if it is critical that the data is saved off for sure then you have your answer.
thanks again; turns out this made a tremendous difference; I now make 1 call to the database rather than 6. The other thing I did was to populate the users dropdown listbox in each page load by calling for each user a ProfileInfo method to get the user's
first name and last name; as you can understand this involved calling the database twice for each user (there are aboput 30 or so of them), just to populate the dropdown list;
How would you go about doing this? after doing some research I thought of going through this process once at application start and populating a datatable in the application session object; I spent a long time trying to make this work, as it was fine on my
development machine, but was not working on the customer's server running IIS7. It appears that IIS7 running the application in an application pool in Integrated Mode does not execute Application_Start (is that right?) and does not have access to the Application
object.....if anyone has any example on how to do this or insight as to what I should be doing, please let me know.
After numerous attempts to make this work, I ended up saving the users table in Session on Session_Start. Now this is fine I guess, but what happens when a new user is added? Does that mean that all users will need to logout and then log back in?
cloucas
Member
64 Points
65 Posts
Ways to improve the performance of an ASP.Net application
Nov 17, 2011 12:55 PM|LINK
I have been designing an ASP.Net 4.0 Web Forms application using SQL2008R2 for the database; This is an intranet application which is being used by 30 or so users concurrently; the users experience some performance issues, and I have noticed that postbacks take a long time, to the point where users re-submit pages because they think that the application didn't register the original submission.
Being a somewhat novice programmer in ASP.Net, I am mostly sure that most of the delay is due to bad coding; one such example which I hope you can help me go through is a page which is used for the users to create an order; I am initially populating the customer dropdown listbox with some 2000 customer names and below that, the user has two more dropdown listboxes, one for the category of products and then one for the product itself; so by selecting a category, a db call is made to fetch the products of that category to the second dropdown list. An additional drodown list is filled by the employee names in selecting the employee to handle the order; So in loading the page, I have a number of db calls, some of them carrying a lot of data.
I noticed that in changing categories, a few seconds pass before the second dropdown is populated. I would appreciate any input as to whether this kind of programming is correct (oe whether there are techniques to use to enhance performance, like caching?). Also I would appreciate if you could point out a few pointers in detecting bottlencks and performance hogs.
thanks
chris
tehremo
Star
10540 Points
1704 Posts
Re: Ways to improve the performance of an ASP.Net application
Nov 17, 2011 01:08 PM|LINK
2000 items in a listbox is a lot. If your other drop downs have similar counts, this would definitely be an issue. Could you replace this with maybe a lookup or search instead?
I would definitely look at caching the DB results if that is an option for you. If you cache those you would see a huge performance increase, but of course the trade off is stale data in the cache. When using cache its a good idea to have solid business rules in place for what is cached and how long, as well as setting people's expectations that the data may be stale for a certain time frame.
unseth
Member
596 Points
110 Posts
Re: Ways to improve the performance of an ASP.Net application
Nov 17, 2011 02:13 PM|LINK
It's probably not a good idea to have drop downs with that much information. Besides the performance hit, it's not very user friendly. Look to present this data a different way like in a search box or even better an autocomplete.
Also you said users are resubmitting pages because they take a while. If you have steps that will take some time, make sure you present the user with a waiting icon and temporary disable any submit buttons. This will make sure they don't resubmit and are aware that the process is expected to take a little time.
atconway
All-Star
16846 Points
2756 Posts
Re: Ways to improve the performance of an ASP.Net application
Nov 17, 2011 03:30 PM|LINK
Been there! ...and it really slows down the rendering of the page because of all the items that have to be added to it. The solution? Use a jQuery AutoComplete ComboBox with a wired up .ashx custom handler that will make asyncronous calls in the background to gather items while the user types. Super slick. Downside to it you might ask? A bit more complex (only initially when learning) that just binding to a dropdown. When I started using these the size of my page went down drastically where DDLs were getting bloated. Check out the following for some great information on implementing this:
jQuery AutoComplete:
http://weblogs.asp.net/karan/archive/2010/10/06/jquery-autocomplete.aspx
jQuery UI - Autocomplete Demos & Documentation:
http://jqueryui.com/demos/autocomplete/#default
Here is one as well on imporving overall ASP.NET Performance:
Improving ASP.NET Performance:
http://msdn.microsoft.com/en-us/library/ms998549.aspx
Hope this helps!
frez
Contributor
5418 Points
913 Posts
Re: Ways to improve the performance of an ASP.Net application
Nov 17, 2011 03:43 PM|LINK
As well as the excellent suggestions you have received so far, if the content of the page and/or drop down is not changing or changing by parameter you could use partial page caching to improve performance.
cloucas
Member
64 Points
65 Posts
Re: Ways to improve the performance of an ASP.Net application
Nov 24, 2011 08:07 PM|LINK
thanks for all the input; I have gine through some documentation regarding performance optimization techniques, but admidetly I can only follow some of it and implemented Output Caching, Caching on some business objects and changed all var declarations in type declarations (explicit); a couple of things I saw was to use the application object for caching; is this the same as the Web.Caching Cache object? Also, I have developed and am using some user web controls, having a web tab control each of the tabs with a number of controls and each with datasources retrieving data from the database. Is there a way for me to consolidate all my queries (e.g. list of users to select a resposnibel person, list of other projects running so as to display on a web scheduler control, list of comments for the project, list of audit events, etc) so as to receive them through a single SqlConnection? The way the application is currently allows each of these objects to call down to a DAL equivalent of each object which in turn uses a provider model to call a using type Sql stored procedure and retrieve and process the reader returning back objects. I have taken this architecture from a textbook as I thought it was a separation of layers and thus good maintenability.
Any ideas?
frez
Contributor
5418 Points
913 Posts
Re: Ways to improve the performance of an ASP.Net application
Nov 25, 2011 08:21 AM|LINK
Yes, although you should now prefer to use the cache class in the System.Runtime.Caching namespace instead as that will receive enhancements going forwards whereas the one in the System.Web.Caching may not. See http://deanhume.com/Home/BlogPost/object-caching----net-4/37 for further details.
cloucas
Member
64 Points
65 Posts
Re: Ways to improve the performance of an ASP.Net application
Nov 25, 2011 04:30 PM|LINK
OK thanks again
Going through my project page code for an entire day, I have discovered (no surpises) that I was calling the database more than 10 times on a page load, to retrieve all the users' profiles, pay rates, etc. I have moved all that in the Application object on application start event of the Global.asax. I have also replaced a number of heavy 3rd party controls with AJAX toolkits controls for simple cases where the extra functionality was not required so as to make the page lighter.
Although I have not yet minimosed the number of SQL calls, I am already starting to see a performance improvement, motivating me to keep at it.
Going through the code a couple of questions came up, which I would like to post here for your expert consultation:
1. In reading the project object, that has as members List<ProjectResources>, List<ProjectEvents>, etc, so the Data Access Layer provider actually makes a number of Sql connections to retrieve a single object instance; can this be consolidated into a single connection?
2. Going one step further, after I load the project object I keep it in session and bind page controls on the object for further manipulation; a user may add or remove a resource, or change the project's priority, etc; in such cases where for instance the project's status is changed, I am calling a Project class's static method essentially calling an SQL update in the database, while at the same time updating the project's status in Session. Is this a good way of doing this or should I just change the object's properties and then save all changes at the end? That will mean that the user will not be receiving prompt feedback until a number of changes are applied.
thanks
atconway
All-Star
16846 Points
2756 Posts
Re: Ways to improve the performance of an ASP.Net application
Nov 28, 2011 08:40 PM|LINK
You can by making a 'chunky' call to the database in which more data is being brought back all at once. This has a trade off and requires bloating the stored procedures, TSQL, etc. but if it makes sense and is logical then you can go down that road. For example 'GetAllProjectData' as opposed to all the individual calls to get data of the 'project' type nature.
It depends on the type of app, but I usually do not persist the data to the database until the entire 'process' (however that is defined in your app) is complete. This however is not a hard and fast rule. If you were doing a shopping cart, you might want to save the data as the user moves along so they don't loose their shopping cart, etc. if their browser closed or left the site. It just depends on how important it is for that data to be maintained in between user actions/postbacks and available back to the user. Yes, calling the database to save the data is more resource intensive than only persisting in session, but if it is critical that the data is saved off for sure then you have your answer.
cloucas
Member
64 Points
65 Posts
Re: Ways to improve the performance of an ASP.Net application
Nov 29, 2011 03:31 AM|LINK
thanks again; turns out this made a tremendous difference; I now make 1 call to the database rather than 6. The other thing I did was to populate the users dropdown listbox in each page load by calling for each user a ProfileInfo method to get the user's first name and last name; as you can understand this involved calling the database twice for each user (there are aboput 30 or so of them), just to populate the dropdown list;
How would you go about doing this? after doing some research I thought of going through this process once at application start and populating a datatable in the application session object; I spent a long time trying to make this work, as it was fine on my development machine, but was not working on the customer's server running IIS7. It appears that IIS7 running the application in an application pool in Integrated Mode does not execute Application_Start (is that right?) and does not have access to the Application object.....if anyone has any example on how to do this or insight as to what I should be doing, please let me know.
After numerous attempts to make this work, I ended up saving the users table in Session on Session_Start. Now this is fine I guess, but what happens when a new user is added? Does that mean that all users will need to logout and then log back in?
chris