Omar AL Zabir blog on ASP.NET Ajax and .NET 3.5

Working hard to enrich millions of peoples' lives

Sponsors

News

I was
Co-Founder and CTO of Pageflakes, acquired by LiveUniverse - founded by MySpace founder.

I am
Chief Architect, SaaS Platform, British Telecom

I will be
Chief Architect, Mi...

Follow omaralzabir on Twitter

My Public Page
www.pageflakes.com/omar

View Omar AL Zabir's profile on LinkedIn

Read my blog on:

Omar AL Zabir

www.oazabir.com



Views:

Open source projects

Fast page loading by moving ASP.NET AJAX scripts after visible content

ASP.NET ScriptManager control has a property LoadScriptsBeforeUI, when set to false, should load all AJAX framework scripts after the content of the page. But it does not effectively push down all scripts after the content. Some framework scripts, extender scripts and other scripts registered by Ajax Control Toolkit still load before the page content loads. The following screen taken from www.dropthings.com shows several script tags are still added at the beginning of <form> which forces them to download first before the page content is loaded and displayed on the page. Script tags pause rendering on several browsers especially in IE until the scripts download and execute. As a result, it gives user a slow loading impression as user stares at a white screen for some time until the scripts before the content download and execute completely. If browser could render the html before it downloads any script, user would see the page content immediately after visiting the site and not see a white screen. This will give user an impression that the website is blazingly fast (just like Google homepage) because user will ideally see the page content, if it's not too large, immediately after hitting the URL.

image
Figure: Script blocks being delivered before the content

From the above screen shot you see there are some scripts from ASP.NET AJAX framework and some scripts from Ajax Control Toolkit that are added before the content of the page. Until these scripts download, browser don't see anything on the UI and thus you get a pause in rendering giving user a slow load feeling. Each script to external URL adds about 200ms avg network roundtrip delay outside USA while it tries to fetch the script. So, user basically stares at a white screen for at least 1.5 sec no matter how fast internet connection he/she has.

These scripts are rendered at the beginning of form tag because they are registered using Page.ClientScript.RegisterClientScriptBlock. Inside Page class of System.Web, there's a method BeginFormRender which renders the client script blocks immediately after the form tag.

   1: internal void BeginFormRender(HtmlTextWriter writer, string formUniqueID)
   2: {
   3:     ...
   4:         this.ClientScript.RenderHiddenFields(writer);
   5:         this.RenderViewStateFields(writer);
   6:         ...
   7:         if (this.ClientSupportsJavaScript)
   8:         {
   9:             ...
  10:             if (this._fRequirePostBackScript)
  11:             {
  12:                 this.RenderPostBackScript(writer, formUniqueID);
  13:             }
  14:             if (this._fRequireWebFormsScript)
  15:             {
  16:                 this.RenderWebFormsScript(writer);
  17:             }
  18:         }
  19:         this.ClientScript.RenderClientScriptBlocks(writer);
  20: }

Figure: Decompiled code from System.Web.Page class

Here you see several script blocks including scripts registered by calling ClientScript.RegisterClientScriptBlock are rendered right after form tag starts.

There's no easy work around to override the BeginFormRender method and defer rendering of these scripts. These rendering functions are buried inside System.Web and none of these are overridable. So, the only solution seems to be using a Response Filter to capture the html being written and suppress rendering the script blocks until it's the end of the body tag. When the </body> tag is about to be rendered, we can safely assume page content has been successfully delivered and now all suppressed script blocks can be rendered at once.

In ASP.NET 2.0, you to create Response Filter which is an implementation of a Stream. You can replace default Response.Filter with your own stream and then ASP.NET will use your filter to write the final rendered HTML. When Response.Write is called or Page's Render method fires, the response is written to the output stream via the filter. So, you can intercept every byte that's going to be sent to the client (browser) and modify it the way you like. Response Filters can be used in variety ways to optimize Page output like stripping off all white spaces or doing some formatting on the generated content, or manipulating the characters being sent to the browser and so on.

