SiteSetting class need redesign

This forum is only for questions or discussions about working with the mojoPortal source code in Visual Studio, obtaining the source code from the repository, developing custom features, etc. If your question is not along these lines this is not the right forum. Please try to post your question in the appropriate forum.

Please do not post questions about design, CSS, or skinning here. Use the Help With Skins Forum for those questions.

This forum is for discussing mojoPortal development

This forum is only for questions or discussions about working with the mojoPortal source code in Visual Studio, obtaining the source code from the repository, developing custom features, etc. If your question is not along these lines this is not the right forum. Please try to post your question in the appropriate forum.

You can monitor commits to the repository from this page. We also recommend developers to subscribe to email notifications in the developer forum as occasionally important things are announced.

Before posting questions here you might want to review the developer documentation.

Do not post questions about design, CSS, or skinning here. Use the Help With Skins Forum for those questions.
This thread is closed to new posts. You must sign in to post in the forums.
9/1/2006 2:34:21 PM
Gravatar
Total Posts 148

Re: SiteSetting class need redesign

Repeatedly double num browser sessions up until server cpu pegs at 100% or "average time until first byte" roughly doubles.  That should indicate that the server has hit a bottleneck.  Make sense?
9/1/2006 2:39:59 PM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

The remote web server was pegged at 100% cpu in the last tests. Do you mean the ACT machine? It wasn't working very hard.
9/1/2006 3:53:24 PM
Gravatar
Total Posts 148

Re: SiteSetting class need redesign

No, I mean the remote web server.  I don't think you need to redo the last tests.  I think you should redo the earlier 2 tests where you weren't doing page output caching.  One with and one without module caching.  That will give you a better indication of what you are gaining with module caching and page output caching.

9/1/2006 4:08:20 PM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

The last 2 tests were with module caching and no page output caching. One was on running all locally on my laptop with both ACT and Web/SQL and one was with ACT running on my laptop and the Web/SQL running on a remote P3 800 machine.

Tests previous to those showed significant benefit to module caching vs not module caching and dumb pageoutput caching also showed significant improvement over module caching though that was run all on my laptop. I can redo the comparisons on the remote machine though thats no problem.
I'll run them in the morning and post the results.

9/2/2006 1:06:07 PM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

OK, here are some more tests run against a remote machine. I have not yet done anything to reduce page size in mojoPortal, so this is still just trying to establish a baseline before working on that and to get a comparisin vs DotNetNuke.

The ACT machine is my laptop Pentium M 2.13Ghz with 2Gigs of RAM
The Test web server is Pentium3 with 1Gig of RAM running Win2003 Server with MS SQL 2005 on the same machine.

In all tests the ACT machine was barely working and the web server was 100%cpu. 4 browsers seemed to be the right amount to push the processor to 100% on the web server.

In between each test I rebooted the web server and waited a few minutes to ensure all services were up and running.

I tested both mojoPortal, and the latest download of DotNetNuke, v4.3.4

The test sites consists of 5 pages, Home, Blog, Events, Forum, Image Gallery, each page has the corresponding module, the home page has an Html module and a links module

In both the mojoportal site and the DNN site I entered the exact same content in the modules.

mojoPortal using no Module Cache
maximum wpg memory use during test was 51,336K





mojoPortal using Module Cache of 360 Seconds
maximum wpg memory use during test was 49,024K




mojoPortal using dumb page output cache
maximum wpg memory use during the test was 47,952K
"dumb" means it renders the same page to all users regardless fo roles or anything else, it just caches the entire page and serves that copy up to all requests until the cache expires. We can't actually use this but it gives an idea of the upper bounds of possible improvement through caching.





DotNetNuke 4.3.4
The html module in DNN has a default cache time of 1200 seconds and the links module has a default of 60 seconds, the forums, blog, and image gallery all have defaults of 0 seconds which I assume is no cache.
For the first test I left things at the defaults.
Maximum wpg memory use during the first test was 100,644K




DotNetNuke test with additional modules cached
I then tried bumping up the cache time on the Blog, Events, Forum, and Image Gallery of DNN to 360 seconds.
Apparently there are some major problems in caching the Events or the Blog as the site became un-responsive to anonymous requests of the Blog page or Events page.
wpg memory consumption went up over 632,248K and seemed as if it would keep going up the longer the test was run.




