Skip to content
This repository has been archived by the owner on Jul 24, 2018. It is now read-only.

Possible map panning jank #9

Open
andygup opened this issue Apr 5, 2016 · 17 comments
Open

Possible map panning jank #9

andygup opened this issue Apr 5, 2016 · 17 comments

Comments

@andygup
Copy link
Collaborator

andygup commented Apr 5, 2016

I think I'm seeing map panning jank. Need to compare ionic map with plain old cordova map on same device.

@andygup
Copy link
Collaborator Author

andygup commented Apr 5, 2016

After a some more rudimentary testing, it's not clear if the touch event isn't being registered or if actual jank is occuring. Need to frame the test better and compare against the on-device performance stats.

@andygup
Copy link
Collaborator Author

andygup commented Apr 5, 2016

CPU profile while panning. Need to compare to plain old cordova map:

image

@andygup
Copy link
Collaborator Author

andygup commented Apr 5, 2016

Compared to plain old cordova map (POCM), ionic uses a lot more baseline CPU. POCM baseline is ~1.5% and panning/zooming uses between 45% - 50% CPU compared to between 50% - 60% with ionic. These numbers are not definitive, just an initial investigation into performance.

image

Here's a snapshot of the CPU baseline for POCM:

image

In comparison, here's the baseline CPU for ionic. User processes bouncing above 20%:

image

@andygup
Copy link
Collaborator Author

andygup commented Apr 5, 2016

Short term memory usage looks stable for both POCM and Ionic, no obvious memory leaks. Only thing I noticed was the Window usage was 2x greater for ionic. Not too surprising considering the size of the angular library in comparison to the POCM sample.

Heap size analysis. POCM:

image

Ionic heap dump:

image

@andygup
Copy link
Collaborator Author

andygup commented Apr 6, 2016

Map performance has pretty much returned to almost normal while using JSAPI v3. Baseline CPU is tad higher than POCM, most likely due to Angular overhead, but it's bouncing between 0% - 3%.

This is still better than the idling CPU usage seen with the JSAPI 4 beta and the shark's tooth pattern that spiked at 10%+.

@andygup
Copy link
Collaborator Author

andygup commented Apr 6, 2016

After a bit more testing, I'm going to say the performance with JSAPI v3 is 'as to be expected' for a simple app.

I'm going to recommend we create a slightly more complex app that loads up the browser with features and uses renderers to twist the performance a bit.

@andygup
Copy link
Collaborator Author

andygup commented May 4, 2016

Testing update for fullpage.html for JSAPI v3.16.

Minor jank occuring at touchstart. Significant CPU usage while panning and zooming.

User agent: Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MOB30D; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/50.0.2661.86 Mobile Safari/537.36

image

@andygup
Copy link
Collaborator Author

andygup commented May 4, 2016

Testing update for plain old Cordova app running JSAPI v3.16 using same user agent on WebView.

Just by eye-balling it doing panning and zooming there is a tad less jank and peak CPU about 10% less.

image

@andygup
Copy link
Collaborator Author

andygup commented May 4, 2016

Memory footprint analysis using same device as above - memory usage not acceptable when compared to other non-Ionic Cordova apps.

Memory headroom < 250KB. This may be part of the reason I'm seeing performance issues. I suspect with that little headroom and non-existent garbage collection that there is a lot of memory-to-memory copying going on and that's consuming extra CPU during map operations such as panning and zooming.

image

In comparison, here's what I'd consider a more normal memory footprint. In the screenshot below the app consumes memory and there is a GC at regular but not excessive intervals.

image

Here's an example of a normal GC that occurred when the app had about 450KB remaining in head room:

image

@andygup
Copy link
Collaborator Author

andygup commented May 13, 2016

Well I tried to take a look at this as a memory snapshot and ran into a possible Chrome bug. I'll try again next week, and maybe I'll get a response back from the Chromium folks by then.

@andygup
Copy link
Collaborator Author

andygup commented May 23, 2016