I have created a Response filter which captures all characters being sent to the browser. It it finds that script blocks are being rendered, instead of rendering it to the Response.OutputStream, it will extract the script blocks out of the buffer being written and render the rest of the content. It stores all script blocks, both internal and external, in a string buffer. When it detects </body> tag is about to be written to the response, it flushes all the captured script blocks from the string buffer.

   1: public class ScriptDeferFilter : Stream
   2: {
   3:     Stream responseStream;
   4:     long position;
   5:  
   6:     /// <summary>
   7:     /// When this is true, script blocks are suppressed and captured for 
   8:     /// later rendering
   9:     /// </summary>
  10:     bool captureScripts;
  11:  
  12:     /// <summary>
  13:     /// Holds all script blocks that are injected by the controls
  14:     /// The script blocks will be moved after the form tag renders
  15:     /// </summary>
  16:     StringBuilder scriptBlocks;
  17:     
  18:     Encoding encoding;
  19:  
  20:     public ScriptDeferFilter(Stream inputStream, HttpResponse response)
  21:     {
  22:         this.encoding = response.Output.Encoding;
  23:         this.responseStream = response.Filter;
  24:  
  25:         this.scriptBlocks = new StringBuilder(5000);
  26:         // When this is on, script blocks are captured and not written to output
  27:         this.captureScripts = true;
  28:     }

Here's the beginning of the Filter class. When it initializes, it takes the original Response Filter. Then it overrides the Write method of the Stream so that it can capture the buffers being written and do it's own processing.

   1: public override void Write(byte[] buffer, int offset, int count)
   2: {
   3:     // If we are not capturing script blocks anymore, just redirect to response stream
   4:     if (!this.captureScripts)
   5:     {
   6:         this.responseStream.Write(buffer, offset, count);
   7:         return;
   8:     }
   9:  
  10:     /* 
  11:      * Script and HTML can be in one of the following combinations in the specified buffer:          
  12:      * .....<script ....>.....</script>.....
  13:      * <script ....>.....</script>.....
  14:      * <script ....>.....</script>
  15:      * <script ....>.....</script> .....
  16:      * ....<script ....>..... 
  17:      * <script ....>..... 
  18:      * .....</script>.....
  19:      * .....</script>
  20:      * <script>.....
  21:      * .... </script>
  22:      * ......
  23:      * Here, "...." means html content between and outside script tags
  24:     */
  25:  
  26:     char[] content = this.encoding.GetChars(buffer, offset, count);
  27:  
  28:     int scriptTagStart = 0;
  29:     int lastScriptTagEnd = 0;
  30:     bool scriptTagStarted = false;
  31:  
  32:     for (int pos = 0; pos < content.Length; pos++)
  33:     {
  34:         // See if tag start
  35:         char c = content[pos];
  36:         if (c == '<')
  37:         {
  38:             int tagStart = pos;
  39:             // Check if it's a tag ending
  40:             if (content[pos+1] == '/')
  41:             {
  42:                 pos+=2; // go past the </ 
  43:  
  44:                 // See if script tag is ending
  45:                 if (isScriptTag(content, pos))
  46:                 {
  47:                     /// Script tag just ended. Get the whole script
  48:                     /// and store in buffer
  49:                     pos = pos + "script>".Length;
  50:                     scriptBlocks.Append(content, scriptTagStart, pos - scriptTagStart);
  51:                     scriptBlocks.Append(Environment.NewLine);
  52:                     lastScriptTagEnd = pos;
  53:  
  54:                     scriptTagStarted = false;
  55:                     continue;
  56:                 }
  57:                 else if (isBodyTag(content, pos))
  58:                 {
  59:                     /// body tag has just end. Time for rendering all the script
  60:                     /// blocks we have suppressed so far and stop capturing script blocks
  61:  
  62:                     if (this.scriptBlocks.Length > 0)
  63:                     {
  64:                         // Render all pending html output till now
  65:                         this.WriteOutput(content, lastScriptTagEnd, tagStart - lastScriptTagEnd);
  66:  
  67:                         // Render the script blocks
  68:                         byte[] scriptBytes = this.encoding.GetBytes(this.scriptBlocks.ToString());
  69:                         this.responseStream.Write(scriptBytes, 0, scriptBytes.Length);
  70:  
  71:                         // Stop capturing for script blocks
  72:                         this.captureScripts = false;
  73:  
  74:                         // Write from the body tag start to the end of the inut buffer and return
  75:                         // from the function. We are done.
  76:                         this.WriteOutput(content, tagStart, content.Length - tagStart);
  77:                         return;
  78:                     }
  79:                 }
  80:                 else
  81:                 {
  82:                     // some other tag's closing. safely skip one character as smallest
  83:                     // html tag is one character e.g. <b>. just an optimization to save one loop
  84:                     pos++;
  85:                 }
  86:             }
  87:             else
  88:             {
  89:                 if (isScriptTag(content, pos+1))
  90:                 {
  91:                     /// Script tag started. Record the position as we will 
  92:                     /// capture the whole script tag including its content
  93:                     /// and store in an internal buffer.
  94:                     scriptTagStart = pos;
  95:  
  96:                     // Write html content since last script tag closing upto this script tag 
  97:                     this.WriteOutput(content, lastScriptTagEnd, scriptTagStart - lastScriptTagEnd);
  98:  
  99:                     // Skip the tag start to save some loops
 100:                     pos += "<script".Length;
 101:  
 102:                     scriptTagStarted = true;
 103:                 }
 104:                 else
 105:                 {
 106:                     // some other tag started
 107:                     // safely skip 2 character because the smallest tag is one character e.g. <b>
 108:                     // just an optimization to eliminate one loop 
 109:                     pos++;
 110:                 }
 111:             }
 112:         }
 113:     }
 114:     
 115:     // If a script tag is partially sent to buffer, then the remaining content
 116:     // is part of the last script block
 117:     if (scriptTagStarted)
 118:     {
 119:         
 120:         this.scriptBlocks.Append(content, scriptTagStart, content.Length - scriptTagStart);
 121:     }
 122:     else
 123:     {
 124:         /// Render the characters since the last script tag ending
 125:         this.WriteOutput(content, lastScriptTagEnd, content.Length - lastScriptTagEnd);
 126:     }
 127: }

There are several situations to consider here. The Write method is called several times during the Page render process because the generated HTML can be quite big. So, it will contain partial HTML. So, it's possible the first Write call contains a start of a script block, but no ending script tag. The following Write call may or may not have the ending script block. So, we need to preserve state to make sure we don't overlook any script block. Each Write call can have several script block in the buffer as well. It can also have no script block and only page content.

The idea here is to go through each character and see if there's any starting script tag. If there is, remember the start position of the script tag. If script end tag is found within the buffer, then extract out the whole script block from the buffer and render the remaining html. If there's no ending tag found but a script tag did start within the buffer, then suppress output and capture the remaining content within the script buffer so that next call to Write method can grab the remaining script and extract it out from the output.

There are two other private functions that are basically helper functions and does not do anything interesting:

   1: private void WriteOutput(char[] content, int pos, int length)
   2: {
   3:     if (length == 0) return;
   4:  
   5:     byte[] buffer = this.encoding.GetBytes(content, pos, length);
   6:     this.responseStream.Write(buffer, 0, buffer.Length);
   7: }
   8:  
   9: private bool isScriptTag(char[] content, int pos)
  10: {
  11:     if (pos + 5 < content.Length)
  12:         return ((content[pos] == 's' || content[pos] == 'S')
  13:             && (content[pos + 1] == 'c' || content[pos + 1] == 'C')
  14:             && (content[pos + 2] == 'r' || content[pos + 2] == 'R')
  15:             && (content[pos + 3] == 'i' || content[pos + 3] == 'I')
  16:             && (content[pos + 4] == 'p' || content[pos + 4] == 'P')
  17:             && (content[pos + 5] == 't' || content[pos + 5] == 'T'));
  18:     else
  19:         return false;
  20:  
  21: }
  22:  
  23: private bool isBodyTag(char[] content, int pos)
  24: {
  25:     if (pos + 3 < content.Length)
  26:         return ((content[pos] == 'b' || content[pos] == 'B')
  27:             && (content[pos + 1] == 'o' || content[pos + 1] == 'O')
  28:             && (content[pos + 2] == 'd' || content[pos + 2] == 'D')
  29:             && (content[pos + 3] == 'y' || content[pos + 3] == 'Y'));
  30:     else
  31:         return false;
  32: }

The isScriptTag and isBodyTag functions may look weird. The reason for such weird code is pure performance. Instead of doing fancy checks like taking a part of the array out and doing string comparison, this is the fastest way of doing the check. Best thing about .NET IL is that it's optimized, if any of the condition in the && pairs fail, it won't even execute the rest. So, this is  as best as it can get to check for certain characters.

There are some corner cases that are not handled here. For example, what if the buffer contains a partial script tag declaration. For example, "....<scr" and that's it. The remaining characters did not finish in the buffer instead next buffer is sent with the remaining characters like "ipt src="..." >.....</scrip". In such case, the script tag won't be taken out. One way to handle this would be to make sure you always have enough characters left in the buffer to do a complete tag name check. If not found, store the half finished buffer somewhere and on next call to Write, combine it with the new buffer sent and do the processing.

In order to install the Filter, you need to hook it in in the Global.asax BeginRequest or some other event that's fired before the Response is generated.

   1: protected void Application_BeginRequest(object sender, EventArgs e)
   2: {
   3:     if (Request.HttpMethod == "GET")
   4:     {
   5:         if (Request.AppRelativeCurrentExecutionFilePath.EndsWith(".aspx"))
   6:         {
   7:             Response.Filter = new ScriptDeferFilter(Response);
   8:         }
   9:     }
  10: }

Here I am hooking the Filter only for GET calls to .aspx pages. You can hook it to POST calls as well. But asynchronous postbacks are regular POST and I do not want to do any change in the generated JSON or html fragment. Another way is to hook the filter only when ContentType is text/html.

When this filter is installed, www.dropthings.com defers all script loading after the <form> tag completes.

image
Figure: Script tags are moved after the <form> tag when the filter is used

You can grab the Filter class from the App_Code\ScriptDeferFilter.cs of the Dropthings project. Go to CodePlex site and download the latest code for the latest filter.

Comments

AJAX coding school » Blog Archive » AJAX Code [2008-04-06 17:01:20] said:

Pingback from  AJAX coding school  &raquo; Blog Archive   &raquo; AJAX Code [2008-04-06 17:01:20]

# April 6, 2008 1:11 PM

Joe Chung said:

Is this transformation safe?  How would it affect UpdatePanels, for example?

# April 6, 2008 3:57 PM

Fatih Senel said:

Thanks for your great tip

# April 6, 2008 4:19 PM

Kazi Manzur Rashid said:

I think you have incorrectly described the LoadScriptsBeforeUI property in "ASP.NET ScriptManager control has a property LoadScriptsBeforeUI, when set to true, should load all AJAX framework scripts after the content of the page. But it does not effectively push down all scripts after the content."

The correct behavior is when LoadScriptsBeforeUI is set to true (which is also true by default) the script blocks are rendered in place of the ScriptManager. Often the ScriptManager is placed right after the ASP.NET Form tag as it requires the server side form tag as its container which means the scripts are loaded prior the main ui is rendered.

On the other hand when you set LoadScriptsBeforeUI to false then the ASP.NET Ajax Framework scripts, the application service like Authentication/Profile, your custom web service proxy get render before the UI and all the custom scripts that you register manually or by the AJAX Control/Extender got rendered before the forms end tag which means after rendering the main ui.

So the ultimate result is no matter what the value of LoadScriptsBeforeUI is the ASP.NET AJAX Framework scripts and web services proxy scripts loads before the UI.

Hope this will help.

# April 6, 2008 5:09 PM

oazabir said:

Hi Kazimanzirrashid,

Sorry I made a typo, it should be "false" instead of "true".

Expectation from LoadScriptsBeforeUI is that, when it's set to false, it should not Load Scripts Before UI. If it still downloads the giant frameworks before the UI, it does not provide much value. The purpose of this filter is to make sure *all* scripts Load after the UI.

# April 6, 2008 8:34 PM

oazabir said:

Hi Joe,

It does not affect UpdatePanels. As I hook this only on GET, Async Postback is not affected and thus UpdatePanels work fine.

# April 6, 2008 8:39 PM

mehfuzh said:

Nice one and pretty informative.

# April 7, 2008 4:00 AM

Mark said:

This is excellent. I am seeing a huge increase in performance on my US hosted site (I am in AU). OK I know all the scripts still have to download but the perception is that it is a much faster site.

Thank you very much.

Mark

# April 7, 2008 4:54 AM

Dave said:

So now the user clicks on something and what? Nothing happens? Should you implement an error trap that says something like - Please wait.. The page may not be fully loaded?

# April 7, 2008 9:36 PM

oazabir said:

This can be handled three ways:

1) Capture the click and wait in a timer until the scripts necessary to execute the call is available.

