core icon indicating copy to clipboard operation
core copied to clipboard

Sitelet runtime performance improvements

Open Jand42 opened this issue 7 years ago • 2 comments

Sitelets encapsulate routing and serving content. Both has possible ways to improve upon, needs to be investigated and profiled.

  1. Standard WebSharper resource folders (Content/Scripts) and possibly other custom folders could be excluded from routing and thus Sitelet runtime spends minimal amount of time on these request and will go down the pipeline to serve the files faster.
  2. Content type could wrap a synchronous or asynchronous value (either F# Async or Task) with minimal conversions between them. Synchronous content should be served without any asynchronicity introduced by the Sitelet runtime.
  3. The Context type should wrap underlying information through lazy values, not evaluating any properties of HttpRequestBase if not needed.

Jand42 avatar Jan 04 '18 12:01 Jand42

I would say no to 1), since that's a form of hardcoding, and it is completely valid to potentially need URLs involving "resource folders" routed from a sitelet.

Can you elaborate on the proposed API changes/additions for 2)?

granicz avatar Jan 04 '18 14:01 granicz

@granicz re 2): Currently, pretty much all Content-handling F# functions manipulate values of type Async<Content<'T>>. They would need to manipulate values of type Content<'T> instead. Now the issue is, if eg Application.MultiPage expects you to provide a Content<'T>, how are you going to do asynchronous actions such as ctx.UserSession.GetLoggedInUser() before returning a Content<'T>? The best possibility I can see is that we create a custom computation expression that can let!-bind Async<'T> but returns a Content<'T>:

// Current code:
Application.MultiPage <| fun ctx endpoint ->
    match endpoint with
    | Home ->
        async {
            let! user = ctx.UserSession.GetLoggedInUser()
            return!
                Content.Text "blah"
                |> Content.WithContentType "text/plain"
        }

// Proposed code:
Application.MultiPage <| fun ctx endpoint ->
    match endpoint with
    | Home ->
        content {
            let! user = ctx.UserSession.GetLoggedInUser()
            return
                Content.Text "blah"
                |> Content.WithContentType "text/plain"
        }

Here, the types of Application.MultiPage, Content.Text and Content.WithContentType would change from taking and/or returning Async<Content<'T>> to Content<'T>.

The code above looks very similar, but more complex examples might not be so lucky; in terms of API it is a sizeable breaking change, so we may want to leave it for v5.0.

Tarmil avatar Jan 09 '18 18:01 Tarmil