Tests with the browser showed it was the blog and event pages that were un-responsive with anonymous sessions, though it seemed ok when logged in as admin, not sure whether caching is disabled or handled differently for admins or authenticated users but obviously setting a cache time greater than 0 on blgo module or events module in DNN will hose up a site when visited by anonymous browsers.

I had heard from a number of people that DNN has performance problems but now I see it is more than anecdotal, there are some performance issues and apparently memory leaks in the lates version of DNN.
9/2/2006 2:12:49 PM
Gravatar
Total Posts 148

Re: SiteSetting class need redesign

Here's my quick and dirty analysis:

Processing of requests can be broken into three parts:

A. Rendering modules.  This includes DB calls, business object instantiation, and rendering to HTML
B. Rendering a page from rendered modules.
C. Sending the rendered page to the browser.

A+B+C = 130 req/sec = 7.7 ms/req
B+C = 190 req/sec = 5.3 ms/req
C = 300 req/sec = 3.3 ms/req

Taking differences:

A = 2.4 ms/req = 31%
B = 2.0 ms/req = 26%
C = 3.3 ms/req = 43%

Reducing the number of bytes sent to the browser definitely seems to be the way to go.  Not only will it reduce C but it will probably also reduce A and B because they both involve rendering those bytes.

--Dean
9/2/2006 3:10:52 PM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

I think your analysis is right on. Here are the file sizes from the test when saved as html from IE



Obviously file size was a factor in the DNN tests since the files are bigger.
I can understand the dnnForum page being larger as it has some additional things compared to the mojoPortal Forum, like a scrolling marquee of the most recent posts. But in general I think there is heavier table layout markup in the DNN pages, maybe more viewstate too I haven't measured it.

Interesting since I entered the same content in both, yet there is still room for improvement in mojoPortal. I'll be working on this tomorrow and will post some results. I'll be testing after little changes to see if the page is smaller and if the performance of the tests goes up.
9/4/2006 6:30:04 AM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

After doing some work to reduce the size of viewstate and to reduce the amount of inline styles the file sizes were a good bit smaller and performance improved.

File Sizes from first test (same as previous post)

File sizes after reducing viewstate and inline styles

This is with the exact same content in the db as before.

mojoPortal Using no module cache



mojoPortal with All modules Cached 360 seconds




However, I discovered in my testing that not all modules in their current implementation can work correctly with caching enabled. Modules that use postback don't seem to work as expected. I tried working around this by checking whether its a postback in the CachedSiteModule control by always loading a fresh copy instead of the cached one on postback but then it did not seem to fire the events. Maybe I can figure out a way at some point but for now I disabled cache on the 2 modules affected, Blog and Events. Blog works fine except for the calendar navigation so it could be cached if not showing the calendar. Events was affected by the same problem because it is essentially a calender inheriting from the asp.net Calendar. Possibly these could be re-implemented at some point to use javascript calendars and querystring based rather than postback based navigation. So for current real world comparison I tested again after setting cache to 0 (no cache) on the blog and events modules. This configuration is comparable to the defaults in DotNetNuke, they cache Html module and links module by default but not Events and not Blog (but don't forget if you enable caching Blog and Events in DNN it causes serious memory leak and performance degradation).

mojoPortal with All Modules except Blog and Events cached 360 seconds



So, in summary, reducing page size by reducing viewstate and inline markup increased performance as follows:
Using no Module Cache                    RPS went from 123.90 to 135.65
Using Module Cache on all Modules     RPS went from 191.52 to 200.57

and caching all modules except Blog and Events came in at 171.76 RPS

The main trick to reducing inline styles was not using style properties from the theme.skin file and only setting css class names there. Using the properties for style seems to result in very verbose inline styles. For example the asp.net Calendar control the original theme file was like this:

