smohadjer / formwizard

A boilerplate for multi-step single-page forms
MIT License
1 stars 0 forks source link

Add js pre-fetch for step before and after current step #8

Open amcoho opened 6 years ago

amcoho commented 6 years ago

This is an optimization step so user experience is as fast as possible when js is enabled. Should be able to switch this on and off via a configuration flag and separately for before and after steps.

amcoho commented 6 years ago

From email: Since next screen can depend on choices user makes on current screen we use a data attribute on every step to indicate whether this step has decision-tree or not. If it doesn’t, we fetch the next step immediately and show it as soon as user clicks next. If it does, we fetch the next step first when user clicks next. I think this is a good compromise since I don’t think most form steps have decision three.

smohadjer commented 6 years ago

@amcoho

  1. But if we prefetch steps from server and store them in a js variable, doesn't this mean we display next step with data that maybe out-dated? Or do we assume that the data which user submits in current step, has no impact on how the next step will be displayed? For sake of simplicity let's assume no decision-tree is involved.

  2. Another concern is that in case of going to next step, we still need to wait for ajax to submit current step to server and for server to run validation and return us a response before we can show the next step. So would there be really a performance improvement with prefetching in this case? Is the performance improvement because server now returns only a flag indicating that all is good and we can display the next step rather than returning markup for the next step?

  3. In case of going to previous step I assume we don't need to send an ajax when back button is clicked anymore since data in current step has not changed when we go back in the form and hence we can immediately display the prefetched step. So the workflow changes from what we have right now, i.e. that is we only submit ajax when submit button is clicked, not when back button is clicked, right? Whenever ajax submits a step successfully to server and server confirms that data was valid, we store the current step in js, so we can display it later if user comes back to that step. Do you agree with this approach?

amcoho commented 6 years ago

Re 1: If it is safe to fetch next step (as indicated by presence of a data attribute, say, on form element) then it means it is safe. The decision of safety is made in the back-end.

Re 2: Yes, you save one round-trip to server. If server returns http 200 then you swap in the next step that you have pre-fetched.

Re 3: Yes. Again I suggest you work off a data attribute that tells you whether you can pre-fetch the previous step or not. This would make it more flexible and the implementation approach to both next and previous would be symmetrical.

smohadjer commented 6 years ago

@amcoho How are we saving one round-trip to server? We still need to post current step to server and wait until ajax response is received before deciding whether we can use the prefetched next step or not. We actually have one more ajax request in prefetch version!

smohadjer commented 6 years ago
  1. In which case we can not prefetch a previous step? Give me an example.

Now that I look at the whole thing what we have written is an ajax-based way of going from one page to another and it really has not much to do with forms. Same approach can be used by any Website so that the whole website works as a single-page app.

amcoho commented 6 years ago

We may not be able to pre-fetch a previous step in cases where data on previous step may change outside our control: say the user has a countdown airline arrival information on previous page.

amcoho commented 6 years ago

You are right about pre-fetching the next page. I had forgotten that on post we return the markup for the next page in response so having it as pre-fetched is of no additional help and actually costs an extra roundtrip.

amcoho commented 6 years ago

But it would be an optimization if you can determine that data on a form has not changed between retrieval from server and submit and instead of submit go to next page. It may introduce a lot of complexity though so we should evaluate whether it is worth it to implement such support.

smohadjer commented 6 years ago

I'm not sure this prefetching has any advantage at all. It seems that we can only use it when we "GET" a url, such as when we go back and forth in browser history. But in such cases if pages have not changed, ajax would get them from browser cache anyways, wouldn't it?

amcoho commented 6 years ago

No, XMLHttpRequest has nothing to do with browser history. It doesn't know it exists. Thank of it as a browser within a browser.

smohadjer commented 6 years ago

I think we should not over complicate things. Let's skip this for now and only implement prefetching when we notice delays. Even a little delay (less than a second) when an ajax request happens is not a bad thing as it tells you something is happening.

amcoho commented 6 years ago

Yes it can wait but we will definitely need it for previous steps since the user expectation is that browser back button operates fast. And with us putting markup together on the backend, it will be more than a few seconds of delay.

smohadjer commented 6 years ago

No, XMLHttpRequest has nothing to do with browser history. It doesn't know it exists. Thank of it as a browser within a browser.

But if ajax request returns a 304 response, then it will fetch the url from cache. That should happen pretty fast so I don't think prefetching in such cases makes a big difference.

amcoho commented 6 years ago

But ajax requests to server will never return 304.

Ajax request hits either form.php or xt_form.php and both of these have headers that say do not cache (otherwise PHP wouldn't re-execute)

With no-js back button will re-execute PHP but in js version with pre-fetching there is an opportunity to make back link not to re-execute the PHP.

amcoho commented 6 years ago

One correcdtion: XMLHttpRequest does not know about the browser history but it knows about browser cache.

smohadjer commented 6 years ago

But do you always need to re-execute php? If you know that data in a page has not changed can't you use a different header so that page gets cached?

amcoho commented 6 years ago

I can but then I cannot invalidate that cache when I need to, browsers are not respecting cache headers as they should.

You can easily test this yourself (and I think you should) as it will help you with your understanding of http protocol and behaviour of various browsers.

Write a hello world php page and chance cache headers on it and see how browsers behave. It will drive you crazy.

------ Original Message ------ From: "Saeid Mohadjer" notifications@github.com To: "smohadjer/formwizard" formwizard@noreply.github.com Cc: "amcoho" test123@webserverone.com; "Mention" mention@noreply.github.com Sent: 7/13/2018 12:15:17 AM Subject: Re: [smohadjer/formwizard] Add js pre-fetch for step before and after current step (#8)

But do you always need to re-execute php? If you know that data in a page has not changed can't you use a different header so that page gets cached?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/smohadjer/formwizard/issues/8#issuecomment-404747712, or mute the thread https://github.com/notifications/unsubscribe-auth/ANTieMnx0RpSUQrZjfWmj6525MsCd6wsks5uGEkFgaJpZM4VHDZl.

smohadjer commented 6 years ago

We may not be able to pre-fetch a previous step in cases where data on previous step may change outside our control: say the user has a countdown airline arrival information on previous page.

This is also true for next step, so even if we know that user has not changed anything when he clicks the next button, we still need to get the next step with ajax from server rather than simply going to next view inside the browser.