2010-12-22 92 views
1

我正在構建一個產品目錄,每頁顯示50/100個產品。 由於我想在我的網站上有不同的瀏覽部分,我已將每個產品 放到UserControl中。那麼,不是產品本身的課程,而是一些標籤,div和 和圖像。然後在處理數據庫結果時在運行時設置它的屬性。所以我的優勢是我只需要在整個網站的1個地方改變產品控制。我在循環中使用LoadControl將控件放在頁面中。asp.net usercontrol vs customcontrol vs stringbuilder

但是頁面加載速度不如其他頁面處理相同db查詢並使用StringBuilder輸出相同html的速度。而且,因爲我希望我的網站在收到一些像樣的流量時表現的很好,所以我很擔心這一點。我還沒有做任何基準,但我清楚地看到了差異。

我的問題夠了!我對你的問題是'是否有任何替代方法可以更快地使用LoadControl進行定製控制,但易於維護(或者至少在1個位置)?「

我在想:

  1. 創建customcontrol(雖然我從來沒有做過,不知道100%,這是否會加快速度)
  2. 繼續與StringBuilder的方法,並把在我的基類
  3. 的CreateProduct開溝1個位置

保持了產品的整個想法,我希望你們有過類似情況的選擇,所以我很想聽到˚F rom你!

[編輯]代碼[/編輯] 我沒有excact用戶控件代碼在這裏,但是當我拿到home..but這裏是簡化的想法,我會編輯這個職位:

1)讓我數據庫結果(使用亞音速2.2作爲我DAL)

DAL.ProductCollection coll = new DAL.ProductCollection(); 
if(coll.count > 0) 
{ 
    foreach(DAL.Product item in coll) 
    { 
    Control p = LoadControl("FeaturedProduct.ascx"); 
    placeholder.Controls.Add(p); 

    //Set properties 
    p.title = item.Title; 
    p.img = GetImage(item.Guid); 
    ....etc 
    } 
} 

我的用戶itselves只是由3個立即控制和1點圖像的控制。

但我會在我到家時發佈完整的代碼! 謝謝

+0

你可以發佈一些你的html輸出嗎?和你的產品`UserControl`?當你調用`LoadControl()`時? – hunter 2010-12-22 19:30:49

回答

2

您是否試過在您的UserControl中關閉Viewstate?如果您使用StringBuilder構建標記,那麼將不會有任何Viewstate來回傳遞任何標記。如果您使用的是默認的ASP網頁控件,則它們將默認爲Viewstate,它將在頁面加載和回發期間來回傳輸,並且可能會非常大,具體取決於UserControl中使用的Web控件的重複次數,並重復50到100次。

編輯:如果Viewstate不是問題,您是否驗證過UserControl生成的標記與您在StringBuilder中生成的標記相同或合理等效?

另一個重要的事情是基準服務器和客戶端時間。如果標記不同,客戶端渲染時間可能會明顯改變。如果服務器和客戶端時間相同(或者不相同),則需要查看服務器輸出和傳輸時間的大小。

+0

是的,該網站的大部分部分都關閉了視圖狀態。雖然它不是很慢,但顯然比stringbuilder慢。也許我只是偏執狂,需要更快的電腦。 – Mark 2010-12-22 19:29:50

1

UserControl聽起來像是你正在做的一個高質量的解決方案。不要拋棄這個想法。抽象使世界四處走動。

我要求您顯示您的UserControl標記。另外,除非您在後面的代碼中構建全部內容,否則不需要使用LoadControl()

2

假設您的數據庫查詢結果中包含產品List<Product>的列表。您可以將Repeater控件綁定到該列表,然後在您的標記中添加中繼器中的UserControl。

這裏有一個例子,以一流的產品,如下所示:

class Product{ public string Sku{ get; set; } public string Name{ get; set; } } 

在你的標記聲明:

在後面的代碼
<asp:Repeater runat="server" ID="ProductsRepeater" > 
    <ItemTemplate> 
     <uc1:ProductsUserControl runat="server" ID="productsControl" Sku='<%# Eval("Sku")%>' Name='<%# Eval("Name") %>'/> 
    </ItemTemplate> 
</asp:Repeater> 

然後:

protected void Page_Load(object sender, EventArgs 
{ 
    ProductsRepeater.DataSource = myProductsList; 
    ProductsRepeater.DataBind(); 
} 

這將增加1用戶控制產品列表中的每個記錄,並將Property對象的Sku和Name屬性綁定到相應的pr操作用戶控件。

如果這還不夠快,或許你的用戶控件有些時髦嗎?

+0

嗨格雷格,感謝您的建議。我也想過這個解決方案,但我認爲Repeater在後臺也使用LoadControl。我認爲!但我會檢查出肯定感謝 – Mark 2010-12-22 21:00:15

1

我會切換到使用ASP.NET服務器控件並重寫它的Render方法。這更類似於您的StringBuilder解決方案,因爲您可以使用提供給該方法的HtmlTextWriter來構建HTML輸出,這與您對字符串構建器的使用方式類似。但是同時你得到了控制結構,這使得你可以添加屬性,管理狀態等等。而且由於編譯了服務器控件,我認爲它通常會比用戶控件執行得更好一些。

我還會創建另一個服務器控件,它是用來構建控件列表的容器。不確定這會更高性能,但這是一個很好的做法,並會使您的代碼更容易重用和維護。