<asp:Calendar  runat="server"
     BackColor=""
     BorderColor=""
     BorderStyle="solid"
     BorderWidth="0"
     CaptionAlign="Top"
     CellPadding="3"
     CellSpacing="0"
     CssClass=""
     DayHeaderStyle-BackColor=""
     DayHeaderStyle-BorderColor=""
     DayHeaderStyle-BorderStyle="Solid"
     DayHeaderStyle-BorderWidth="0"
     DayHeaderStyle-CssClass=""
     DayHeaderStyle-Font-Bold="true"
     DayHeaderStyle-Font-Italic="false"
     DayHeaderStyle-Font-Names=""
     DayHeaderStyle-Font-Overline="false"
     DayHeaderStyle-Font-Size="8pt"
     DayHeaderStyle-Font-Strikeout="false"
     DayHeaderStyle-Font-Underline="false"
     DayHeaderStyle-ForeColor="black"
     DayHeaderStyle-Height=""
     DayHeaderStyle-HorizontalAlign="center"
     DayHeaderStyle-VerticalAlign="NotSet"
     DayHeaderStyle-Width=""
     DayHeaderStyle-Wrap="false"
     DayNameFormat="FirstLetter"
     DayStyle-BackColor=""
     DayStyle-BorderColor=""
     DayStyle-BorderStyle="solid"
     DayStyle-BorderWidth="0"
     DayStyle-CssClass=""
     DayStyle-Font-Bold="false"
     DayStyle-Font-Italic="false"
     DayStyle-Font-Names=""
     DayStyle-Font-Overline="false"
     DayStyle-Font-Size="8pt"
     DayStyle-Font-Strikeout="false"
     DayStyle-Font-Underline="false"
     DayStyle-ForeColor="black"
     DayStyle-Height=""
     DayStyle-HorizontalAlign="center"
     DayStyle-VerticalAlign="NotSet"
     DayStyle-Width=""
     DayStyle-Wrap="false"
     FirstDayOfWeek="sunday"
     Font-Bold="false"
     Font-Italic="false"
     Font-Names=""
     Font-Overline="false"
     Font-Size="small"
     Font-Strikeout="false"
     Font-Underline="false"
     ForeColor="Black"
     Height=""
     NextMonthText="+"
     NextPrevFormat="CustomText"
     NextPrevStyle-BackColor=""
     NextPrevStyle-BorderColor="black"
     NextPrevStyle-BorderStyle="solid"
     NextPrevStyle-BorderWidth="0"
     NextPrevStyle-CssClass=""
     NextPrevStyle-Font-Bold="true"
     NextPrevStyle-Font-Italic="false"
     NextPrevStyle-Font-Names=""
     NextPrevStyle-Font-Overline="false"
     NextPrevStyle-Font-Size="small"
     NextPrevStyle-Font-Strikeout="false"
     NextPrevStyle-Font-Underline="false"
     NextPrevStyle-ForeColor="black"
     NextPrevStyle-Height=""
     NextPrevStyle-HorizontalAlign="center"
     NextPrevStyle-VerticalAlign="NotSet"
     NextPrevStyle-Width=""
     NextPrevStyle-Wrap="false"
     OtherMonthDayStyle-BackColor="#f3f3f3"
     OtherMonthDayStyle-BorderColor="black"
     OtherMonthDayStyle-BorderStyle="solid"
     OtherMonthDayStyle-BorderWidth="0"
     OtherMonthDayStyle-CssClass=""
     OtherMonthDayStyle-Font-Bold="false"
     OtherMonthDayStyle-Font-Italic="false"
     OtherMonthDayStyle-Font-Names=""
     OtherMonthDayStyle-Font-Overline="false"
     OtherMonthDayStyle-Font-Size="8pt"
     OtherMonthDayStyle-Font-Strikeout="false"
     OtherMonthDayStyle-Font-Underline="false"
     OtherMonthDayStyle-ForeColor="black"
     OtherMonthDayStyle-Height=""
     OtherMonthDayStyle-HorizontalAlign="center"
     OtherMonthDayStyle-VerticalAlign="NotSet"
     OtherMonthDayStyle-Width=""
     OtherMonthDayStyle-Wrap="false"
     PrevMonthText="-"
     SelectedDayStyle-BackColor="Beige"
     SelectedDayStyle-BorderColor="black"
     SelectedDayStyle-BorderStyle="solid"
     SelectedDayStyle-BorderWidth="0"
     SelectedDayStyle-CssClass=""
     SelectedDayStyle-Font-Bold="false"
     SelectedDayStyle-Font-Italic="false"
     SelectedDayStyle-Font-Names=""
     SelectedDayStyle-Font-Overline="false"
     SelectedDayStyle-Font-Size="8pt"
     SelectedDayStyle-Font-Strikeout="false"
     SelectedDayStyle-Font-Underline="false"
     SelectedDayStyle-ForeColor="black"
     SelectedDayStyle-Height=""
     SelectedDayStyle-HorizontalAlign="center"
     SelectedDayStyle-VerticalAlign="NotSet"
     SelectedDayStyle-Width=""
     SelectedDayStyle-Wrap="true"
     SelectorStyle-BackColor="#eee"
     SelectorStyle-BorderColor="red"
     SelectorStyle-BorderStyle="solid"
     SelectorStyle-BorderWidth="0"
     SelectorStyle-CssClass=""
     SelectorStyle-Font-Bold="true"
     SelectorStyle-Font-Italic="false"
     SelectorStyle-Font-Names=""
     SelectorStyle-Font-Overline="false"
     SelectorStyle-Font-Size="8pt"
     SelectorStyle-Font-Strikeout="false"
     SelectorStyle-Font-Underline="false"
     SelectorStyle-ForeColor="Green"
     SelectorStyle-Height=""
     SelectorStyle-HorizontalAlign="center"
     SelectorStyle-VerticalAlign="NotSet"
     SelectorStyle-Width=""
     SelectorStyle-Wrap="false"
     ShowDayHeader="true"
     ShowGridLines="true"
     ShowNextPrevMonth="true"
     ShowTitle="true"
     TitleFormat="MonthYear"
     TitleStyle-BackColor=""
     TitleStyle-BorderColor="black"
     TitleStyle-BorderStyle="solid"
     TitleStyle-BorderWidth="0"
     TitleStyle-CssClass=""
     TitleStyle-Font-Bold="true"
     TitleStyle-Font-Italic="false"
     TitleStyle-Font-Names=""
     TitleStyle-Font-Overline="false"
     TitleStyle-Font-Size="8pt"
     TitleStyle-Font-Strikeout="false"
     TitleStyle-Font-Underline="false"
     TitleStyle-ForeColor="Black"
     TitleStyle-Height=""
     TitleStyle-HorizontalAlign="center"
     TitleStyle-VerticalAlign="NotSet"
     TitleStyle-Width=""
     TitleStyle-Wrap="false"
     TodayDayStyle-BackColor="lightyellow"
     TodayDayStyle-BorderColor="black"
     TodayDayStyle-BorderStyle="solid"
     TodayDayStyle-BorderWidth="0"
     TodayDayStyle-CssClass=""
     TodayDayStyle-Font-Bold="false"
     TodayDayStyle-Font-Italic="false"
     TodayDayStyle-Font-Names=""
     TodayDayStyle-Font-Overline="false"
     TodayDayStyle-Font-Size="8pt"
     TodayDayStyle-Font-Strikeout="false"
     TodayDayStyle-Font-Underline="false"
     TodayDayStyle-ForeColor="Black"
     TodayDayStyle-Height=""
     TodayDayStyle-HorizontalAlign="center"
     TodayDayStyle-VerticalAlign="NotSet"
     TodayDayStyle-Width=""
     TodayDayStyle-Wrap="true"
     WeekendDayStyle-BackColor="lightgray"
     WeekendDayStyle-BorderColor="black"
     WeekendDayStyle-BorderStyle="solid"
     WeekendDayStyle-BorderWidth="0"
     WeekendDayStyle-CssClass=""
     WeekendDayStyle-Font-Bold="false"
     WeekendDayStyle-Font-Italic="false"
     WeekendDayStyle-Font-Names=""
     WeekendDayStyle-Font-Overline="false"
     WeekendDayStyle-Font-Size="8pt"
     WeekendDayStyle-Font-Strikeout="false"
     WeekendDayStyle-Font-Underline="false"
     WeekendDayStyle-ForeColor="black"
     WeekendDayStyle-Height=""
     WeekendDayStyle-HorizontalAlign="center"
    WeekendDayStyle-VerticalAlign="NotSet"
     WeekendDayStyle-Width=""
     WeekendDayStyle-Wrap="true"
     Width=""
    />