2) Store the clicks in some kind of "Action" queue. When all framework scripts load, play back all actions from such queue

3) Do nothing. User will click again

Here's a script that I use to wait until something is available

function until( test, callback )

{

if( test() == true ) callback();

else

{

 window.setTimeout( function() { until( test, callback ) }, 100 );

}

}

On a hyperlink which has likely to be clicked before the scripts download, I use this:

<a href="until(function(){return typeof MyFramework != "undefined";}, function() { MyFramework.DoWork() })">Click me before script loads</a>

# April 8, 2008 7:24 AM

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# April 9, 2008 4:54 PM

Talkin ’bout Filter Helpers » Blog Archive » Fast Sunday links said:

Pingback from  Talkin &#8217;bout Filter Helpers  &raquo; Blog Archive   &raquo; Fast Sunday links

# April 10, 2008 2:38 PM

Muhammad Adnan Amanullah said:

wonderful article.

i just wanted to know if u can tell

how can we show page contents (partially) ... somehow flushing the response safely.

i have webpage which has 10 webUserControls i want as soon any webUserControl load/process it get render/show on page

# April 11, 2008 6:08 AM

Joseph said:

Great article. Highlights the facility and flexibility of asp.net. I would be interested to know if you have any statistics on the performance implications of pushing everything through your own filter vs. the asp.net built in filter?

