I'm making an ASP.NET Web page that generates pages from SQL when they're not cached. Their loading time could be between 300ms to 1.5seconds (No fix you database replies please).
I personally find these values to be too long, and was looking for a solution that allows me to inform the user that the page he is visiting will require a bit of time to load.
I was looking for a solution that could be via the Page_Load function, if that's possible. The perfect solution for me in this case is showing the user either an animated GIF or text saying the page is being generated.
On a side note I come from programming mostly Windows applications.
Here is an example of how to use the Response object to flush content to the browser and continue processing:
using System;
using System.Web.UI;
using System.Threading;
public partial class _Default : Page
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Response.Write("<h1>please wait...</h1>");
Response.Flush();
// simulate load time
Thread.Sleep(2000);
Response.Write("<h1>finished</h1>");
}
}
You can start rendering the page, and flush the buffer calling Response.Flush(). Which will send the contents of the buffer to the browser. You will then need to turn off the graphic once its loaded.
Another option would be to use AJAX to load the images, so you load the entire page, without the images, and then iniate another request to get the images. This might be easier then trying to render a partial page.
1.5 seconds isn't bad for a page to load you sure this is worth your time and effort?
You're going to want to first output the loading graphic and then flush the output buffer so the content so far is sent to the user's browser by using Response.Flush().
When you output the rest of the content, you will need to have a bit of javascript in there to remove the first page elements sent so the loading graphic goes away.
Related
I have made a custom report viewer control that utilized the output of an ssrs render request. I am having difficulty matching the speed of the ssrs ReportViewer control. The report is 2.5 mb.
I am watching the request and responses over the wire and can see it is taking roughly 2.8 seconds to get the buffer of the contents from ssrs. However, it is taking 10-15 seconds to show the content inside of an html element in my current view.
The problem is when I log into the ssrs manager directly and render the report it takes just as long to process the report however, it only takes, 3 seconds to render in the ssrs report viewer control.
The original design was to place the html as a payload on the ajax response. Then I thought that the json serialization/deserialization could be the bottleneck so I added the ability to save the output to a temp folder on the server as html and call load(html)...no improvement.
I am using the code below to load the content in my page from the Ajax.BeginForm success function :
function setReportContent(content, isUrl) {
if(isUrl)
$('#reportContent').load(content);
else
$("#reportContent").html(content);
showReportWaitIndicator(false);
$("#reportContent").show();
}
I cant figure out why there is such a huge discrepancy in rendering times between the ssrs report viewer control and the way I am loading.
Is there a more efficient technique to load large content other than .load(url); ?
Edit: I have downloaded the html file and opened it directly in the browser and the markup was rendered instantly. Why does appending the contents to the dom take up to 20 seconds?
Thanks
I found one solution but it uses an IFrame and I am iffy on that but it matches the speed of the ssrs report viewer. In a nutshell loading an IFrame does not contain some of the overhead of placing the contents in the dom. Made a small adjustment to the setip and it works.
function setReportContent(content, isUrl, renderInIFrame) {
if (isUrl) {
if (renderInIFrame)
$("#reportContent").html("<iframe id='reportFrame' scrolling='yes' onload='resizeReportFrame();' src='" + content + "'\></iframe>");
else
$("#reportContent").load(content);
}
else {
if (renderInIFrame) {
$("#reportContent").html("<iframe id='reportFrame' scrolling='yes' onload='resizeReportFrame();'\></iframe>");
$('#reportFrame').contents().find('html').html(content);
}
else
$("#reportContent").html(content);
}
showReportWaitIndicator(false);
$("#reportContent").show();
}
I have a form with a browser control. (this control uses IE9 because I set values on registry editor)
This web browser navigates to a specific URL and fills all fields on HTML page and submit them, then result page is displayed.
My problem is that i just want to know when this reslut page is fully loaded or completed so that i can fetch some information.
I use WebBroswer_DocumentCompleted event which works fine for the first page but not for the result page as it triggers before result
page is loaded.
I tried other solution which is to check the div tag inside the result page (this tag only appears when result page is loaded completely) and it works but not always.
My code:
private void WebBroswer_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
HtmlElementCollection elc3 = this.BotBrowser.Document.GetElementsByTagName("div");
foreach (HtmlElement el in elc3)
{
if (el.GetAttribute("id").Equals("Summary_Views")) //this determine i am at the result page
{
// fetch the result
}
}}
That div id is "Summary_Views".
I can provide you the link of that website on demand which is just for BLAST tools and database website for research purpose.
Frames and IFrames will cause this event to fire multiple times. Check out this answer:
HTML - How do I know when all frames are loaded?
Or this answer:
How to use WebBrowser control DocumentCompleted event in C#?
Or ms's kb article:
http://support.microsoft.com/kb/180366
Do you know if there are frames? If so then please say so, so people can help with that. If not then say so, so people can offer alternatives.
My guess is that the content is being generated by JavaScript. If it is then the document is complete before the JavaScript executes and you need to somehow wait until the JavaScript is done. The solution depends upon the web page. So you might need to process multiple document completes for diagnostic purposes and attempt to determine if there is a way to know which one you need.
At last i have solved my problem. I put a timer control from toolbox and set its time interval to 200ms and its Autoreset property to false. I set a tick event which has a code to check every 200ms whether this Div has been loaded or not, after that, Autoreset property is set to true.This solution is working perfectly :)
Problem
I have some pages that need dynamic data from website to generate output to users.
A simple solution is an aspx(php, ...) page to generate data and create another html page serving as GUI retrieving data from first page and showing it to users. in this method I can call my GUI page for example form1.aspx and my data page form1.json.aspx.
although I personally like this method, it is not suitable when creating components for it.
Another method that currently I'm using is using same GUI page call itself with a querystring to retrieve data. this page should check for that query string and if it exists, only generate data and remove everything else from page. As an example for this method if I call my page form1.aspx, to retrieve data, I need to call it like form1.aspx?JSON
Here is an example of what I'm doing:
protected void Page_Load(object sender, EventArgs e) {
if (Request.QueryString.ToString().IndexOf("JSON") == 0){
this.Controls.Clear();
Response.Clear();
// send pure data to client
} else {
// render page as GUI
}
}
However this method becomes too messy if I add master page and/or inherit my page from some template page. Master pages can only removed in Page_PreInit and that adds another extra method.
Security controls cause another problem, if user leaves page open for long time until session expires any attempt to retrieve data will fail cause security module will redirect the request to login page.
Next problem is I cannot consolidate my component in package because it needs modification in page (removing master page, clearing page components ...).
What I'm looking for:
1- I'm looking for a solution that I can call my page and get pure data (JSON or XML format) and doing so run a server side method that generates data, so I don't have to worry about what another designer puts in their master page or template.
2- I think it is possible to use axd extension to do this but I don't have a clue about it and couldn't find a helping document either.
3- Is there any better way of doing this. any suggestion or solution to improve this much appreciated.
Page methods. Check this article: http://weblogs.asp.net/craigshoemaker/archive/2008/09/29/using-jquery-to-call-asp-net-ajax-page-methods.aspx or http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/
WCF JSON service: http://www.codeproject.com/Articles/327420/WCF-REST-Service-with-JSON
Other ways of doing is using an HTTP Handler. Implement IHttpHandler interface and register your implementation in your Web.config file. Later call it using jQuery ($.get / $.post):
http://msdn.microsoft.com/en-us/library/46c5ddfy.aspx
EDIT
As OP pointed out, in order to access session state in a page method you should use WebMethodAttribute this way:
[WebMethod(EnableSession = true)]
I think you can use webservice instead of aspx page to return a JSON or XML string and then the caller page (any aspx page) will response after process is success.
So with this webservice, any third party page will have access to your server side method.
To create a webservice pls Check this link: Create and use Asp.net web service basic
Regards
I have an asp.net page, with couple of Divs, some of these div's get the image path from database and show the image in a smaller version (thumbnail). and as soon as user click on thumbnail, I use ajax Modal popup to show the full size image, what I need to have is to have a progree image(gif), on every thumbnail image while loading the asp.net page for the first time, I konw that it is possible to use UpadePanel, but I need the actual working code,or any other way to achieve this,
Thanks in advance
Well, if you are posting back, udpate panel can work; but you can programmably in JS do this yourself, or also consider using a JS plugin like lightbox: http://www.huddletogether.com/projects/lightbox2/
Which has that feature and looks very cool.
I am using a generateimage.aspx page which is used as an image source for an image.
When this page is called i am passing a querystring and then using a Session["abc"] var whoes value is being retruned as a jpg image.
The GenerateImage page is called from another page test.aspx like GenerateImage.aspx?text=P as image source under the img tag .And the value returned is then dislayed i the form of image.
PROBLEM: some time this page is called and some time not.
Thus when the page is not called then the image value that is being returned is that which is assigned to the Session["abc"] var in previous Session.
Please let me know what might be the reason that the page is called sometime and sometime not
And how can I handle this problem.
I think this is a caching issue. By appending a timestamp or a random number to the end of the request url as a querystring will solve this.
Something like
GenerateImage.aspx?text=P&dynstr=" + (new Date()).getTime();
You can disable caching this way:
Response.Cache.SetExpires(DateTime.Now.AddDays(-1));
I agree with #pulse, HTML images are commonly cached by most browsers. So you have two options: 1. Append a random string to the source (not my favorite as it's just a hack) 2. Set the page to force no cache by setting a response header (much better IMO).
Another thing is that I would switch to a handler (ashx page) instead of a standard aspx page for image handling as it has a much lighter footprint/lifecycle and can be easily reused.