@jwasilgeo My Chrome memory profiling tools are working again after the last couple Chrome updates.

We know that Cordova + JS API by itself works just fine. I can only conclude that there is something to do with how Angular and the JS API are interacting that is hosing performance.

I was able to get a quick memory profile snapshot and dig around for a minutes. This is by no means conclusive, but I took snapshot while attempting to pan the map, so get an idea of what's hanging up.

  • No surprise, the vast majority of memory usage was dojo related. (Screenshot on top)
  • The second largest memory user was Angular. (Screenshot on bottom)

Maybe Angular is getting hung up on keeping a huge amount of memory in Deferreds?

image

image

@andygup
Copy link
Collaborator Author

andygup commented May 26, 2016

Here's a 1 minute memory snapshot with Cordova-only and JS API 3.16 basic Hello World Map for comparison.

CURRENT STATS:
System memory usage:
SOff/Norm: 1 samples:
Cached: 368MB min, 368MB avg, 368MB max
Free: 53MB min, 53MB avg, 53MB max
ZRam: 0.00 min, 0.00 avg, 0.00 max
Kernel: 161MB min, 161MB avg, 161MB max
Native: 61MB min, 61MB avg, 61MB max

Per-Package Stats:

  • com.ag.phonegap / u0a124 / v10:
    • com.ag.phonegap / u0a124 / v10:
      TOTAL: 35% (67MB-106MB-124MB/60MB-99MB-116MB over 5)
      Top: 35% (67MB-106MB-124MB/60MB-99MB-116MB over 5)
      (Cached): 0.48%

Summary:

  • com.ag.phonegap / u0a124 / v10:
    TOTAL: 35% (67MB-106MB-124MB/60MB-99MB-116MB over 5)
    Top: 35% (67MB-106MB-124MB/60MB-99MB-116MB over 5)
    (Cached): 0.48%

Run time Stats:
SOff/Norm: +6m25s811ms
SOn /Norm: +14m14s888ms (running)
TOTAL: +20m40s699ms

Memory usage:
Kernel : 161MB (8 samples)
Native : 61MB (8 samples)
Persist: 235MB (20 samples)
Top : 96MB (61 samples)
ImpFg : 104MB (86 samples)
ImpBg : 47MB (54 samples)
Service: 238MB (139 samples)
Receivr: 124KB (149 samples)
Home : 43MB (12 samples)
LastAct: 35MB (10 samples)
CchAct : 245MB (16 samples)
CchEmty: 183MB (110 samples)
Cached : 368MB (8 samples)
Free : 53MB (8 samples)
TOTAL : 1.8GB
ServRst: 590 (2 samples)

      Start time: 2016-05-26 15:22:00

Total elapsed time: +1h14m17s481ms (partial) libart.so

@andygup
Copy link
Collaborator Author

andygup commented May 26, 2016

And, here's a 1 minute memory snapshot with Cordova-only and JS API 4.0 basic Hello World Map for comparison.

CURRENT STATS:
System memory usage:
SOff/Norm: 1 samples:
Cached: 368MB min, 368MB avg, 368MB max
Free: 53MB min, 53MB avg, 53MB max
ZRam: 0.00 min, 0.00 avg, 0.00 max
Kernel: 161MB min, 161MB avg, 161MB max
Native: 61MB min, 61MB avg, 61MB max

Per-Package Stats:

  • com.ag.phonegap / u0a124 / v10:
    • com.ag.phonegap / u0a124 / v10:
      TOTAL: 48% (67MB-108MB-124MB/60MB-100MB-116MB over 8)
      Top: 48% (67MB-108MB-124MB/60MB-100MB-116MB over 8)
      (Cached): 0.38%

Summary:

  • com.ag.phonegap / u0a124 / v10:
    TOTAL: 48% (67MB-108MB-124MB/60MB-100MB-116MB over 8)
    Top: 48% (67MB-108MB-124MB/60MB-100MB-116MB over 8)
    (Cached): 0.38%