# April 11, 2008 6:48 AM

Scott Guthrie's Blog in Russian said:

Вот здесь можно посмотреть предыдущий пост из серии списка постов. Также некоторые ссылки на мои популярные

# April 11, 2008 1:36 PM

Muhammad Adnan said:

I implemented your techniques code but sorry to say. all my javascript code mess up. started to get different javscript errors and some times javascript code started to show up directly on webpage :)

# April 11, 2008 1:51 PM

InfinitiesLoop said:

# April 11, 2008 2:09 PM

oazabir said:

Hi Adnan,

Can you give me some example of the JS errors?

# April 11, 2008 2:18 PM

Scott Guthrie's Blog in Dutch said:

11 april Links: ASP.NET, ASP.NET AJAX, ASP.NET MVC, VISUAL STUDIO, Silverlight ASP.NET Meer ASP.NET Beveiliging

# April 12, 2008 6:29 AM

gOODiDEA said:

.NETUpcomingChangesInRoutingASP.NETDynamicDataPreviewReleasedonMSDNCodeGalleryC#We...

# April 13, 2008 9:04 PM

gOODiDEA.NET said:

.NET Upcoming Changes In Routing ASP.NET Dynamic Data Preview Released on MSDN Code Gallery C# WebServer

# April 13, 2008 9:05 PM

