2011-12-04 7 views
0

.NETと関連するすべてのクールな機能がありますが、ユーザーコントロールとJSが持つ効率については疑問です。ユーザーコントロールを使用するときにJavaScriptを組み込むためのベスト/効率的な方法

私のユーザーコントロールは主にascx表示ページと.vb.ascxコードで構成されています。これはコードビハインドコーディングスタイルの.NETと同じように、コードシンプルには最適です必要なファイルの数。しかし、私が理解しているように、サーバーはこれらをコンパイルし、HTMLを効率的に返します。

コントロールがJavaScriptを必要とするところでは、私が開発しているように、ユーザーコントロールが「controlName.ascx、controlName.vb.ascx、controlName」で構成されるように、同じ名前の各ユーザーコントロールに対して外部JSファイルを作成しています。 js '

ユーザーが要求したページに複数のユーザーコントロールが含まれている場合、ブラウザは複数のJSファイルを要求しています。おそらくマスタページのJSファイル、jQuery、それぞれのコントロールに必要なファイルです。

このアプローチは、開発中でもすべてがすべて素敵できれいに保たれているので問題解決が容易になりますが、ライブが始まるとブラウザから多くの取得要求がありますファイル、キャッシュされているかどうかを確認するためにファイルを要求するプロセスさえ、時間がかかる必要があります。

ascxファイルでJSインラインを使用したり、スクリプトを直接挿入したり、ブラウザからのリクエストを減らすためにこれらの複数のファイルを処理するための正しい方法は何ですか?

私は同じ理由からボタンや素材にCSSスプライトを使用しています。そのため、JSファイルとは何かを考えています。私の場合、CSSは一般にプライマリページのクラスによって処理されるため、問題はありません。

+0

[ASP.netで複数のJavaScriptファイルを組み合わせるとキャッシュ]の可能な重複(http://stackoverflow.com/questions/47937/combining-and-caching-は、複数のjavascript-files-in-asp-net) –

+0

Hmm。しかし、申し訳ありませんが、それを見つけませんでした...その質問から参照されるコントロールは.NET 3用です。残念ながら、私は現在、私のホスティングによって.NET 2.0にバインドされています。 –

+0

[このスレッド](http://forums.asp.net/t/1525305.aspx/1)によると、 "ASP.Net 2.0 AJAX拡張機能"のセットをインストールする場合、 'ScriptManager'を使用することができます。 –

答えて

0

私たちは実際にscriptresource.axdを含む、ページ上のすべてのコントロールからすべてのjを自動的に抽出し、それらを単一のキャッシュファイルに保存するScriptManagerの上にコントロールを作成しました。これにより、自動化されているため、パフォーマンスが大幅に向上し、保守作業が軽減されます。私たちは.Net 2.0から始まりました。ScriptManagerが同じ機能を提供するかどうかは分かりませんが、言及する価値はあると思いました。ここで

は、私たちのこのクラスの実装です:上記のコードで

Option Explicit On 
Option Strict On 

Imports System.Collections.Generic 
Imports System.Web.SessionState 

Public Class OurScriptManager 
    Inherits ScriptManager 
    Implements IRequiresSessionState 

    Private m_ScriptBuilder As New StringBuilder 
    'Private m_sSessionIndex As String = "" 
    Private m_cScripts As List(Of ScriptReference) 
    Private m_fIsCached As Boolean 
    Private m_sScriptName As String = "" 
    Private m_sScriptFileName As String = "" 

    Const CACHED_SCRIPTS_DIR As String = "/scriptcache/" 

    Public Sub New() 
     ' default constructor 
    End Sub 

    Public Property ScriptName() As String 
     Get 
      Return m_sScriptName 
     End Get 
     Set(ByVal value As String) 
      m_sScriptName = value 
     End Set 
    End Property 

    Private ReadOnly Property ScriptFileName() As String 
     Get 
      If String.IsNullOrEmpty(m_sScriptFileName) Then 
       m_sScriptFileName = "~" & CACHED_SCRIPTS_DIR & Me.ScriptName & ".js" 
      End If 

      Return m_sScriptFileName 
     End Get 
    End Property 

    Protected Overrides Sub OnInit(ByVal e As System.EventArgs) 
     ' Exceptions are handled by the caller 

     MyBase.OnInit(e) 

     If String.IsNullOrEmpty(Me.ScriptName) Then 
      Me.ScriptName = Me.Page.ToString 
     End If 

     ' this compiled script should be cached on the server 
     ' check for the file, if it exists, load that file instead of generating it 
     If Configuration.HasPageScriptBeenCached(Me.ScriptFileName) AndAlso File.Exists(Me.Page.Server.MapPath(Me.ScriptFileName)) Then 
      m_fIsCached = True 
     Else 
      m_cScripts = New List(Of ScriptReference) 
     End If 
    End Sub 

    Protected Overrides Sub OnResolveScriptReference(ByVal e As System.Web.UI.ScriptReferenceEventArgs) 
     Try 
      MyBase.OnResolveScriptReference(e) 

      If Not m_fIsCached Then 
       ' First, check to make sure this script should be loaded 
       Dim fIsFound As Boolean 

       For Each oXref As ScriptReference In m_cScripts 
        If oXref.Assembly = e.Script.Assembly AndAlso oXref.Name = e.Script.Name AndAlso oXref.Path = e.Script.Path Then 
         fIsFound = True 
         Exit For 
        End If 
       Next 

       ' If this script is found within the list of scripts that this page uses, add the script to the scripthandler.aspx js output 
       If Not fIsFound Then 
        Dim oReference As ScriptReference 
        Dim oElement As ScriptReference 
        Dim fIsPathBased As Boolean 

        oElement = e.Script 

        If String.IsNullOrEmpty(oElement.Path) AndAlso Not String.IsNullOrEmpty(oElement.Name) AndAlso String.IsNullOrEmpty(oElement.Assembly) Then 
         ' If resource belongs to System.Web.Extensions.dll, it does not 
         ' provide assembly info that's why hard-coded assembly name is 
         ' written to get it in profiler 
         oElement.Assembly = "System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
        End If 

        'check to see what type of script this is 
        If Not String.IsNullOrEmpty(oElement.Path) Then 
         ' this script is a physical file 
         oReference = New ScriptReference(oElement.Path) 
         fIsPathBased = True 

        ElseIf Not String.IsNullOrEmpty(oElement.Assembly) AndAlso Not String.IsNullOrEmpty(oElement.Name) Then 
         ' this script is generated by an assembly 
         oReference = New ScriptReference(oElement.Name, oElement.Assembly) 

        Else 
         ' Couldn't find script, so bail to allow standard processing to take place. 
         Return 

        End If 

        If Not fIsPathBased Then 
         Dim sUrl As String 
         Dim oRequest As HttpRequest 
         Dim sScriptResourcePath As String 

         sUrl = GetUrl(oReference) 
         sScriptResourcePath = String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", Context.Request.Url.Scheme, "://", Context.Request.Url.Host, ":", Context.Request.Url.Port, "/", Context.Request.ApplicationPath, "/ScriptResource.axd") 

         oRequest = New HttpRequest("scriptresource.axd", sScriptResourcePath, sUrl.Substring(sUrl.IndexOf("?"c) + 1)) 

         Try 
          Using oWriter As New StringWriter(m_ScriptBuilder) 
           Dim oHandler As IHttpHandler = New System.Web.Handlers.ScriptResourceHandler 

           oHandler.ProcessRequest(New HttpContext(oRequest, New HttpResponse(oWriter))) 
          End Using 
         Catch theException As Exception 
          Call ReportError(theException) 
          ' Since we couldn't automatically process this, just bail so that standard processing takes over 
          Return 
         End Try 
        Else 
         ' If this script is from a file, open the file and load the 
         ' contents of the file into the compiled js variable 
         Dim sAbsolutePath As String 

         sAbsolutePath = Context.Server.MapPath(oElement.Path) 
         Try 
          If System.IO.File.Exists(sAbsolutePath) Then 
           Using oReader As New StreamReader(sAbsolutePath, True) 
            m_ScriptBuilder.Append(oReader.ReadToEnd()) 
           End Using 
          Else 
           Throw New Exception("File " & sAbsolutePath & " does not exist") 
          End If 
         Catch theException As Exception 
          Call ReportError(theException, New ExtraErrorInformation("File", sAbsolutePath)) 
          ' Since we couldn't automatically process this, just bail so that standard processing takes over 
          Return 
         End Try 
        End If 

        m_ScriptBuilder.AppendLine() 

        ' add this script to the script reference library 
        Dim oNewElement As New ScriptReference 

        oNewElement.Name = e.Script.Name.ToString() 
        oNewElement.Assembly = e.Script.Assembly.ToString() 
        oNewElement.Path = e.Script.Path.ToString() 

        m_cScripts.Add(oNewElement) 
       End If 
      End If 

      ' a script filename is provided for caching 
      e.Script.Assembly = String.Empty 
      e.Script.Name = String.Empty 
      e.Script.Path = Me.ScriptFileName 
     Catch theException As Exception 
      HttpContext.Current.Response.Write(ReportError(theException)) 
      HttpContext.Current.Response.End() 
     End Try 
    End Sub 

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter) 
     ' Exceptions are handled by the caller 

     MyBase.Render(writer) 

     If Not m_fIsCached Then 
      If Not String.IsNullOrEmpty(Me.ScriptName) Then 
       ' Save script to file for caching 
       Using fsFile As New FileStream(Me.Page.Server.MapPath(Me.ScriptFileName), FileMode.Create, FileAccess.Write, FileShare.Read) 
        Using oWriter As New StreamWriter(fsFile) 
         oWriter.Write(m_ScriptBuilder.ToString) 
         oWriter.Flush() 
         oWriter.Close() 
        End Using 
        fsFile.Close() 
       End Using 

       ' Record that the script file has been cached 
       Configuration.RecordPageScriptCached(Me.ScriptFileName) 
      End If 
      m_ScriptBuilder = Nothing 
     End If 
    End Sub 

    Private Function GetUrl(ByVal oReference As ScriptReference) As String 
     ' Exceptions are handled by the caller 

     If String.IsNullOrEmpty(oReference.Path) Then 
      Try 
       Dim oMethod As MethodInfo 

       oMethod = oReference.GetType.GetMethod("GetUrl", BindingFlags.NonPublic Or BindingFlags.Instance) 
       If oMethod IsNot Nothing Then 
        Return DirectCast(oMethod.Invoke(oReference, New Object() {Me, False}), String) 
       Else 
        Return String.Empty 
       End If 
      Catch ex As Exception 
       Return String.Empty 
      End Try 
     Else 
      Return Me.ResolveClientUrl(oReference.Path) 
     End If 
    End Function 

End Class 

、でReportErrorは、イベントログおよび/またはファイルに例外を記録します。これを独自のメカニズムで置き換えることができます。

ここでの設定コードです:

Private Shared m_cCachedPageScripts As Collections.Generic.List(Of String) 

''' <summary> 
''' This method is used to determine whether or not the script for the page has been cached. 
''' This is used for script combining. 
''' </summary> 
''' <param name="sKey"></param> 
''' <returns></returns> 
''' <remarks></remarks> 
Public Shared Function HasPageScriptBeenCached(ByVal sKey As String) As Boolean 
    ' Exceptions are handled by the caller 

    SyncLock CacheSyncObject 
     If m_cCachedPageScripts IsNot Nothing AndAlso m_cCachedPageScripts.Contains(sKey) Then 
      Return True 
     End If 
    End SyncLock 

End Function 
''' <summary> 
''' This method is used to record the fact that the page script has been cached. 
''' This is used for script combining. 
''' </summary> 
''' <param name="sKey"></param> 
''' <remarks></remarks> 
Public Shared Sub RecordPageScriptCached(ByVal sKey As String) 
    ' Exceptions are handled by the caller 

    SyncLock CacheSyncObject 
     If m_cCachedPageScripts Is Nothing Then 
      m_cCachedPageScripts.Add(sKey) 
     End If 
     m_cCachedPageScripts.Add(sKey) 
    End SyncLock 
End Sub 
+0

私はこの質問をしてから年を経ています...今すぐ戻ってきてください!あなたのコードは、もう一度、すばらしく見えます。私はそれの多くを理解していないが、それでも、それは素晴らしいよ!私は彼らが何であるか分からないので、 'not declared'エラーを出すいくつかの変数について問題を抱えています。それをどのようにソートするのか不明です。 'ReportError'、' ExtraErrorInformation'、 'CacheSyncObject'はこれらのエラーを示しています。実際に私はここに自分の方法を作ることを意図しているのだろうか?また、これはどのように実装されていますか、それは完全に自動化されていますか、またはControlファイルに必要な参照ですか? –

関連する問題