asp.net 用户控件 vs 自定义控件 vs stringbuilder

发布于 2024-10-09 07:23:39 字数 1100 浏览 4 评论 0原文

我正在构建一个产品目录,每页显示 50/100 个产品。 由于我想在我的网站上有不同的浏览部分,因此我将每个产品 到用户控件中。好吧,当然不是产品本身,而是一些标签、div 和图像。然后,我在处理数据库结果时在运行时设置其属性。所以优点是我只需要在整个站点的 1 个地方更改产品控制。我在循环中使用 LoadControl 将控件放入页面中。

然而,这些页面的加载速度不如其他处理相同数据库查询并使用 StringBuilder 输出相同 html 的页面那么快。因为我希望我的网站在收到一些不错的流量时表现良好,所以我对此感到担心。我还没有进行任何基准测试,但我清楚地看到了差异。

我的问题已经够多了!我向您提出的问题是“是否有任何替代方案比将 LoadControl 与自定义控件一起使用更快但易于维护(或至少在 1 个位置)?”

我正在考虑:

  1. 创建一个自定义控件(尽管我从未这样做过,并且不知道 100% 这是否会加快速度)
  2. 继续使用 StringBuilder 方法并将 CreateProduct 放入我的基类中
  3. 放弃维护产品在 1 个位置

我希望你们也有类似情况的选择,所以我真的很想听听你们的意见!

[编辑]代码[/编辑] 我这里没有准确的用户控件代码,但我回家后会编辑这篇文章..但这里是简化的想法:

1)获取我的数据库结果(使用 Subsonic 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
   }
}

我的用户控件本身只包含 3文字控件和 1 个图像控件。

但当我回到家时,我会发布完整的代码! 谢谢

I'm building a product catalog which displays between 50/100 products per page.
Since I want to have different browse sections on my site I've put each product
into a UserControl. Well, not the products themselves ofcourse, but some labels, divs
and images. I then set its properties in run-time when processing the database results. So the advantage is that I only have to change the product control at 1 place for the whole site. I'm putting the controls in a page using LoadControl in a loop.

However the pages are not loading quite as fast as other pages which process the same db query and output the same html using a StringBuilder. And since I want my site to perform well if/when it receives some decent traffic I'm worried about this. I haven't done any benchmarkings yet but I clearly see the difference.

Well enough of my problems! My questions to you is 'Are there any alternatives which are faster then using LoadControl with a customcontrol but are easily maintained (or atleast in 1 location)?'

I was thinking of:

  1. Creating a customcontrol (although I've never done it and don't know 100% if this will speed things up)
  2. Continue with the StringBuilder method and put the CreateProduct in my base class
  3. Ditching the whole idea of maintaining the product in 1 location

I hope you guys have had similar situations choices so I'd really like to hear from you!

[edit]Code[/edit]
I don't have the excact usercontrol code here but I will edit this post when I get home..but here is the simplified idea:

1) Getting my database result (using Subsonic 2.2 as my 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
   }
}

My usercontrol itselves just consists of 3 Literal controls and 1 Image control.

But I will post complete code when I arrive home!
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

°如果伤别离去 2024-10-16 07:23:39

假设您的数据库查询结果有一个产品列表 List。您可以将 Repeater 控件绑定到该列表,然后在标记中将 UserControl 添加到转发器中。

下面是一个示例,其中类 Product 如下所示:

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 属性绑定到用户的相应属性控制。

如果这还不够快,也许您的用户控件有些奇怪?

Let's say you have a list of products List<Product> as a result of your database query. You can bind a Repeater control to that list and then in your markup add the UserControl within the repeater.

Here's a example, with class Product as shown:

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

In your markup declare:

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

Then in your code behind:

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

That will add 1 user control per record in your products list and bind the Sku and Name properties of Property object to the respective properties on the user control.

If that's not fast enough, maybe there's something funky with your user control?

小清晰的声音 2024-10-16 07:23:39

UserControl 听起来像是您正在做的事情的优质解决方案。不要放弃这个想法。抽象让世界运转。

我已要求您显示您的 UserControl 标记。另外,您不需要使用 LoadControl() ,除非您在后面的代码中构建这一切。

A UserControl sounds like a quality solution for what you're doing. Do not ditch this idea. Abstraction makes the world go around.

I've asked you to show your UserControl mark up. Also, you don't need to use LoadControl() unless you're building this all in the code behind.

呆萌少年 2024-10-16 07:23:39

我会改用 ASP.NET Server 控件并重写它的 Render 方法。这与您的 StringBuilder 解决方案更相似,因为您可以使用提供给该方法的 HtmlTextWriter 来构建 HTML 输出,类似于使用字符串构建器的方式。但同时您可以获得控制结构,它使您能够添加属性、管理状态等。并且由于服务器控件是编译的,因此我认为它通常会比用户控件执行得更好一些。

我还将创建另一个服务器控件,它是一个用于构建控件列表的容器。不确定这会提高性能,但这是一个很好的实践,并且将使您的代码更容易重用和维护。

I would switch to using an ASP.NET Server control and override it's Render method. This is more similar to your StringBuilder solution in that you can use the HtmlTextWriter supplied to the method to build your HTML output similar to how you would with your string builder. But at the same time you get the control structure, which gives you the ability to add properties, manage state, etc. And since an server control is compiled, I think it will generally perform a little better than a user control.

I would also create another server control that is a container that is used to build your list of controls. Not sure this will be much more performant, but it's a good practice and will make your code a bit easier to reuse and maintain.

素衣风尘叹 2024-10-16 07:23:39

您是否尝试过在 UserControl 中关闭 Viewstate ?如果您使用 StringBuilder 构建标记,则不会为任何该标记来回传输任何 Viewstate。如果您使用默认的 ASP Web 控件,它们将默认具有 Viewstate,该视图状态将在页面加载和回发期间来回传输,并且可能会很大,具体取决于应用程序中使用的 Web 控件。 UserControl 并重复 50 至 100 次。

编辑:如果 Viewstate 不是问题,您是否验证了 UserControl 生成的标记与您在 UserControl 中生成的标记相同或相当等效>字符串生成器?

另一件重要的事情是对服务器和客户端时间进行基准测试。如果标记不同,客户端渲染时间可能会显着变化。如果服务器和客户端时间相同(或差异不大),那么您需要查看服务器输出的大小和传输时间。

Have you tried turning Viewstate off in your UserControl? If you're building the markup using a StringBuilder, then there will not be any Viewstate transferred back and forth for any of that markup. If you're using default ASP web controls, they will default to having Viewstate, which will be transferred back and forth during pageload and postbacks, and could be quite large depending on what web controls are used in the UserControl and repeated 50 to 100 times.

Edit: If Viewstate is not the problem, have you verified that the markup generated by the UserControl is the same or reasonably equivalent to the markup you're generating in the StringBuilder?

Another critical thing to do is to benchmark server and client times. If the markup is different, the client rendering times may change noticably. If the server and client times are the same (or insignificantly different) then you need to look at sizes of the server output and transfer times.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文