and after moving the style settings into separate .css file the theme.skin was like this:

<asp:Calendar  runat="server"
     CaptionAlign="Top"
     CssClass="aspcalendarmain"
     DayHeaderStyle-CssClass="aspcalendardayheader"
     DayNameFormat="FirstLetter"
     DayStyle-CssClass="aspcalendarday"
     FirstDayOfWeek="sunday"
     NextMonthText="+"
     NextPrevFormat="CustomText"
     NextPrevStyle-CssClass="aspcalendarnextprevious"
     OtherMonthDayStyle-CssClass="aspcalendarothermonth"
     PrevMonthText="-"
     SelectedDayStyle-CssClass="aspcalendarselectedday"
     SelectorStyle-CssClass="aspcalendarselector"
     ShowDayHeader="true"
     ShowGridLines="false"
     ShowNextPrevMonth="true"
     ShowTitle="true"
     TitleFormat="MonthYear"
     TitleStyle-CssClass="aspcalendartitle"
     TodayDayStyle-CssClass="aspcalendartoday"
     WeekendDayStyle-CssClass="aspcalendarweekendday"
  
    />
9/4/2006 6:56:48 AM
Gravatar
Total Posts 148

Re: SiteSetting class need redesign

Performance improvement is substantially less than I would have expected.  Not sure why.  You said the test involve visiting each of the 5 pages, but the ACT results show 1194 iterations, 40695 total requests, and 28 unique requests.  Any idea why?  Is ACT requesting the images on each page in addition to the HTML?  Somethinge else?