Enlaces de Abril: ASP.NET, ASP.NET AJAX, ASP.NET MVC, Visual Studio, Silverlight « Thinking in .NET said:

Pingback from  Enlaces de Abril: ASP.NET, ASP.NET AJAX, ASP.NET MVC, Visual Studio, Silverlight &laquo; Thinking in .NET

# April 14, 2008 4:32 PM

Scott Guthrie's Blog in French said:

Voici l&#8217;article le plus r&#233;cent dans ma s&#233;rie Listes de liens .&#160; Visitez aussi ma

# April 15, 2008 3:41 PM

Javier Romero said:

Hi... i'm trying to implement this aproach in one of my projects...

This project has componentArt controls like the treeview.. the behavior is... when i'm loading a big tree.. the string that contains the tree declaration and items is cropped so the rest of items is treated like literal and shows in the page..

The question.... there are some limitation about the chars that allow this filter?... or perhaps need i to define another validation about "special chars"?

# April 16, 2008 2:39 PM

وبلاگ اسکات گوسری به زبان فارسی said:

ASP.NET: آموزش های امنیت بیشتر در ASP.NET : سه آموزش آخر و عالی اسکات میشل در مورد امنیت ASP.NET سه آموزش

# April 17, 2008 8:22 AM

وبلاگ اسکات گوسری به زبان فارسی said:

