Male veľké veci alebo ako jednoducho ušetriť pár KB v generovanom HTML

Je pravdou, že kvalita pripojenia domácností sa v ostatnej dobe výrazne zlepšila a tak dokážu úspešne fungovať aj stránky, ktoré na pozadí generujú kvantum zbytočného neefektívneho HTML a scriptov, stránky ktoré majú obrovský viewState, stránky ktoré majú inlineovo v rámci HTML štýly. Na druhej strane, ľudia začali používať mobily na prehliadanie stránok, kde je pripojenie GRPS, EDGE stále ešte štandardom, kde zariadenia majú veľmi obmedzené zdroje napriek tomu, že mobilné prehliadače(napr. ten symbianový) sa posunuli dopredu. Nabádať k vypnutiu a nepoužívaniu ViewState je asi zbytočné, toto už bolo pretriasané na mnohých fórach. Ukážme si jeden malý, na pohľad banálny trik ako ušetriť...

Každý server side control v ASP .NET ak nemá pridelené ID explicitne, pridelí mu ho ASP .NET engine genericky(už ste určite videli ctl00, ctl01 vo výslednom HTML alebo debuggery). Aby bola zabezpečená jedinečnosť IDčiek, framework vytvára IDčka tak, že child kontrol prilepí svoje IDčko na koniec IDčka containera v ktorom sa nachádza a jeho child control zase ku tomuto IDčku. Každé IDčko nájdeme na forme použíté viackrát. Ak ide o napr. textbox, ktorý sa generuje ako HTML input element, tak IDčko nájdeme v jeho atribúte name(zodpovedá UniqueID property server side reprezentácie controlu), v atribúte ID(zodpovedá ClientID property server side reprezentácie controlu), v najmä v neštastných inicializačných scriptoch validátrov. Zoberme si stránku s Master Page a jedným controlom s dvoma validátormi a nechajme si vygenerovať HTML. ID controlu resp html input bez úprav vyzerá takto:

<input name="ctl00$ContentPlaceHolder1$MyTxtBx" type="text" id="ctl00_ContentPlaceHolder1_MyTxtBx" />

Urobme pokus, jednoduchá master page, jednoduchá page:

Master page:

<%@ Master 
    Language="C#"
    EnableViewState="false"
    AutoEventWireup="true"    
    CodeBehind="TestMaster.master.cs"
    Inherits="TestID.TestMaster" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"/>
    </div>
    </form>
</body>
</html>

Page:

<%@ Page 
    Language="C#" 
    MasterPageFile="~/TestMaster.Master"
    AutoEventWireup="false"
    EnableViewState="false"
    CodeBehind="TestForm.aspx.cs"
    Inherits="TestID.TestForm"
    Title="Test form" %>
    
<asp:Content ID="CM" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
Test:
<asp:TextBox ID="MyTxtBx" runat="server"/>
<asp:RequiredFieldValidator 
    ID="RVMyTxtBx"
    runat="server" 
    ControlToValidate="MyTxtBx"
    Text="Očakáva sa hodnota"
    />
<asp:RangeValidator
    runat="server"     
    ControlToValidate="MyTxtBx"
    Text="Očakáva sa číslo v rozsahu 10 až 100"
    MaximumValue="100"
    MinimumValue="10"
    ID="RNVMyTxtBx"
    SetFocusOnError="true"
    Type="Integer"
    />
</asp:Content>

Výsledok ma 2980 byteov, vídime inicializačné scripty validátorov, všade sa opakujúce Ctl00 na začiatku(to je ID master page) a ID contentPlaceholdera ContentPlaceHolder1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
    Test form
</title></head>
<body>
    <form name="aspnetForm" method="post" action="TestForm.aspx" onsubmit="BLOCKED SCRIPTreturn WebForm_OnSubmit();" id="aspnetForm">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTk4MjY1NjY2NGRkCKQG+6K3m9gtobmrXoJrUZT8gNw=" />
</div>


<script src="/WebResource.axd?d=e633EYn8AdtDVxUjMLr_1tcFZRgO8QzFRHdrJH7e-Hs1&amp;t=633099800076221175" type="text/javascript"></script>
<script type="text/javascript">
<!--
function WebForm_OnSubmit() {
if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) return false;
return true;
}
// -->
</script>

    <div>
        
Test:
<input name="ctl00$ContentPlaceHolder1$MyTxtBx" type="text" id="ctl00_ContentPlaceHolder1_MyTxtBx" />
<span id="ctl00_ContentPlaceHolder1_RVMyTxtBx" style="color:Red;visibility:hidden;">Očakáva sa hodnota</span>
<span id="ctl00_ContentPlaceHolder1_RNVMyTxtBx" style="color:Red;visibility:hidden;">Očakáva sa číslo v rozsahu 10 až 100</span>

    </div>
    
<script type="text/javascript">
<!--
var Page_Validators =  new Array(document.getElementById("ctl00_ContentPlaceHolder1_RVMyTxtBx"), document.getElementById("ctl00_ContentPlaceHolder1_RNVMyTxtBx"));
// -->
</script>