--Dean
9/4/2006 7:00:17 AM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

Yes, the ACT script seems to request each file associated with each page, images, css, js etc.
Here is an example fragment from the test script that ACT generated:

Sub SendRequest7()
    Dim oConnection, oRequest, oResponse, oHeaders, strStatusCode
    If fEnableDelays = True then Test.Sleep (31)
    Set oConnection = Test.CreateConnection("loadtest", 80, false)
    If (oConnection is Nothing) Then
        Test.Trace "Error: Unable to create connection to loadtest"
    Else
        Set oRequest = Test.CreateRequest
        oRequest.Path = "/mojo/Data/Sites/1/logos/mojotonguesmall.gif"
        oRequest.Verb = "GET"
        oRequest.HTTPVersion = "HTTP/1.0"
        set oHeaders = oRequest.Headers
        oHeaders.RemoveAll
        oHeaders.Add "Accept", "*/*"
        oHeaders.Add "Referer", "http://loadtest/mojo/"
        oHeaders.Add "Accept-Language", "en-us,it;q=0.91,de;q=0.82,nl;q=0.73,pt-br;q=0.64,ru;q=0.55,cs;q=0.45,ar-iq;q=0.36,es-mx;q=0.27,tr;q=0.18,es;q=0.09"
        oHeaders.Add "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; InfoPath.1)"
        'oHeaders.Add "Host", "loadtest"
        oHeaders.Add "Host", "(automatic)"
        'oHeaders.Add "Cookie", ".ASPXANONYMOUS=2lksUHn1XnRaup90RPMBynbWw2f7745q0xZRq2QnY85H4eCWQ6NudN20yphIUdM2Y27QTlSSxVc-2uShJkiKsj6mNGoVDbJ80; DisplayName=Admin; ASP.NET_SessionId=ouu1rz55zo0ivwexohawa4bm"
        oHeaders.Add "Cookie", "(automatic)"
        Set oResponse = oConnection.Send(oRequest)
        If (oResponse is Nothing) Then
            Test.Trace "Error: Failed to receive response for URL to " + "/mojo/Data/Sites/1/logos/mojotonguesmall.gif"
        Else
            strStatusCode = oResponse.ResultCode
        End If
        oConnection.Close
    End If
End Sub

Joe
9/4/2006 8:13:08 AM
Gravatar
Total Posts 148

Re: SiteSetting class need redesign

OK.  So we need to add:

D. Sending static content to the browser.

and the test you've been running so far assumes that all users are new users.  To measure performance for existing users, you should probably add:

oHeaders.Add "If-Modified-Since", "Mon, 4 Sep 2006 00:00:00 GMT"

to each of the requests for static content.  I'm assuming that ACT doesn't do that automatically somehow.  Note that if you do that, you'll either need to update that data manually if you modify the static content, or generate it automatically in the correct format.  A simpler method would be to just not make the requests for static content at all.  For that to be truly realistic though mojoPortal would need to provide a way to offload the static requests to a different server, a la akamai.  I don't think that would be that hard to implement.  Basically wherever you generate URLs that contain "Data/Sites", you'd allow for a different hostname to be used.

Also, it's not clear whether ACT is actually creating a new connection for each request or whether it is pooling connections somehow.  If it's creating a new connection that could create a slightly higher load on the server and increase the time to first byte.  I'd ignore that for now though.

--Dean
You must sign in to post in the forums. This thread is closed to new posts.