Run time Stats:
SOff/Norm: +6m25s811ms
SOn /Norm: +20m10s211ms (running)
TOTAL: +26m36s22ms

Memory usage:
Kernel : 161MB (8 samples)
Native : 61MB (8 samples)
Persist: 239MB (15 samples)
Top : 99MB (72 samples)
ImpFg : 103MB (103 samples)
ImpBg : 47MB (62 samples)
Service: 248MB (172 samples)
Receivr: 113KB (203 samples)
Home : 43MB (13 samples)
LastAct: 42MB (12 samples)
CchAct : 254MB (16 samples)
CchEmty: 178MB (128 samples)
Cached : 368MB (8 samples)
Free : 53MB (8 samples)
TOTAL : 1.9GB
ServRst: 459 (2 samples)

      Start time: 2016-05-26 15:22:00

Total elapsed time: +1h20m12s804ms (partial) libart.so

@andygup
Copy link
Collaborator Author

andygup commented Jul 11, 2016

@jwasilgeo Looks like esri-angular-js1 (and JS API 3.17) has been ruled out as a CPU/Memory hog when used with Cordova by itself. It is using CPU and memory appropriately when Ionic is removed from the picture.

I tested Cordova 6.2 with esri-angular-js1 on Android 6.0.1. CPU usage at idle is perfect. Memory usage good.

image

The indicators now seem to be pointing at Ionic as the potential culprit for the memory usage. I did notice a similar odd CPU usage pattern when Ionic was removed from the picture in this test. Although without Ionic they were considerably muted and averaging about 4 - 5% CPU. It's possible that Ionic is magnifying something within angular that already exists. Screenshot below:

image

Next step seems to be taking a bit closer look at Ionic to see if this is something obvious or if it's systemic and deep within the Ionic architecture.

@jwasilgeo
Copy link
Owner

@andygup wow, thanks for researching this and providing me with a sigh of relief for our Angular+Esri integration library. It is surprising to hear that Ionic looks like it might be the culprit.

@andygup
Copy link
Collaborator Author

andygup commented Sep 7, 2016

Working on an unrelated Cordova project I stumbled across a use case that may be the key to isolating 2D map jank (jerkiness, screen freezing) in Cordova. Initial research is pointing towards using certain CSS properties in WebView and how they task the GPU. Further research is pending as this is all speculative at this point.

Device: Android Nexus 5 running 6.0.1.

Background: I noticed that a simple JS API app running on Cordova (without Ionic) was generating regular and fairly rapid GCs (garbage collection). It's important to note the application was idling. Digging further using Android systrace, I've been able to isolate skipped draw frames. The skipped frames occured when the WebView rendering activity occurred at the same time as the RenderThread's DrawFrame. DrawFrame is the "actual formation and issuing of drawing commands to the GPU."

Supported Theory. In the same JS API app, I ran tests that didn't include the Esri SearchWidget or bootstrap/Collapse, bootstrap/Dropdown, bootstrap/Tab. There was significantly less jank and negligible garbage collection.

Next Steps. Continue to isolate the use case and identify elements that are causing memory leaks. Determine which widgets or libraries (CSS and/or JavaScript) cause jank.

Screenshot 1 shows all four cores tasked, and at least one skipped draw frame and possible two around 3075 - 3090ms. The Render Thread capture, and associated Cordova processes show a pipelined sequence of events related to GPU tasking. This time slice demonstrates the underlying Android thread activity during pan and zoom events, but is critical in demonstrating a reproducible missed draw frame event.

Breakout of active processes:

Record View#draw() - Every invalidated View's drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded
BrowserViewRenderer::OnDrawHardware - Category: android_webview
RenderWidgetHostViewAndroid::OnVSync
DrawFame - RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.
GLRenderer::SwapBuffers
DeferredGpuCommandService::RunTask - Category: android_webview

image

Screenshot 2 is a detailed view of the application's RenderThread's DrawFrame heartbeat.

image

@andygup
Copy link
Collaborator Author

andygup commented Sep 7, 2016

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants