Page MenuHomePhabricator

[Bug] Changing gallery images causes an abrupt and jarring white flash
Closed, ResolvedPublic5 Estimated Story Points

Description

In several places it is possible for a white jarring flash to occur. The problem occurs due to how overlays are managed by MobileFrontend's OverlayManager

To understand the cause of the flashes it is important to first understand how the image overlay works.

The lifecycle

Typical life cycle of image overlay:

  1. User makes request to load image overlay via a change in the URL e.g. https://reading-web-staging.wmflabs.org/wiki/Stephen_I_of_Hungary#/media/File%3APortrayal_of_Stephen_I%2C_King_of_Hungary_on_the_coronation_pall.jpg
  2. The ImageOverlay code is downloaded via a transparent pane e.g.

Screen Shot 2018-08-15 at 3.27.38 PM.png (351×1 px, 99 KB)

  1. The OverlayManager checks the current route for a matching overlay that has been added inside a overlayManager.add call
  2. If a match, the callback is invoked, returning a Deferred object. When that deferred resolves, it resolves with an overlay which is then rendered in the display
  3. The ImageOverlay renders with a spinner

Screen Shot 2018-08-15 at 3.22.36 PM.png (356×698 px, 18 KB)

It fires a request to the api to obtain information about the image associated in the URL at a resolution matching the current display [[ e.g. https://en.m.wikipedia.org/w/api.php?action=query&format=json&prop=imageinfo&titles=File%3AStephen_I%27s_birth_(Chronicon_Pictum_037)%2Ejpg&formatversion=2&iiprop=url%7Cextmetadata&iiurlwidth=1280&iiurlheight=640 | example ]]

  1. When the API request returns, the image is downloaded. When the image finally finishes downloaded, the spinner is replaced with the image
  2. The image is readjusted based on the available space.
  3. When the user clicks the next/previous icons a new request is made (move to step 1)

The problem

There are two problematic flashes here.

  1. Inside the callback. Steps 1-3 are always performed asynchronously due to the way the code is setup in Minerva.

https://gerrit.wikimedia.org/r/448019 dealt with this part of the problem.

flash1.gif (556×641 px, 393 KB)

  1. In steps 5-7 with the callback problem removed the switch from a spinner to an image is jarring due to the asynchronous replacement of the existing image (5-6) and then the image adjustment (step 7)

flashes.gif (556×641 px, 652 KB)

Replication of problem 1

You'll notice a white flash with each arrow click.
Notice how with https://gerrit.wikimedia.org/r/448019 this flash disappears.

Replication of problem 1+2 combined

Steps to Reproduce

  1. Go to https://reading-web-staging.wmflabs.org/wiki/Barack_Obama#/media/File%3AObama_Macri_October_2017.jpg
  2. Press the previous button

Expected Results

  • The gallery gracefully animates preloaded images in

Ex: https://mobile.twitter.com/Oniropolis/status/998898880459804672

Actual Results

    • The gallery unconditionally shows the spinner then immediately blasts it down with a massive white flare brighter than a thousand suns before begrudgingly and gutturally smashing the image in place:
      THESUN.gif (526×501 px, 2 MB)
  • When the image is initially opened from a page there is a flash of the top of the article right before the image loads. Check out this screen recording (Alex extended the frame where the top of the article flashes):

Environments Observed

  • enwiki

Browser Version

  • Chromium v66.0.3359.181

OS Version

  • Ubuntu v18.04 64b

Device Model

  • Desktop

Device Language

  • English

Developer notes

The issue here is the asynchronous nature of the method loadImageOverlay and the synchronous nature of hiding an overlay.
Currently the media viewer route when invoked will make an async call to loadModule( 'mobile.mediaViewer' ) which will eventually resolve to an ImageOverlay (read about the JavaScript Eventloop if it's not clear why this is a problem)

Code: https://github.com/wikimedia/mediawiki-skins-MinervaNeue/blob/master/resources/skins.minerva.scripts/init.js#L108

To remedy this we'll want to make the mediaViewer synchronous every time the module has already been loaded
e.g.

		} else if ( mw.loader.getState( 'mobile.mediaViewer' ) === 'ready' ) {
			return makeOverlay( title );
		} else {
			return loader.loadModule( 'mobile.mediaViewer' ).then( function () {
				return makeOverlay( title );
			} );
		}

I've verified that this does indeed solve the problem.

QA notes

  • Screen sizes to test: desktop & mobile
  • Browsers to test on: Safari & Chrome
  • Skin to use: Minerva
  • Environment to test in: staging
  • Steps:
    1. go to any page with multiple images (e.g. https://reading-web-staging.wmflabs.org/wiki/Gorilla?useskin=minerva)
    2. open an image and use the prev/next arrows to click through a bunch of images
    3. compare this experience with how it looks in production
    4. verify that the white flash you see in production is not present in staging

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

Additionally, I noticed that when you initially open an image from a page there is a flash of the top of the article right before the image loads. Check out this screen recording (I extended the frame where the top of the article flashes):

ovasileva set the point value for this task to 3.Jun 19 2018, 4:35 PM
Vvjjkkii renamed this task from [Bug] Changing gallery images causes an abrupt and jarring white flash to 13aaaaaaaa.Jul 1 2018, 1:04 AM
Vvjjkkii raised the priority of this task from Medium to High.
Vvjjkkii removed the point value for this task.
Vvjjkkii updated the task description. (Show Details)
Vvjjkkii removed a subscriber: Aklapper.
CommunityTechBot renamed this task from 13aaaaaaaa to [Bug] Changing gallery images causes an abrupt and jarring white flash.Jul 2 2018, 12:27 PM
CommunityTechBot lowered the priority of this task from High to Medium.
CommunityTechBot updated the task description. (Show Details)
CommunityTechBot set the point value for this task to 3.
CommunityTechBot added a subscriber: Aklapper.

Change 448019 had a related patch set uploaded (by Jdlrobson; owner: Jdlrobson):
[mediawiki/skins/MinervaNeue@master] Avoid abrupt and jarring white flash in media viewer

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

Change 450185 had a related patch set uploaded (by Jdlrobson; owner: Jdlrobson):
[mediawiki/extensions/MobileFrontend@master] WIP: Use placeholders rather than spinner in image overlay

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

Jdlrobson subscribed.

I'll follow up with @Niedzielski to make sure this task is well defined/scoped and reprioritised and estimated as necessary.

I'll follow up with @Niedzielski to make sure this task is well defined/scoped and reprioritised and estimated as necessary.

@Jdlrobson @Niedzielski was there any further follow up we did on this that should be placed in the card?

@nray, I don't think so. I'm just as frustrated as anyone with the state of some of our fundamental UI components on mobile like the gallery or the really confusing "power off" / logout button in the menu and would like to see an overhaul which isn't really fair to pin on this task.

Change 448019 abandoned by Jdlrobson:
Avoid abrupt and jarring white flash in media viewer

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

Change 448019 restored by Jdlrobson:
Avoid abrupt and jarring white flash in media viewer

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

Jdlrobson removed the point value for this task.Aug 15 2018, 10:42 PM
Jdlrobson updated the task description. (Show Details)
Jdlrobson removed a project: Patch-For-Review.

Since there was initial confusion on this ticket, I've had a go at adding more detail. I've removed the points so it can be estimated again.

Preliminary estimations via Slackbot for this work were 2 5s (Nick+Stephen) and 1 8 (me). Let's talk about in person.

Jdlrobson set the point value for this task to 5.Aug 21 2018, 4:36 PM
Restricted Application changed the subtype of this task from "Deadline" to "Task". · View Herald TranscriptAug 21 2018, 4:36 PM

Change 455731 had a related patch set uploaded (by Nray; owner: Nray):
[mediawiki/extensions/MobileFrontend@master] Fix jarring white flash bug on image gallery

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

So I think the white flash from steps 5 - 7 is actually caused by the white background color CSS set on the image being rendered before the image loads. You can see a red flash if you set the background color to red like in this video:

red-image-overlay.gif (884×1 px, 2 MB)

I tried to address that by (mainly) setting the white background color only until after the image load event and adding transition effects. I think this is a major improvement and it seems to help in the majority of cases but I still notice a more subtle white flash sometimes on some loads of some browsers (Firefox for example). In Firefox, it might be related to this:

https://bugzilla.mozilla.org/show_bug.cgi?id=626613

Overall though, I think the remaining sporadic white flash (not addressed by my patch) is just due to the way browser is rendering the image and is a difficult problem to fully eliminate. That is why I am moving this to code review to see if what I have is sufficient.

My patch to address the image flash is here:

https://gerrit.wikimedia.org/r/#/c/mediawiki/extensions/MobileFrontend/+/455731/

Jon's patch to address the async overlay script load is here. I don't have much to add to Jon's latest patch so I'm inclined to +2 unless anyone objects:

https://gerrit.wikimedia.org/r/#/c/mediawiki/skins/MinervaNeue/+/448019/

Change 455731 merged by jenkins-bot:
[mediawiki/extensions/MobileFrontend@master] Fix jarring white flash bug on image gallery

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

Change 448019 merged by jenkins-bot:
[mediawiki/skins/MinervaNeue@master] Avoid abrupt and jarring white flash in media viewer

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

alright, so from what I can tell:

  • on desktop (Mac OS, Chrome & Safari), and mobile (Android, Chrome) there is no longer a while flash when switching between gallery images (hooray!!)
    • I am seeing a flash still when I first open an image, although I'm not sure if that is within the scope of this ticket. It seems like this might be due to the page jumping to the top before rendering the image in the overlay. Here is a video and a screenshot at 0:09 of the page jump/flash:
Screen Shot 2018-08-29 at 1.22.03 PM.png (934×1 px, 680 KB)
  • on mobile (iOS, Chrome & Safari) I'm still seeing a flash when switching between images (as well as the one that appears when I first open an image). It does seem less intense than the flash when switching between images on production, so perhaps it's partially working.

I am seeing a flash still when I first open an image, although I'm not sure if that is within the scope of this ticket. It seems like this might be due to the page jumping to the top before rendering the image in the overlay. Here is a video and a screenshot at 0:09 of the page jump/flash:

This is somewhat related to T201687 and out of scope for this ticket. It applies to editor overlay too.

on mobile (iOS, Chrome & Safari) I'm still seeing a flash when switching between images

Slowing down the video @ ~ 4s and ~6s mark I see:

Screen Shot 2018-08-29 at 11.49.17 AM.png (578×499 px, 24 KB)

Do we know what's causing that?
I'm guessing it's the image before loaded. Would it help if the background of that was transparent/black?

I am seeing a flash still when I first open an image, although I'm not sure if that is within the scope of this ticket. It seems like this might be due to the page jumping to the top before rendering the image in the overlay. Here is a video and a screenshot at 0:09 of the page jump/flash:

This is somewhat related to T201687 and out of scope for this ticket. It applies to editor overlay too.

on mobile (iOS, Chrome & Safari) I'm still seeing a flash when switching between images

Slowing down the video @ ~ 4s and ~6s mark I see:

Screen Shot 2018-08-29 at 11.49.17 AM.png (578×499 px, 24 KB)

Do we know what's causing that?

Yes, it's the background color of the image that we set with CSS. This patch tried to defer setting that until after the image load event (assuming the image is rendered beforehand) and it seems to work in a lot of the browsers I tested but as Alex's video shows some browser's will sometimes still paint the background color of the image before painting the image which produces this remaining flash. When I tested iphone in browserstack this happened occasionally but not on every image load. I'm curious how consistently it happens on Alex's phone out of ten times.

I'm guessing it's the image before loaded. Would it help if the background of that was transparent/black?

If we made the background color transparent that would certainly eliminate the issue but I believe we set the background white to make images with transparent backgrounds and black foregrounds visible. E.g. If we removed this CSS rule, this image would not be visible: http://localhost:8080/wiki/Barack_Obama#/media/File%3ABarack_Obama_signature.svg

You could also argue that we are already making images with transparent backgrounds and white foregrounds not visible by setting the background of the image to be white, but I'm not sure how often that scenario comes up.

Change 456212 had a related patch set uploaded (by Nray; owner: Nray):
[mediawiki/extensions/MobileFrontend@master] Remove remaining white flicker from image overlay load

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

@alexhollender Another attempt at this has now been deployed to staging. Can you please test with your iphone again? I added a transition delay for the white background to appear .15s after the image loads in hopes this will eliminate the white background appearing before the browser paints the image (which causes that flash).

Let me know if that helps

Change 450185 abandoned by Jdlrobson:
WIP: Use placeholders rather than spinner in image overlay

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

@alexhollender Just fyi, I noticed my latest revision that was previously on staging is no longer there. No rush, just let me know when you are ready to review this again, and I can tell Jon to put it on staging again.

Change 456212 merged by jenkins-bot:
[mediawiki/extensions/MobileFrontend@master] Remove remaining white flicker from image overlay load

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

alexhollender_WMF added a subscriber: Jdrewniak.

As far as I can tell the white flash is no longer occurring. I'm adding QA instructions and moving this over to QA.

A followup note @Jdlrobson @Jdrewniak @Niedzielski @nray:
Removing the white flash helps the image transition feel more smooth, however I think there's more we can do to make it feel even smoother. There are a number of visual aspects to our image transitions that each, subtly, contribute to the feeling of the transition being more/less smooth. This is the transition with the new patch:

image transition.jpg (1×3 px, 987 KB)

After a quick browse around it seems like the smoothest image transition pattern that exists is the images sliding seamlessly, e.g:

We have the slight added complexity of also transitioning the information in the infobox below the image, but if someone is keen to take this on I'm happy to make a ticket ;) I think it would roughly look like this:

image transition - slide.jpg (1×2 px, 987 KB)

I am not sure if I am seeing the right thing. But I don't see much difference between production and staging. There is no while flash appearing for me when I checked the gallery on production. I will have to confirm this with @Jdlrobson next week.

@Ryasmeen I am in the kitchen if you need my help, but the problem here is that the change has been live in production for some time. I would advise comparing staging to the gif in the project description!

@Jdlrobson: ah! well in that case it's definitely been fixed. Not seeing those weird white flash on my testing on staging and production.

Looks good, white flashes all gone!