Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minibrowser: Add loading spinner #31713

Merged
merged 2 commits into from
Mar 26, 2024
Merged

Conversation

frereit
Copy link
Contributor

@frereit frereit commented Mar 17, 2024

I've started to implement a simple spinner that indicates when a page is loading. This PR is not complete yet but I'd like to get some feedback and discuss some implementation details if that's possible.

For this "MVP", I've simply added a new bool loading_changed analogous to the history_changed field in PumpResult::Continue. The WebView then keeps track of wether or not it is loading and exposes this via WebView::loading(), like WebView::shutdown_requested. The Minibrowser then gets a notification from the App when loading changed and updates the spinner accordingly.

A few questions arose while implementing this:

  • The comments in the code and issue indicate that EmbedderMsg::HeadParsed should also "influence" the loading state, but I do not understand how this should surface. In my understanding, the spinner simply shows up when the document starts loading and stops once it is complete. What is the intended "intermediary" step here?

EmbedderMsg::HeadParsed => {
// FIXME: surface the loading state in the UI somehow
},

  • It seems a bit clunky to add a xyz_changed for everything about the WebView that could be required to bubble up to the Minibrowser. For example, showing the Favicon might also require a favicon_changed: bool in the future. Perhaps it would make sense to combine all these into a toolbar_data_changed or metadata_changed or something and let the Minibrowser figure out what it has to do (or just refresh the entire toolbar when anything changed, that shouldn't really impact performance). Is this something I should implement in this PR?

  • These changes do not require tests because it is purely visual in the minibrowser.

@jdm
Copy link
Member

jdm commented Mar 17, 2024

What is the intended "intermediary" step here?

One common pattern I've seen is a slow spinner in one direction while the initial network request is in flight, then the spinner changes direction or speeds up when the beginning of the response is received. This corresponds to the HeadParsed event.

@delan delan self-requested a review March 18, 2024 09:39
@delan
Copy link
Member

delan commented Mar 18, 2024

What is the intended "intermediary" step here?

One common pattern I've seen is a slow spinner in one direction while the initial network request is in flight, then the spinner changes direction or speeds up when the beginning of the response is received. This corresponds to the HeadParsed event.

Yeah, HeadParsed happens somewhere between LoadStart and LoadComplete. It would be good to show these two periods differently, but if we can’t, then we should treat HeadParsed like LoadStart.

It seems a bit clunky to add a xyz_changed for everything about the WebView that could be required to bubble up to the Minibrowser. For example, showing the Favicon might also require a favicon_changed: bool in the future. Perhaps it would make sense to combine all these into a toolbar_data_changed or metadata_changed or something and let the Minibrowser figure out what it has to do (or just refresh the entire toolbar when anything changed, that shouldn't really impact performance). Is this something I should implement in this PR?

Good point! Since we only use our history_changed flag to check if we should run an egui update (and maybe update some Minibrowser fields), I agree that it would be good to combine them.

@frereit
Copy link
Contributor Author

frereit commented Mar 18, 2024

What is the intended "intermediary" step here?

One common pattern I've seen is a slow spinner in one direction while the initial network request is in flight, then the spinner changes direction or speeds up when the beginning of the response is received. This corresponds to the HeadParsed event.

Yeah, HeadParsed happens somewhere between LoadStart and LoadComplete. It would be good to show these two periods differently, but if we can’t, then we should treat HeadParsed like LoadStart.

Done. During the LoadStart -> HeadParsed period the spinner is now Color32::GRAY and the default white otherwise.

It seems a bit clunky to add a xyz_changed for everything about the WebView that could be required to bubble up to the Minibrowser. For example, showing the Favicon might also require a favicon_changed: bool in the future. Perhaps it would make sense to combine all these into a toolbar_data_changed or metadata_changed or something and let the Minibrowser figure out what it has to do (or just refresh the entire toolbar when anything changed, that shouldn't really impact performance). Is this something I should implement in this PR?

Good point! Since we only use our history_changed flag to check if we should run an egui update (and maybe update some Minibrowser fields), I agree that it would be good to combine them.

Done.

I've also changed the webview to always return need_present: true when the spinner should be active because the spinner is animated and requires regular redraws to not be choppy. Is this the idiomatic way to achieve this or should the redraw be requested some other way?

There are other data points in the toolbar that might need to be
updated. This commit prepares for that by generaliziing the
"history_changed" flag to a more generic "need_update" flag.

Signed-off-by: Frederik Reiter <hi@frereit.de>
Copy link
Member

@delan delan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work! One question…

ports/servoshell/minibrowser.rs Outdated Show resolved Hide resolved
@delan
Copy link
Member

delan commented Mar 25, 2024

I've also changed the webview to always return need_present: true when the spinner should be active because the spinner is animated and requires regular redraws to not be choppy. Is this the idiomatic way to achieve this or should the redraw be requested some other way?

This makes sense and seems good enough to me.

Copy link
Member

@delan delan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks!

@delan delan enabled auto-merge March 25, 2024 10:00
Signed-off-by: Frederik Reiter <hi@frereit.de>
auto-merge was automatically disabled March 25, 2024 16:29

Head branch was pushed to by a user without write access

@frereit
Copy link
Contributor Author

frereit commented Mar 25, 2024

Apologies for the format errors. Fixed.

@delan delan added this pull request to the merge queue Mar 26, 2024
Merged via the queue into servo:main with commit 585e0d6 Mar 26, 2024
9 checks passed
@frereit frereit deleted the 31689-loading-spinner branch March 26, 2024 19:25
ektuu pushed a commit to ektuu/servo that referenced this pull request Mar 28, 2024
* minibrowser: Rename "history_changed" flag to "need_update"

There are other data points in the toolbar that might need to be
updated. This commit prepares for that by generaliziing the
"history_changed" flag to a more generic "need_update" flag.

Signed-off-by: Frederik Reiter <hi@frereit.de>

* minibrowser: Add spinner to indicate loading status of the webview

Signed-off-by: Frederik Reiter <hi@frereit.de>

---------

Signed-off-by: Frederik Reiter <hi@frereit.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

servoshell: add a spinner that indicates when the page is loading
3 participants