 <p>Have you tried turning <code>Viewstate</code> off in your <code>UserControl</code>? If you're building the markup using a <code>StringBuilder</code>, then there will not be any <code>Viewstate</code> transferred back and forth for any of that markup. If you're using default ASP web controls, they will default to having <code>Viewstate</code>, 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.</p> <p>Edit: If <code>Viewstate</code> is not the problem, have you verified that the markup generated by the <code>UserControl</code> is the same or reasonably equivalent to the markup you're generating in the <code>StringBuilder</code>?</p> <p>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.</p>