Page MenuHomePhabricator

NewImpact: Create skeleton loading state
Closed, ResolvedPublic

Description

Because the impact module is rendered on the client side we need to have a skeleton or loading state to display before the JavaScript can execute.

Current (no loading state)Proposed skeleton design
image.png (1×934 px, 113 KB)
  • Design details:
    • Add skeleton loading behaviour in keeping with the same visual style and animation as the skeleton implemented in the Suggested edits cards (see T263040 and associate codepen).
    • Module height should be the same as final height once content is loaded.
    • Elements that should be available/appear on load (no progess loader required):
      • Scorecard background colour
      • Scorecard icons + labels
      • Section headings
      • Time period dropdown
      • “View all your edits” label (minus count)
    • Elements that will show as an ellipsis until replaced with the value (as per T236842):
      • Scorecard values
      • Count of all edits
    • Elements that will show as a block of Base80 colour “shimmering” while loading:
      • Recent activity value + bar chart
      • Views count with line chart
      • Top viewed articles thumbnails
    • Elements that will show as a block of Base70 colour “shimmering” while loading:
      • Top viewed article titles + view counts
  • Recent activity skeleton elements “shimmer” by changing opacity of Base80 background from 100% to 40%.
  • Most viewed articles list - thumbnail “shimmers” by changing opacity of Base80 background from 100% to 40%. Similarly, article title and views count changes from Base70 at opacity 100% to 40%. There is a cascade effect via animation-delay in subsequent article rows

(see same effect on T263040)

See also the Figma spec

Acceptance Criteria

  1. I should see a skeleton or loading state that doesn't cause the module box to grow in size when the JavaScript executes.
  2. ....
Completion checklist

Functionality

  • The patches have been code reviewed and merged
  • The task passes its acceptance criteria

Engineering

  • There are existing and passing unit/integration tests
  • Tests for every involved patch should pass
  • Coverage for every involved project should have improved or stayed the same

Design & QA

  • If the task is UX/Design related: it must be reviewed and approved by the UX/Design team
  • Must be reviewed and approved by Quality Assurance.

Documentation

  • Related and updated documentation done where necessary

Event Timeline

@RHo do we already have a design or component for this? If not, could you please create one?

kostajh triaged this task as Medium priority.Oct 27 2022, 11:30 AM
RHo updated the task description. (Show Details)

@RHo do we already have a design or component for this? If not, could you please create one?

Thanks @kostajh, I'll reuse the existing styles we have for welcome survey and article card loading and update the task.

RHo updated the task description. (Show Details)
RHo moved this task from 📗Backlog (Current sprint) to 💪In Progress on the Growth Design board.
RHo added a subscriber: Sgs.

Moving to Ready for dev – but also pinging @Sgs in anticipation of discussion about what is actually feasible to have on load vs my assumptions in this initial design :)

Moving to Ready for dev – but also pinging @Sgs in anticipation of discussion about what is actually feasible to have on load vs my assumptions in this initial design :)

Thanks for this design!

There are two stages of loading:

  1. The first stage of loading is on the server-side, where we output the markup for the module. If you disable JavaScript in your browser, you'll see how that looks:

image.png (1×1 px, 248 KB)

What we probably want here instead is a box that is sized for some expected height (which is impossible to say precisely, because it can vary by languages, and by number of articles). The contents for it could be a spinner or it could be the bars used in the skeleton design for this task, but we can't easily render the different cards/components on the server-side, without duplicating a lot of work.

  1. Once the JavaScript loads, there is then some period of time between the JS loading and the HTTP request to fetch the user impact data from the API. In "normal" scenarios where the data is already cached for the user, and with good network conditions, this should happen in let's say < 200ms. In this case, we can make use of the skeleton bars as provided in the design, until the data is loaded and rendered in the application.

So I guess the question is if we should try to accommodate what is happening in phase 1, before the JS loads, or just do something ultra minimal like setting a minimum height on the impact module box?

Moving to Ready for dev – but also pinging @Sgs in anticipation of discussion about what is actually feasible to have on load vs my assumptions in this initial design :)

Thanks for this design!

There are two stages of loading:

  1. The first stage of loading is on the server-side, where we output the markup for the module. If you disable JavaScript in your browser, you'll see how that looks:

image.png (1×1 px, 248 KB)

What we probably want here instead is a box that is sized for some expected height (which is impossible to say precisely, because it can vary by languages, and by number of articles). The contents for it could be a spinner or it could be the bars used in the skeleton design for this task, but we can't easily render the different cards/components on the server-side, without duplicating a lot of work.

  1. Once the JavaScript loads, there is then some period of time between the JS loading and the HTTP request to fetch the user impact data from the API. In "normal" scenarios where the data is already cached for the user, and with good network conditions, this should happen in let's say < 200ms. In this case, we can make use of the skeleton bars as provided in the design, until the data is loaded and rendered in the application.

