vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
618 stars 167 forks source link

Trivial Vaadin UI with emty div element makes two XHRs to the server #17428

Open mstahv opened 1 year ago

mstahv commented 1 year ago

Description of the bug

When this Vaadin app renders, it makes two different XHRs to the server:

@Route
public class MainView extends Div {

    public MainView() {
    }
}

Expected behavior

There should be only one (or 0 in optimal situation where the state would be sent in initial host page).

Minimal reproducible example

Above

Versions

caalador commented 1 year ago

The first is a init request to the JavaScriptBootstrapHandler and the second returns the UI setup commands. The client-side bootstrapping model introduces the 2 step bootstrapping so this is an expected outcome against v10-v14

mshabarov commented 1 year ago

I don't see what we should fix here taking into account these 2 requests explained by @caalador , thus closing the issue.

mstahv commented 1 year ago

I have absolutely no idea what JavaScriptBootstrapHandler is and what it does, but let me show with couple of diagrams what happens:

V14:

sequenceDiagram
    Browser->>Server: Hello, what to render here?
    activate Server
    Server-->>Browser: Render this page with "Hello world"
    deactivate Server
    Browser->Browser: Interesting, content in embedded JS, fine, let's add that <p>Hello world</p> tag to body.

Here is a Safari requests in V14 for a trivial hello world app (taken from zero latency local environment):

Screenshot 2023-08-15 at 14 37 46

V24:

sequenceDiagram
    Browser->>Server: Hello, what to render here?
    activate Server
    Server-->>Browser: Start with this empty page, then let's see..
    deactivate Server
    Browser->Browser: Some JS that tells me to go to server again, ok...
    Browser->>Server: OK, your instructions told me to ask more here?
    activate Server
    Server-->>Browser: What was it that you want?
    deactivate Server
    Browser->Browser: Again some JS that tells me to go to server!!
    Browser->>Server: I just want to know what to render here 🤬
    activate Server
    Server-->>Browser: Ah ok, just render "Hello world!"
    deactivate Server
    Browser->Browser: Finally, let's add that <p>Hello world</p> tag to body.

Here is a Safari requests in V24.1.4 for the same trivial hello world app (taken from zero latency local environment):

Screenshot 2023-08-15 at 14 34 54

This is slower even in local environment. If there happens to be intercontinent network connection (or slow latency mobile network), the app loading time may turn from ok to shitty one. Fixing that intuitively sounds like a good idea to me.

Even if (for some wrong reasons like optimising defaults for compatibility with different frameworks) this "2 step bootstrapping" is preferred, I don't see why 2-step bootstrapping needs 3 visits to the server instead of two.

tltv commented 1 year ago

Enabling eager server load with vaadin.eagerServerLoad=true (JavaDoc in DeploymentConfiguration) will remove one extra xhr and speeds up init with slow network connection. It includes the initial UIDL fragment in the index.html but there's still one more xhr for UI init commands. Note that index.html is cacheable file by default but not so much anymore with vaadin.eagerServerLoad=true.

Question is, why do we need extra xhr for the following commands in the response and could we also include that in the initial UIDL?

for(;;);[
    {
        "clientId": 1,
        "execute": [
            [
                false,
                [
                    0,
                    3
                ],
                "return (function() { this.serverConnected($0)}).apply($1)"
            ],
            [
                0,
                null,
                [
                    0,
                    1
                ],
                "return (function() { this.$server['}p']($0, true, $1)}).apply($2)"
            ]
        ],
        "timings": [
            424,
            0
        ],
        "syncId": 1
    }
]