New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 790938 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner: ----
Closed: Feb 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 2
Type: Bug-Regression



Sign in to add a comment

`transitionend` not sent after CSS transition

Reported by jando...@gmail.com, Dec 1 2017

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5

Steps to reproduce the problem:
1. Load the app

What is the expected behavior?
After dissolve of the preloader, the page gets updated further

What went wrong?
Visualization of the page freezes completely, while the other code continues normally. An expected `transitionend` was not sent.

Did this work before? Yes Chrome 57

Does this work in other browsers? Yes

Chrome version: Version 62.0.3202.94 (Official Build) (64-bit)  Channel: stable
OS Version: OS X 10.13.1
Flash Version: 

Since Chrome v58, some Chrome process [sometimes (Mac) | very often
(Win)] goes haywire around a CSS transform transition. It now seems
plausible that this is a bug in Chrome, and not in our code. I did not
find any reference to this behavior in the known issues or on the web in
general. The closest is
[Some CSS transitionend events don't fire on Android devices without displays](https://bugs.chromium.org/p/chromium/issues/detail?id=781924).

The problem seems to go away when the CSS transform is removed.

It looks like some Chrome process (the render engine?) stops, or stops
communicating, with the net effect that Chrome stops updating the
visualization of a page, while other parts, e.g., JavaScript, XHR, …
keep working as expected.

The issue occurs in a private business application, during setup. To
demonstrate the problem, I created 2 screencasts, one for Mac, and one for
Windows, that show first a normal load, then several reloads, until the
issue occurs. In the screencasts the developer tools are used to inspect
some properties. Finally, after several minutes, Chrome shows a message.
During the screencast, you'll see me record a heap snapshot and timeline.
These are attached.

- Mac: [https://youtu.be/DVxRp6h4OAQ]
- Windows: [https://youtu.be/y7DcZ-DelcE]

Context 
-------

The issue occurs at least in 2 different SPAs, that share common code. I
will discuss the simplest one. These SPAs are built with dojo, dijit,
dojox, util, currently at version 1.13.0; put-selector 0.3.6; xstyle
0.3.2; the simple SPA discussed here uses dgrid 0.3.19. The debugging
effort, and evolution of the code since the issue surfaced, makes it
unlikely that the issue is related to these libraries. This is a large
application, that contains complex JavaScript code, and shows it's age.
It is not impossible that our code has issues, but even then, the
behavior of Chrome is not what it should be. Our code ends nominally,
continuing long after the issue occurs.

The issue immediately occurred when Chrome 58 was released, and can be
reproduced on Win and Mac, although much more easily on Win than Mac.
This issue does not occur on Firefox, Safari, or Edge, on Win nor Mac.
On Windows, the issue occurs so often that using Chrome has become
impossible for the users.

Description of the issue 
------------------------

### Normal behavior

The screencasts first show me loading the SPA with normal results. The
SPA starts out with a preloader. Debugging shows this is where the issue
is. Behind the preloader, dojo parses its templates, and populates the
DOM. When the layout is ready, the preloader is removed, and we see the
SPA layout (Mac: 00:13, Win: 00:16 in the screencast). There does not
seem to be an issue with this.

The SPA is split in a left and a right side. For the purposes of this
issue, the right hand side is inert.

On the left hand side, we see a list with paging. When the preloader
dissolves, an XHR is already busy getting information from the server
for the first page. Deserialization of this data is rather involved, and
uses a queuing mechanism to leave CPU time for user interaction. The
console shows log information about the deserialization process. During
initial load, we see a loading message in the left hand pane, and a
turning busy indicator. The busy indicator is an animated gif, attached
via CSS. At the bottom, there is a slim blue progress indicator, that
shows the depth of the queue.

When the data for the first page is deserialized, it is handed to the
list, and rendered. The loading message and busy indicator are replaced
with the list entries for the first page (Mac: 00:15, Win: 00:18).

In the console you can see that logging continues: the lists preloads a
second page after the first page is rendered. The bottom slim blue
progress indicator jumps up a second time. This goes on for some
seconds.

After that, all JavaScript is done, and the SPA is waiting for user
input (Mac: 00:19, Win: 00:24).

In the screencast, you see me opening the Elements inspector, and
drilling down in the DOM to show the elements of the first item of the
list (Mac: 00:37, Win: 00:48). These were added by the JavaScript code
after the page got loaded. Also note that we see rectangles in the
Chrome window that show which elements I am hovering over with my mouse
in the Elements inspector.

Note that The first element in the body is
		<div id="fixedSplitter" …

Notably, there is no `<div id="preloader" …` in the body at this time.
The preloader originally is

		<div id="preloader"><div class="progress"><div></div></div></div>

with CSS 

[https://github.com/peopleware/js-ppwcode-util-oddsAndEnds/blob/fe7ff76108fc4a1ce463a317f05009de2694258f/preloader/preloader.css].

The css makes the div page filling, and on top, with a CSS loading indicator.
Transitions are setup for dissolving the preloader when the page is loaded. 
Dissolving happens by adding CSS class "dissolved" to the "preloader" div.

		#preloader {
		  […]
		  transition: all 0.75s linear;
		}

		#preloader.dissolved {
		  opacity: 0;
		  transform: skewx(90deg) rotate(-90deg);
		}

		[…]

		#preloader.dissolved .progress {
		  display: none;
		}

The code listens to "transitionend" to finally remove the `preloader`
div and its contents from the DOM.

    function dissolvePreloader(/*String*/ preloaderId) {
      var deferred = new Deferred();
      var preloader = dom.byId(preloaderId);
      var spinner = query(".progress", preloader)[0];
      preloader.addEventListener(
        "transitionend",
        function() {
          domConstruct.destroy("preloader");
          deferred.resolve(preloaderId);
        },
        true
      );
      domClass.add(preloader, "dissolved");
      return deferred.promise;
    }

Debugging shows the listener is activated 3 times, for font-size,
opacity, and transform. (In hindsight, this is not optimal code, but it
is the code currently that shows the issue, which occurs before the
listener is triggered.)

### Getting the issue to occur

Next in the screencast, you will see me reloading the page several
times, trying to get the issue to occur. I do not always wait for the
page to load completely. As soon as I can see that the issue isn't
occurring, I try again. And sometimes I don't even wait that long, based
on the feeling that 'taxing' the browser more heavily will force the
issue quicker. There is no scientific evidence for that, there are even
more hints to the opposite, so that is purely emotional.

On Mac, it takes about 10 minutes of continuously reloading for the
issue to occur. I've edited most attempts out of the screencast. On
Windows, it only takes a couple of tries.

The issue occurs on 01:26 in the Mac screencast, and on 01:43 in the
Windows screencast.

### Behavior when the issue occurs

The SPA starts out with the preloader, and parses and renders the layout
behind it, as with the normal behavior. The preloader dissolves as
expected (Mac: 01:25, Win: 01:42).

We see the layout, with the inert right hand side, and the list at the
left, showing the loading message and the animated gif busy indicator.

THE ANIMATED GIF IS NOT TURNING.

**From this time on, the contents of the Chrome tab is completely
frozen.**

In the console we can see that the JavaScript continues normally. We see
the initial log messages, the deserialization of the first page, and,
seconds after the preloader dissolved, the start of the second page load
and its deserialization, up to completion as with the normal runs (Mac:
01:31, Win: 01:52).

**The visual representation however did not change after the preloader
dissolved.**

_In the mean time, the ventilators in my computer have started._

In this phase, nothing seems to be going on in the SPA, yet we see a
rather high CPU usage of Chrome (and the Chrome DevTools).

I now have some minutes to do some inspections.

In the screencast you see me opening the Elements inspector, and
drilling down in the DOM to show the elements of the first item of the
list. **THE DOM IS FILLED OUT (except for the preloader, see below), YET
IT IS NOT SHOWN IN THE CHROME WINDOW.** Also note that no rectangles are
shown in the Chrome window as I hover over elements in the Elements
inspector. (Mac: 02:05, Win: 02:18)

The first element in the body is `<div id="preloader" …`. The second is 
`<div id="fixedSplitter" …`.

When I do a recording in the Performance tab, we see that no code is
active, apart from some GPU blibs. The heap snapshot and timeline you
see me make are attached.

**Debugging shows that the PRELOADER EVENT LISTENER IS _NEVER_ CALLED,
although clearly THE TRANSITION WAS EXECUTED**. The preloader visual is
gone, it did so with the transitions (see screencast), and the style of
the preloader div is "dissolved" afterwards, yet it is not removed from
the DOM. **For some reason, the process doing the CSS transition never
sent the `transitionend` event.**

### The aftermath

After several minutes waiting for the grand finale, I give up, and start
to interact.

After several minutes, on Windows, Chrome does come up with an 'Aw,
Snap!' and 'Debugging Connection was closed. Reason: Render process
gone. […]'. When I close the Chrome Windows, I can start over. (Win:
07:34)