So I guess the question is if we should try to accommodate what is happening in phase 1, before the JS loads, or just do something ultra minimal like setting a minimum height on the impact module box?

My inclination is your suggested minimal approach and setting a min height based on height of the contents when using default english copy, which seems to be ~786px.

The prior impact module was rendered on the server whereas the new one is rendered on the client. That means users will have to wait for Javascript to load on their browsers before seeing any meaningful content ( until Codex has SSR support T321356). The proposed design it seems it assumes we can display Vue components (the scorecards) in the server which is sadly not the case. On the other side if we implement this issue 100% in the client it would only cover for the data fetching waiting time (orange), leaving all the user in front of an empty box (screenshot 1) while JS loads.

Screenshot 2022-12-21 at 12.27.06.png (2×3 px, 409 KB)

If we don't want to get in the business of generating HTML in the server again my suggestion is that we create a CSS-only loader with some animation to cover the Javascript loading time. Also the concerns about content height mentioned in T323572#8484270 are somehow related since the possible vertical bumps happen when the user moves from the Javascript loading step to the data fetching.

The prior impact module was rendered on the server whereas the new one is rendered on the client. That means users will have to wait for Javascript to load on their browsers before seeing any meaningful content ( until Codex has SSR support T321356). The proposed design it seems it assumes we can display Vue components (the scorecards) in the server which is sadly not the case. On the other side if we implement this issue 100% in the client it would only cover for the data fetching waiting time (orange), leaving all the user in front of an empty box (screenshot 1) while JS loads.

Screenshot 2022-12-21 at 12.27.06.png (2×3 px, 409 KB)

If we don't want to get in the business of generating HTML in the server again my suggestion is that we create a CSS-only loader with some animation to cover the Javascript loading time. Also the concerns about content height mentioned in T323572#8484270 are somehow related since the possible vertical bumps happen when the user moves from the Javascript loading step to the data fetching.

👍

The prior impact module was rendered on the server whereas the new one is rendered on the client. That means users will have to wait for Javascript to load on their browsers before seeing any meaningful content ( until Codex has SSR support T321356). The proposed design it seems it assumes we can display Vue components (the scorecards) in the server which is sadly not the case. On the other side if we implement this issue 100% in the client it would only cover for the data fetching waiting time (orange), leaving all the user in front of an empty box (screenshot 1) while JS loads.

Screenshot 2022-12-21 at 12.27.06.png (2×3 px, 409 KB)

If we don't want to get in the business of generating HTML in the server again my suggestion is that we create a CSS-only loader with some animation to cover the Javascript loading time. Also the concerns about content height mentioned in T323572#8484270 are somehow related since the possible vertical bumps happen when the user moves from the Javascript loading step to the data fetching.

hi @Sgs - in the proposed design, I was had assumed in the scorecard section the background could be easily replicated and icons loaded up from CSS (since the same icons are on OOUI which I assume is already separately loaded). Same goes for text being shown in there already (like it is in the Suggested edits module when loading).
However, if this is not so easy to achieve, can the following simplified version be done instead:

image.png (1×1 px, 166 KB)

Change 879629 had a related patch set uploaded (by Sergio Gimeno; author: Sergio Gimeno):

[mediawiki/extensions/GrowthExperiments@master] User impact: add skeleton markup while javascript loads

https://gerrit.wikimedia.org/r/879629

Sgs changed the task status from Open to In Progress.Jan 16 2023, 8:14 PM
Sgs moved this task from In Progress to Code Review on the Growth-Team (Sprint 0 (Growth Team)) board.

Change 881406 had a related patch set uploaded (by Sergio Gimeno; author: Sergio Gimeno):

[mediawiki/extensions/GrowthExperiments@master] User impact: show skeleton while an api request is ongoing

https://gerrit.wikimedia.org/r/881406

Change 879629 merged by jenkins-bot:

[mediawiki/extensions/GrowthExperiments@master] User impact: add skeleton markup while JavaScript loads

https://gerrit.wikimedia.org/r/879629

Change 881406 merged by jenkins-bot:

[mediawiki/extensions/GrowthExperiments@master] User impact: show skeleton while an api request is ongoing

https://gerrit.wikimedia.org/r/881406

Etonkovidova subscribed.

Based on https://phabricator.wikimedia.org/T321675#8504932 - the simplified version for the Impact module skeleton was checked on betalabs; no issues were found. See the animated gif below:

impact_skeleton2.gif (745×1 px, 351 KB)

Checked in testwiki wmf.20 - the specs are in place (for the animated gif see the gif in this comment)

Screen Shot 2023-01-24 at 1.46.40 PM.png (1×2 px, 165 KB)