Do you want to save about 500kb traffic for every anonymous request to your MOSS 2007 Publishing Site?
There is no default way in MOSS 2007 where you can say: "I'm online visible for anonymous users, I don't want to load core.js, portal.js, init.js, ... every time a user is accessing a page". I was searching for this switch a long time, but it doesn't seems to exist.
Microsoft's proposal for this is to force a delayed loading of the core.js, which can be read here: http://support.microsoft.com/kb/933823/en-us or here: http://blogs.msdn.com/ecm/archive/2007/02/21/building-a-new-page-layout-which-does-not-reference-core-js-but-downloads-it-while-the-page-is-being-viewed-thereby-optimizing-response-time.aspx. This doesn't solve the problem, but is one way to speed up your pages.
A solution for this problem is a HTTP-Filter. This filter can be deployed in the /bin directory of your web application and has to be referenced in your web.config.
The solution below is not perfect, but it works and saves a lot of traffic, server load, time and money. And it enables you to publish lightweight pages with MOSS 2007.
Improvements for the code below would be a separation of the "tags to cleanup" in a configuration file and the usage of regular expressions. But with output cache enabled, this shouldn't be a performance issue.
Make sure to adapt this code for your own needs, as I'm removing e.g. ViewState and so on, which could possibly crash your MOSS applications.
MOSSCleanupModule.cs:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using Microsoft.SharePoint;
namespace HttpModules
{
public class MOSSCleanupModule : IHttpModule
{
public void Init(HttpApplication app)
{
app.ReleaseRequestState += new EventHandler(InstallResponseFilter);
}
private void InstallResponseFilter(object sender, EventArgs e)
{
HttpResponse response = HttpContext.Current.Response;
HttpRequest request = HttpContext.Current.Request;
if (response.ContentType == "text/html" && request.Url.AbsolutePath.EndsWith(".aspx") && !request.Url.AbsolutePath.Contains
("_layouts/"))
{
SPUser user = SPContext.Current.Web.CurrentUser;
if (user == null || string.IsNullOrEmpty(user.LoginName))
{
response.Filter = new MOSSCleanupFilter(response.Filter);
}
}
}
public void Dispose()
{
}
}
}
MOSSCleanupFilter.cs:
using
System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.IO;
namespace HttpModules
{
public class MOSSCleanupFilter : Stream
{
private static string[] completeTagsToCleanup = new string[]
{
"<meta name=\"GENERATOR\" content=\"Microsoft SharePoint\" />",
"<input type=\"hidden\" name=\"__SPSCEditMenu\" id=\"__SPSCEditMenu\" value=\"true\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOWebPartPage_PostbackSource\" id=\"MSOWebPartPage_PostbackSource\" value=\"\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOTlPn_SelectedWpId\" id=\"MSOTlPn_SelectedWpId\" value=\"\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOTlPn_View\" id=\"MSOTlPn_View\" value=\"0\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOTlPn_ShowSettings\" id=\"MSOTlPn_ShowSettings\" value=\"False\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOGallery_SelectedLibrary\" id=\"MSOGallery_SelectedLibrary\" value=\"\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOGallery_FilterString\" id=\"MSOGallery_FilterString\" value=\"\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOTlPn_Button\" id=\"MSOTlPn_Button\" value=\"none\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOAuthoringConsole_FormContext\" id=\"MSOAuthoringConsole_FormContext\" value=\"\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOAC_EditDuringWorkflow\" id=\"MSOAC_EditDuringWorkflow\" value=\"\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOSPWebPartManager_DisplayModeName\" id=\"MSOSPWebPartManager_DisplayModeName\" value=\"Browse\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOWebPartPage_Shared\" id=\"MSOWebPartPage_Shared\" value=\"\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOLayout_LayoutChanges\" id=\"MSOLayout_LayoutChanges\" value=\"\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOLayout_InDesignMode\" id=\"MSOLayout_InDesignMode\" value=\"\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOSPWebPartManager_OldDisplayModeName\" id=\"MSOSPWebPartManager_OldDisplayModeName\" value=\"Browse\" />"+System.Environment.NewLine,
"<input type=\"hidden\" name=\"MSOSPWebPartManager_StartWebPartEditingName\" id=\"MSOSPWebPartManager_StartWebPartEditingName\" value=\"false\" />"+System.Environment.NewLine,
"_spBodyOnLoadWrapper();",
};
private static string[] tagsToCleanup = new string[]
{
"<link rel=\"stylesheet\" type=\"text/css\" href=\"/_layouts/1033/styles/core.css?rev=",
"<link rel=\"stylesheet\" type=\"text/css\" href=\"/Style%20Library/en-US/Core%20Styles/Band.css",
"<link rel=\"stylesheet\" type=\"text/css\" href=\"/Style%20Library/en-US/Core%20Styles/Controls.css",
"<link rel=\"stylesheet\" type=\"text/css\" href=\"/_layouts/1033/styles/HtmlEditorCustomStyles.css?rev=",
"<link rel=\"stylesheet\" type=\"text/css\" href=\"/_layouts/1033/styles/HtmlEditorTableFormats.css?rev=",
"<input type=\"hidden\" name=\"__REQUESTDIGEST\" id=\"__REQUESTDIGEST\"",
"<input type=\"hidden\" name=\"__VIEWSTATE\" id=\"__VIEWSTATE\" value=",
};
private static string[] scriptsToCleanup = new string[]
{
"<script type=\"text/javascript\" language=\"javascript\" src=\"/_layouts/1033/core.js?rev=",
"<script src=\"/WebResource.axd?",
"<script> var MSOWebPartPageFormName = 'aspnetForm'",
"<script type=\"text/javascript\" language=\"javascript\" src=\"/_layouts/1033/init.js?rev=",
"<script type=\"text/javascript\" language=\"javascript\" src=\"/_layouts/1033/init.js?rev=",
"<script type=\"text/javascript\" language=\"javascript\" src=\"/_layouts/portal.js?rev=",
"<script type=\"text/javascript\" language=\"javascript\" src=\"/_layouts/1033/ie55up.js?rev=",
"<script type=\"text/javascript\" language=\"javascript\" src=\"/_layouts/1033/non_ie.js?rev=",
"<script type=\"text/javascript\">"+System.Environment.NewLine+"<!--"+System.Environment.NewLine+"var __wpmExportWarning",
"<script type=\"text/JavaScript\" language=\"JavaScript\">"+System.Environment.NewLine+"<!--"+System.Environment.NewLine+"var L_Menu_BaseUrl",
};
private Stream responseStream;
private long position;
public MOSSCleanupFilter(Stream inputStream)
{
this.responseStream = inputStream;
}
public override void Write(byte[] buffer, int offset, int count)
{
StringBuilder html = new StringBuilder(System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count));
foreach(string completeTagToClean in completeTagsToCleanup)
{
this.CleanUp(html, completeTagToClean);
}
foreach (string tagToClean in tagsToCleanup)
{
this.CleanUp(html, tagToClean, ">");
}
foreach (string scriptToClean in scriptsToCleanup)
{
this.CleanUp(html, scriptToClean, "</script>");
}
byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(html.ToString());
responseStream.Write(data, 0, data.Length);
}
private void CleanUp(StringBuilder html, string search, string endTag)
{
int startPos = html.ToString().IndexOf(search);
if (startPos != -1)
{
if (!string.IsNullOrEmpty(endTag))
{
int endPos = html.ToString().IndexOf(endTag, startPos);
if (endPos != -1)
{
html.Remove(startPos, endPos - startPos + endTag.Length);
}
}
else
{
html.Remove(startPos, search.Length);
}
}
}
private void CleanUp(StringBuilder html, string search)
{
this.CleanUp(html, search, null);
}
#region Filter overrides
public override bool CanRead
{
get
{
return true;
}
}
public override bool CanSeek
{
get
{
return true;
}
}
public override bool CanWrite
{
get
{
return true;
}
}
public override void Close()
{
responseStream.Close();
}
public override void Flush()
{
responseStream.Flush();
}
public override long Length
{
get
{
return 0;
}
}
public override long Position
{
get
{
return position;
}
set
{
position = value;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
return responseStream.Seek(offset, origin);
}
public override void SetLength(long length)
{
responseStream.SetLength(length);
}
public override int Read(byte[] buffer, int offset, int count)
{
return responseStream.Read(buffer, offset, count);
}
#endregion
}
}
web.config:
<
httpModules>
... <
add name="MOSSCleanupModule" type="HttpModules.MOSSCleanupModule, HttpModules, Version=1.0.0.1, Culture=neutral, PublicKeyToken=..."/>
...
</httpModules>