<script type="text/javascript">
<!--
var ctl00_ContentPlaceHolder1_RVMyTxtBx = document.all ? document.all["ctl00_ContentPlaceHolder1_RVMyTxtBx"] : document.getElementById("ctl00_ContentPlaceHolder1_RVMyTxtBx");
ctl00_ContentPlaceHolder1_RVMyTxtBx.controltovalidate = "ctl00_ContentPlaceHolder1_MyTxtBx";
ctl00_ContentPlaceHolder1_RVMyTxtBx.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";
ctl00_ContentPlaceHolder1_RVMyTxtBx.initialvalue = "";
var ctl00_ContentPlaceHolder1_RNVMyTxtBx = document.all ? document.all["ctl00_ContentPlaceHolder1_RNVMyTxtBx"] : document.getElementById("ctl00_ContentPlaceHolder1_RNVMyTxtBx");
ctl00_ContentPlaceHolder1_RNVMyTxtBx.controltovalidate = "ctl00_ContentPlaceHolder1_MyTxtBx";
ctl00_ContentPlaceHolder1_RNVMyTxtBx.focusOnError = "t";
ctl00_ContentPlaceHolder1_RNVMyTxtBx.type = "Integer";
ctl00_ContentPlaceHolder1_RNVMyTxtBx.evaluationfunction = "RangeValidatorEvaluateIsValid";
ctl00_ContentPlaceHolder1_RNVMyTxtBx.maximumvalue = "100";
ctl00_ContentPlaceHolder1_RNVMyTxtBx.minimumvalue = "10";
// -->
</script>

<div>

    <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgLuiJXhBgKFpqmoBbzi6FWJlSS1r6d/pK0XZhqroVeR" />
</div>

<script type="text/javascript">
<!--
var Page_ValidationActive = false;
if (typeof(ValidatorOnLoad) == "function") {
    ValidatorOnLoad();
}

function ValidatorOnSubmit() {
    if (Page_ValidationActive) {
        return ValidatorCommonOnSubmit();
    }
    else {
        return true;
    }
}
// -->
</script>
        </form>
</body>
</html>

A teraz urobme pár zmien. Zaveďme PageBase, kde si vynútime krátke IDčko pre MasterPage('M') a použime ju ako bázovú triedu pre každú Page a contentPlaceholderom priraďme dvoj písmenkové IDčka(CM).

Master Page:

<%@ Master 
    Language="C#"
    EnableViewState="false"
    AutoEventWireup="true"
    CodeBehind="TestMaster.master.cs"
    Inherits="TestID.TestMaster" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder ID="CM" runat="server"/>
    </div>
    </form>
</body>
</html>

Page:

<%@ Page 
    Language="C#" 
    MasterPageFile="~/TestMaster.Master"
    AutoEventWireup="false"
    EnableViewState="false"
    CodeBehind="TestForm.aspx.cs"
    Inherits="TestID.TestForm"
    Title="Test form" %>
    
<asp:Content ID="CM" ContentPlaceHolderID="CM" runat="server">
Test:
<asp:TextBox ID="MyTxtBx" runat="server"/>
<asp:RequiredFieldValidator 
    ID="RVMyTxtBx"
    runat="server" 
    ControlToValidate="MyTxtBx"
    Text="Očakáva sa hodnota"
    />
<asp:RangeValidator
    runat="server"     
    ControlToValidate="MyTxtBx"
    Text="Očakáva sa číslo v rozsahu 10 až 100"
    MaximumValue="100"
    MinimumValue="10"
    ID="RNVMyTxtBx"
    SetFocusOnError="true"
    Type="Integer"
    />
</asp:Content>

Code Behind:

using ASPNET.Web;

namespace TestID 
{
    public partial class TestForm : PageBase
    {        
    }
}

PageBase:

using System;
using System.Web.UI;

namespace ASPNET.Web
{
    public class PageBase : Page
    {
        protected override void OnPreInit(EventArgs e)
        {
            base.OnPreInit(e);
            if (this.Master != null)
                this.Master.ID = "M";
        }
    }
}

Výsledne HTML má 2 578. Samozrejme, zaujímavejší je ten absolutný rozdiel, nie pomer, pretože ide o naozaj jednoduchú stránku bez ďalšieho statického HTML contentu. Pri zložitejšom formuláry, ako vidíme môžeme ušetriť takto bežne kludne 10kb, ktoré sa na rozdiel od cachovaných obrázkov budú prenášať na klienta vždy, no maličkosť však?

Komentáre

# skippo said:

Ak by to niekoho zaujimalo, kedy ASP.NET prideli kontrolke genericke ClientID, tak je to vo faze pridania kontrolky do kolekcie kontroliek otca. Teda parent.Controls kolekcie.

Tuesday, July 17, 2007 4:08 PM
Prihlásiť | Registrovať | Pomoc