Page MenuHomePhabricator

Visible glitch when switching page (flushCssBuffer makes the page blink at every page change)
Closed, ResolvedPublicBUG REPORT


Steps to Reproduce:

  • Go to EN Wikipedia home page
  • Click a link

Actual Results:

  • When switching page, the whole page loads, then blinks, and then loads

See on the timeline (the screenshots), there is a moment on the screenshots where you can see that the page content is gone.
This seems to be caused by the call to flushCssBuffer function.

Expected Results:

  • The page should not blink

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald TranscriptOct 9 2019, 2:46 PM

Confirmed on latest Chrome Stable for Android and on Kiwi Browser (Chromium-based)

Aklapper added a subscriber: Ebraminio.

Hi @Serpnmwiki, thanks for taking the time to report this and welcome to Wikimedia Phabricator!

Is this about the mobile version (as your screenshot shows ""), or about the desktop version (no "m" in the URL)?

Which exact version of Chrome is used? ("latest stable" changes every few weeks and does not mean much...)

@Ebraminio: Might be another Chrome bug? :-/

Nice bug report! Can repro here in Firefox also so isn't Chrome specific.

Ammarpad added a subscriber: Ammarpad.

This is about mobile version on mobile device. I noticed this earlier today and was planning to fully confirm it and report.

@Ebraminio: Might be another Chrome bug? :-/

I don't think so. I noticed it first on UC browser

Thanks everybody, didn't test myself as I have no machine running Android OS

Peter added a subscriber: Peter.Oct 13 2019, 6:50 PM

I could reproduce this on my Mac on Safari (13.0.2) on and also on Firefox 70.0b14. Attaching a video of what it looks like.

On Chrome it isn't as obvious (at least for me).

Interesting to see that Desktop platforms are affected as well.

I suspect it could change whether the content is cached or not as well (which could mean that it's a race condition in the order of the execution of the JS ?)
You can try on Kiwi Browser for Android for example (which has essentially cache disabled).

Not to be too pushy, but this issue significantly impacts user experience in my opinion.

The flushCssBuffer function is an internal ResourceLoader method that applies stylesheets bundled with a JS-loaded module.

It's possible that it has a bug, but it's also possible the glitch is the result of actual stylesheets delivered by a particular module. The reason the glitch appears later and then disappears again could be due to another module loading later that corrects the styles again.

This can happen because ResourceLoader adheres to the dependency tree when applying JS-styles and scripts. If there are three JS modules that each bundle styles, and have a linear relationship like A > B > C, then their styles and scripts will be executed as A-CSS/JS > B-CSS/JS > C-CSS/JS. For performance reasons we don't block the main thread from start to end of the JavaScript pipeline, instead between independently valid chunks, we allow the browser to breath (e.g. to react to user input such as scrolling the screen, selecting text, typing etc.).

In general, JS modules should never deliver styles that affect the HTML from the server, as this would cause a FOUC (Flash of unstyled content). If instead of zero such modules, there are 2+ such modules, then the rendering between those two modules can become visible.

If we can figure out which styles flushCssBuffer is inserting at this point, we might be able to pinpoint the cause and/or rule it out.

Krinkle moved this task from Inbox to Backlog: Future Goals on the Performance-Team board.
Krinkle moved this task from Backlog: Future Goals to Radar on the Performance-Team board.
Krinkle edited projects, added Performance-Team (Radar); removed Performance-Team.
Peter added a comment.Oct 14 2019, 6:45 AM

I'm not sure but on WebPageTest we got the full screen donate at around the same time so maybe it's related?

This has very similar symptoms as T234599: Flash of MinervaNeue empty main menu animation on page load

The problem with inspecting what flushCssBuffer adds to the page is that ResourceLoader will often have a lot of stylesheets queued up and inserted at once. So that's a lot of CSS being inserted at the same time and it's really a needle in a haystack to find which styles cause the issue. This is where I got stuck on the other task and I was finally able to isolate the issue because there was a suspicious change in the recent commits that I was able to A/B test.

Maybe in some debug mode flushCssBuffer should only add one stylesheet or module at a time so we could isolate such FOUC-like issues more easily when debugging manually.

Considering that this was reported on Oct 9 for enwiki, this might suggest that it went out with 1.34.0-wmf.25. It's probably worth starting to look at those:

Gilles triaged this task as Unbreak Now! priority.EditedOct 15 2019, 9:07 AM

I can definitely see a flash on Chrome too:

Restricted Application added a subscriber: Liuxinyu970226. · View Herald TranscriptOct 15 2019, 9:07 AM
Gilles added a comment.EditedOct 15 2019, 9:49 AM

The flash is caused by some CSS added to the page that is shortly "corrected" by JS soon after. Presumably the CSS and JS come from the same module. I suspect that whoever wrote this assumed that this relationship between the CSS and JS in question was atomic, when it isn't.

I was able to pause the browser's execution in the broken state by adding a breakpoint on JQuery's addClass method:

It seems like this broken visual state gets fixed by JS adding the class "mw-ui-icon" to 40 elements (!).

Inspecting the HTML/CSS in its broken state, it's the <header> element covering the content of the page entirely:

Debugging step-by-step, I'm able to catch which element getting the "mw-ui-icon" class added by JS fixes the layout. It's the "Open main menu" icon on the left:

Digging further up in the callstack, it all comes from this baffling function:

mw.loader.implement("",function($,jQuery,require,module){var $icons=$('.mw-ui-icon').removeClass('mw-ui-icon');setTimeout(function(){$icons.addClass('mw-ui-icon');},0)},null,null,null);;

Which seems to remove the existing class (maybe it was originally in the DOM, then??). Only to add it back after a setTimeout, making sure that the browser has enough time to render a broken frame :)

Where is this insanity coming from? Well:

Seems like someone forgot to remove this... T233521: Language selector and edit button icon not displayed on first load in iOS 13

Can someone with the required edit rights on enwiki nuke MediaWiki:Mobile.js ASAP? Thanks...

Gilles closed this task as Resolved.Oct 15 2019, 9:59 AM
Gilles claimed this task.
Gilles added a subscriber: Jdlrobson.

Verified the fix, I no longer see flashing content.

Thanks everyone for their contribution. I can confirm that the issue appears to be resolved.

Thanks for taking care of this @Gilles and @Krinkle and sorry for confusion this caused. Thanks @Serpnmwiki for reporting.

Which seems to remove the existing class (maybe it was originally in the DOM, then??). Only to add it back after a setTimeout, making sure that the browser has enough time to render a broken frame :)

Yeh it was a super strange bug that we never got to the bottom to relating to iOS and background-size cover. It would sometimes render the image and sometimes not, but forcing a repaint by re-adding the class made the issue go away...🤷