ASP.NET: آموزش های امنیت بیشتر در ASP.NET : سه آموزش آخر و عالی اسکات میشل در مورد امنیت ASP.NET سه آموزش

# April 17, 2008 8:27 AM

Robert said:

Great! 2 suggestions:

- It doesn't work with AdSense scripts: it moves the script at the bottom of the page, but the banner is displayed at the bottom of the page too! So I think all scripts containing "googlesyndication" should be ignored.

- If a buffer contains a partial script tag as you say the code doesn't work, leaving the script in the middle of the page. But if that ignored code requires the execution of the previous ones, it will crash. So, is there a way to solve it?

# April 19, 2008 10:06 AM

Chris Love's Official Blog - Professional ASP.NET said:

This is a really fun week for me at the MVP Summit. But I am gathering a lot of great URLs to reference.

# April 19, 2008 3:10 PM

Howto Optimize Rendering Speed of ASP.NET Ajax Websites | Peter Velichkov's Blog said:

Pingback from  Howto Optimize Rendering Speed of ASP.NET Ajax Websites | Peter Velichkov's Blog

# April 21, 2008 7:41 AM

Shan said:

This is very interesting. But I am not able to map it completely. Can u please provide me (as a link or email) a sample website which demos this.

Email: subscribe[dot]prashanth[at]gmail[dot]com

# April 25, 2008 9:08 AM

Frano Hartman said:

Great thing, much improvent on our site.Thus we have a several problems, some of pages were not rendered at all,or rendered badly. So I first try with

try { } catch block, off course, nothing happens, and when I look deeper I think that I found solution.

If a char[] content (content.Last()) ends with <, this

content[pos + 1] throws a Out of bounds array index exception.

So I simply do this:

if (content.Length <= pos + 1)

   {

    scriptTagStarted = false;

    continue;

   }

to advance to next 28 kb. For me it was on some pages

a a tag, I do not know what will happen if this is a real script tag, but now page are rendered correctly.

Best regards...

# May 2, 2008 4:51 AM

oazabir said:

I have posted an update of this Filter in the latest Dropthings project source code. Please get the latest source code from "Source Code" tab.

It handles the partial script tag problem and other corruption of script tag reported earlier.

# May 9, 2008 9:37 AM

frano said:

Thank you, as you can see on my web site the script works.

# May 9, 2008 10:23 AM

toolkit rendered said:

Pingback from  toolkit rendered

# May 11, 2008 12:10 AM

Muhammad Yousaf Sulahria said:

Adsense Fix ScriptDeferFilter:

// See if script tag is ending

if (isScriptTag(content, pos))

{

   /// Script tag just ended. Get the whole script

   /// and store in buffer

   pos = pos + "script>".Length;

   if (new string(content, scriptTagStart, pos - scriptTagStart).IndexOf("googlesyndication") < -1)

       scriptBlocks.Append(content, scriptTagStart, pos - scriptTagStart);

   else

       this.WriteOutput(content, scriptTagStart, pos - scriptTagStart);

   scriptBlocks.Append(Environment.NewLine);

   lastScriptTagEnd = pos;

   scriptTagStarted = false;

   pos--; // continue will increase pos by one again

   continue;

}

