2

私はしばらくこれを研究してきました。この件に関するいくつかのリソースを見つけましたが、それらはすべて同じアプローチを使用する傾向があります-Page.Renderをオーバーライドし、HtmlTextWriterを使用して出力を文字列に変換し、一連のコンパイルされた正規表現を使用して余分な空白を削除します。ここに例があります

まあ、私はそれを試してみましたが、うまくいきます...しかし....

Safari 5.0 では、これにより、画像の読み込みや「サーバーがビジー状態です」というエラーが発生するなど、あらゆる種類のパフォーマンスの問題が発生するようです。IE 7、FireFox 3.6、および Google Chrome 6.0 は正常に動作しているようですが、サーバーのストレス テストはあまり行っていません。時折、ページの生成に時間がかかるように見えますが、html がブラウザーに送信されると、ページはすばやく表示されます。

とにかく、考えてみると、.NET にこれらすべてのタブと改行を作成させて、文字列解析 (それらを取り除く最も効率の悪い方法) を使用してそれらをすべて再度削除させるのは、かなりばかげているように思えます。HtmlTextWriter をオーバーライドし、それをメイン ページ リクエストのツリーに渡して、出力にまったく含めないようにする方が理にかなっています。論理的には、その場合、ヒットではなくパフォーマンスが向上するはずです。

この方法を使用して空白の 50% しか削除できない場合でも、正規表現が行う作業ははるかに少なくなります。つまり、正規表現のみを使用する場合よりもパフォーマンスが向上するはずです。

コントロールアダプターを使用して、いくつかのメンバーをオーバーライドしてみました

  1. WriteLine() へのすべての呼び出しを対応する Write() メソッドに転送する
  2. NewLine プロパティを空の文字列に設定する
  3. OutputTabs() メソッドをオーバーライドし、単純にコードを削除する
  4. Indent プロパティをオーバーライドして 0 を返す

また、RenderChildren、Render、BeginRender、および EndRender をオーバーライドして、カスタム HtmlTextWriter を渡そうとしましたが、単純なラベル コントロールでさえタグの前のタブを削除できないようです。また、Reflector を使用してフレームワークを掘り下げましたが、これらの文字がどのように生成されているかを理解できません。「キャッチオール」アプローチを使用していると思っていましたが、何かが欠けているようです。

とにかく、ここに私が思いついたものがあります。このコードは、私が望むように機能していません。もちろん、ページ上のさまざまな Render メソッドを直接オーバーライドして、カスタム HtmlTextWriter のインスタンスを渡すことも試みましたが、それもうまくいきませんでした。

Public Class PageCompressorControlAdapter
    Inherits System.Web.UI.Adapters.ControlAdapter

    Protected Overrides Sub RenderChildren(ByVal writer As System.Web.UI.HtmlTextWriter)
        MyBase.RenderChildren(New CompressedHtmlTextWriter(writer))
    End Sub

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
        MyBase.Render(New CompressedHtmlTextWriter(writer))
    End Sub

    Protected Overrides Sub BeginRender(ByVal writer As System.Web.UI.HtmlTextWriter)
        MyBase.BeginRender(New CompressedHtmlTextWriter(writer))
    End Sub

    Protected Overrides Sub EndRender(ByVal writer As System.Web.UI.HtmlTextWriter)
        MyBase.EndRender(New CompressedHtmlTextWriter(writer))
    End Sub

End Class

Public Class CompressedHtmlTextWriter
    Inherits HtmlTextWriter

    Sub New(ByVal writer As HtmlTextWriter)
        MyBase.New(writer, "")
        Me.InnerWriter = writer.InnerWriter

        Me.NewLine = ""
    End Sub

    Sub New(ByVal writer As System.IO.TextWriter)
        MyBase.New(writer, "")
        MyBase.InnerWriter = writer

        Me.NewLine = ""
    End Sub

    Protected Overrides Sub OutputTabs()
        'Skip over the tabs
    End Sub

    Public Overrides Property NewLine() As String
        Get
            Return ""
        End Get
        Set(ByVal value As String)
            MyBase.NewLine = value
        End Set
    End Property


    Public Overrides Sub WriteLine()

    End Sub

    Public Overrides Sub WriteLine(ByVal value As Boolean)
        MyBase.Write(value)
    End Sub

    Public Overrides Sub WriteLine(ByVal value As Char)
        MyBase.Write(value)
    End Sub

    Public Overrides Sub WriteLine(ByVal buffer() As Char)
        MyBase.Write(buffer)
    End Sub

    Public Overrides Sub WriteLine(ByVal buffer() As Char, ByVal index As Integer, ByVal count As Integer)
        MyBase.Write(buffer, index, count)
    End Sub

    Public Overrides Sub WriteLine(ByVal value As Decimal)
        MyBase.Write(value)
    End Sub

    Public Overrides Sub WriteLine(ByVal value As Double)
        MyBase.Write(value)
    End Sub

    Public Overrides Sub WriteLine(ByVal value As Integer)
        MyBase.Write(value)
    End Sub

    Public Overrides Sub WriteLine(ByVal value As Long)
        MyBase.Write(value)
    End Sub

    Public Overrides Sub WriteLine(ByVal value As Object)
        MyBase.Write(value)
    End Sub

    Public Overrides Sub WriteLine(ByVal value As Single)
        MyBase.Write(value)
    End Sub

    Public Overrides Sub WriteLine(ByVal s As String)
        MyBase.Write(s)
    End Sub

    Public Overrides Sub WriteLine(ByVal format As String, ByVal arg0 As Object)
        MyBase.Write(format, arg0)
    End Sub

    Public Overrides Sub WriteLine(ByVal format As String, ByVal arg0 As Object, ByVal arg1 As Object)
        MyBase.Write(format, arg0, arg1)
    End Sub

    Public Overrides Sub WriteLine(ByVal format As String, ByVal arg0 As Object, ByVal arg1 As Object, ByVal arg2 As Object)
        MyBase.Write(format, arg0, arg1, arg2)
    End Sub

    Public Overrides Sub WriteLine(ByVal format As String, ByVal ParamArray arg() As Object)
        MyBase.Write(format, arg)
    End Sub

    Public Overrides Sub WriteLine(ByVal value As UInteger)
        MyBase.Write(value)
    End Sub

    Public Overrides Sub WriteLine(ByVal value As ULong)
        MyBase.Write(value)
    End Sub

End Class

コントロール アダプターに慣れていない場合は、以下の xml を ASP.NET App_Browsers フォルダーの .browser ファイルに配置してください。controlType を変更して、コントロール アダプターをラベルまたはその他のテスト範囲に適用することができます。これを機能させることができれば、プロジェクトのすべてのコントロールをここに追加する必要がある場合は、それほど大したことではありません。

<browsers>

    <browser refID="Default">
        <controlAdapters>
            <adapter controlType="System.Web.UI.Page"
                     adapterType="PageCompressorControlAdapter"/>
        </controlAdapters>
    </browser>

</browsers>

いずれにせよ、 VerboseHtml="false" や PreserveHtmlFormatting="false" などの単純な構成設定があるだけだと思う​​でしょう。MSN.com からの出力を見ると、これに似たある種の圧縮が使用されており、非常にパフォーマンスが高いように見えます。

4

1 に答える 1

1

解決策には、ここで見つけた圧縮モジュールの修正版を使用することが含まれていました。

http://omar-o.blogspot.com/2009/09/aspnet-white-space-cleaning-with-no.html

このソリューションは、カスタム PageParserFilter を実装します。これは、web.config ファイルで構成されます。このソリューションの優れた点は、コンパイル時に空白をフィルタリングするため、実行時にパフォーマンスが低下しないことです。

そして、Aristos と diamandiev のおかげで、圧縮をサポートするブラウザーの応答ストリームに圧縮を追加する合理的な方法を探しました。ここでこれに使用できる別のオープン ソース モジュールを見つけました: http://blowery.org/httpcompress/

2 つの方法を組み合わせると、どちらか一方を使用するよりもはるかに多くのパフォーマンスが大幅に向上しました。ページからタブを削除すると、ブラウザーのレンダリングが大幅に高速化されるようです。

静的コンテンツについては、この記事の方法を使用してそれらのファイルも圧縮する予定です (もちろん、画像を除いて、それらは既に圧縮されています): http://www.lostechies.com/blogs/dahlbyk/archive/2010 /01/08/script-to-enable-http-compression-gzip-deflate-in-iis-6.aspx

最終的解決

この Gistに最終的な解決策を追加しました。

于 2010-10-11T18:37:01.240 に答える