On Mac, things are more dire. The wait for a message takes much longer
(up to over 15 minutes - most of this is edited), and when it gets there
it shows 'Page Unresponsive - You can wait for it to become responsive
or exit the page. […]'. (Mac: 06:33) The reason that this takes longer
might be that the Macs I work on have a lot of RAM, while the Windows
machine has less. In any case, on Mac, the ventilators are doing
overtime by now, although this doesn't really show in the CPU load. Over
the next minutes, the Mac becomes more and more sluggish. In the
recording of this screencast, the end is not shown. At the end, I am
desperately trying to kill Chrome, to be able to save the screencast,
but that is almost impossible. Over different tries, I observed that the
longer I wait, to more difficult it becomes to interact with the machine.

My hypothesis here is that it is not CPU, but memory that is at the
heart of this effect. Although little seems to be going on, something in
Chrome seems to consume more an more RAM, to the point of making the OS
trash.

I have had one occurence where this experience actually crashed the
machine as a whole.

### Workaround

We removed the `transform` transition, and made the `transition` slower in the CSS.
The issue has not occurred again since the change.

[https://github.com/peopleware/js-ppwcode-util-oddsAndEnds/blob/17d7d9e8ae517ba14ba247ffe5bf06d9aca670ec/preloader/preloader.css]

		#preloader {
		  […]
		  transition: all 2s linear;
		}

		#preloader.dissolved {
		  opacity: 0;
		}

### Hypothesis

For some reason, the Chrome rendering process goes into some endless
recursion when a transition is executing or done, before `transitionend`
can be signalled. It doesn't process changes to the DOM anymore, but
keeps slugging on, consuming a small amount of RAM on every turn.
Finally, something detects this on Windows, and stops the silliness. On
Mac, this detection is less advanced, so things get out of whack further.

I have no hypothesis why the issue occurs far more frequent on Win than
Mac.
 

Comment 1 by jando...@gmail.com, Dec 1 2017

Comment 2 by jando...@gmail.com, Dec 1 2017

Snapshots.zip
19.4 MB Download
Labels: Needs-Bisect
Cc: krajshree@chromium.org
Labels: Triaged-ET Needs-Triage-M62 Needs-Feedback
Tried testing the issue on mac 10.12.6 using chrome reported version #62.0.3202.94 by navigating to url: https://test.pictoperfect.com/ui/index.html, but logging into the page require credentials.

jandockx@ - Could you please provide sample credentials to test the issue from TE-end. This will help us in triaging the issue further.

Thanks...!!

Comment 5 by e...@chromium.org, Feb 1 2018

Status: WontFix (was: Unconfirmed)
Closing due to inactivity and inability to reproduce.

Sign in to add a comment