# May 23, 2008 4:36 PM

Muhammad Yousaf Sulahria said:

The above fix which i posted will not work

please use this one.

ScriptDeferFilter Fix for Adsense v2:

// See if script tag is ending

if (isScriptTag(content, pos))

{

  /// Script tag just ended. Get the whole script

  /// and store in buffer

  pos = pos + "script>".Length;

  string temp=new string(content, scriptTagStart, pos - scriptTagStart);

  if ((temp.IndexOf("google_ad_client")==-1) && (temp.IndexOf("googlesyndication") == -1))

  {

      scriptBlocks.Append(content, scriptTagStart, pos - scriptTagStart);

      scriptBlocks.Append(Environment.NewLine);

  }

  else

  {

      this.WriteOutput(content, scriptTagStart, pos - scriptTagStart);

  }

  lastScriptTagEnd = pos;

  scriptTagStarted = false;

  pos--; // continue will increase pos by one again

  continue;

}

# May 24, 2008 2:06 PM

Karthick said:

I am new to Ajax technologies. Can some one confirm, between the Ajax Send and recieve details from server, will I be able to navigate to some other page in my site?

# June 20, 2008 3:46 PM

Satish said:

I have multiple servers where application has been deployed.Is it possible that Scripts.ashx?.. can go to the different server's application in subsequent call or it will go to same server for xml data matching?

# September 19, 2008 8:47 AM

oazabir said:

Yes, it can go to any server. It's hard to predict which server it will hit. Depending on how your load balancer is configured, even for the same user, two subsequent call to Scripts.ashx might hit two diff servers.

I am curious to know, why would that be a problem?

# September 19, 2008 12:01 PM

Satish said:

My problem is if on different servers if xml are not same or more over could you please suggest how can we make xml file to match urls for ajax kind of resources.

As for url given below d and t value is changing-

/Search/ScriptResource.axd?d=y43Z32FZL610QdHKL1FOI0dRMAqDF8pSJlU4gv-59u97u8sLNNruLPU8JGj1aTS4PubJ_6BcQJuKeyEj8Id14uIJGTnDeOTpmzxtuTpTJGU1&amp;amp;t=633510410178281250

please help

# September 22, 2008 1:09 AM

Ramnadh said:

It is a good solution to push the javascript after body is loaded by using ScriptDeferFilter as a reponse filter. But I have a problem when i use my custom GZIP compression response filter at application level. I excluded the page which was using the ScriptDeferFilter algorithm from the GZIP response filter, but how do i achieve the GZIP compression and ScriptDeferFilter in the same response filter. It would be great if you publish the modified code of GZIP applying the current ScriptDeferFilter stream.

# September 28, 2008 2:58 AM

fearunlimited said:

Combining script is good, but the problem is caching stops working in this case. All the script will be unwanted downloaded everytime the page is requested. The script used in the ajaxcontroltookit are already Gzipped and caching is on. It is better to leave them in their state.

Anmol

<a href="http://www.tradersgang.com">Online Shopping - Say no to brokers and agents</a>

# October 13, 2008 4:46 AM

oazabir said:

Ramnadh,

How are you registering the GZip compression? IF you are using IIS 6.0's built in compression, it works without any problem.

# October 13, 2008 5:20 AM

sanakofkawa said:

album downloadable hip hop mp3 music

audio download  song

artist download mp3 music soundtrack

# December 13, 2008 4:50 AM

Veronica said:

I downloaded on the project, and I looked in App_Code, but I couldn't find the source code.  Is it still there?

# March 24, 2009 8:42 PM

retytetrh said:

# September 10, 2009 9:01 PM

Abhishek Singh said:

If some of the java script functions calling on

onload event of the page then will it cause the JS errors in that case or they will execute

# April 20, 2010 8:02 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)