JDK-8092206 : TabPane renders content of all tabs even only one is active
  • Type: Enhancement
  • Component: javafx
  • Sub-Component: controls
  • Affected Version: 8
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2012-08-08
  • Updated: 2018-09-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Blocks :  
Description
TabPane renders content of all tabs even only one is active which very impacts startup time.
Here are more details.

>> I did look at startup time of J1 app and Stage.show() takes ~10.3 seconds where
>>  javafx.scene.Scene.doLayoutPass() takes 7.927
>>  javafx.scene.Scene.doCSSPass()    takes 2.124
>>
>>
>> It looks like we do render all tabs even only one is visible.
>> Setting setVisible(false) for all tabs except Timeline doesn't help.
>> Removing all tabs except Timeline tab reduces Stage.show() to 2.792 seconds.

On 8/8/12 4:40 PM, Jonathan Giles wrote:
> Regarding the issue you're talking about, to me I would consider this a major bug. There are some considerations that need to be made regarding the preferred size of a 
> TabPane possibly being related to the size of the biggest content in all of the Tabs, but this is something Kinsley (CC'd) should look into. We certainly shouldn't be 
> wasting excessive cycles on invisible content.

Comments
Webrev looks good. I can't see any regressions when running in the other modes. We might want to tweak the javadoc a little, but otherwise it's a +1 from me.
02-08-2017

Hi Jonathan, Thanks for guiding through the test. Added a new Tab to HelloTabPane with ToggleButtons to switch load policies. Request you to take a look, http://cr.openjdk.java.net/~arapte/fx/8092206/webrev.04/
02-08-2017

webrev looks good. It would be good if you could make improvements to HelloTabPane to allow for additional testing. Adding code that toggles the state of the tabs, etc - so we can look out for functional regressions.
31-07-2017

Hi Jonathan, Thanks for the review comment. Request you to take a look at the updated webrev: http://cr.openjdk.java.net/~arapte/fx/8092206/webrev.03/
27-07-2017

There is quite a lot of duplication in TabPaneSkin with the new handleTabLoadPolicyChange method. Are you able to reduce this so that we don't run into situations where a bug fix is applied to only one of the two locations? Thanks.
26-07-2017

Hi Jonathan, Please review the updated webrev. Webrev: http://cr.openjdk.java.net/~arapte/fx/8092206/webrev.02/ Webrev has additional changes in documentation & support for run time change of policy.
25-07-2017

Hi Tom, Thanks for your inputs. Regarding the multiple CSS & Layout passes: We are planning to introduce three policies: SELECTED_TAB, VISITED_TABS, ALL_TABS. SELECTED_TAB policy maintains only the selected tab in the scene graph. So this policy results in adding & removing tab content from scene graph. As you pointed out, In this case a CSS & Layout pass will happen on the tab content each time when the tab gets Selected. But in case of VISITED_TABS, Once a tab is selected, it's content will be attached to scene graph & will not be detached later when selected tab changes. & ALL_TABS loads all tabs at once. So depending on the use case of application, a related policy should be selected by developer. Also regarding avoiding CSS Pass on tab content that is not visible, API suggested by you in JDK-8173301 will help.
25-07-2017

The problem I see is that if you detach a scenegraph portion and reattach it later on you get hit by a fully CSS & Layout-Pass. I don't think it is the right strategy to detach the content but it must be excluded from the css and layout passes as long as it is not visible.
14-07-2017

I think another pass on the javadoc is necessary to make things clearer and more understandable. If you want me to do a pass and put up a web rev, let me know and I can do that. Separately, I need to run this patch and look for regressions.
11-07-2017

Hi Jonathan, I have updated the webrev to handle the case of changing load policy at run time. Request you to review : http://cr.openjdk.java.net/~arapte/fx/8092206/webrev.01/
11-07-2017

I observed a problem use case. If the TabLoadPolicy is set to SELECTED_TAB at time of loading tabs, & later changed to ALL_TABS. The newly selected tab is not loaded. I shall test more scenarios & update the webrev.
11-07-2017

Hi Jonathan, Request you to review the changes: http://cr.openjdk.java.net/~arapte/fx/8092206/webrev.00/ There are three policies added, public enum TabLoadPolicy { SELECTED_TAB, VISITED_TABS, ALL_TABS } The time stamp readings are recorded here: https://wiki.se.oracle.com/pages/viewpage.action?pageId=81275881 => Load time for SELECTED_TAB & VISITED_TABS is recorded always around 1600 milliseconds for any number of tabs.
11-07-2017

Will it be once set, or a dynamicly changing property?
03-07-2013

Proposing API to control how tab content gets loaded and hence affecting either startup time or runtime of TabPane. The following enum specifies how the TabPane handles tab content loading . public static enum TabContentSceneGraphPolicy { //The content all the tabs get loaded up front with no optimization. If there are a lot of tabs and content is large - this could potentially cause slow start up time. This is the default behavior. ALL_TABS, //Only the content of the selected tab will be loaded on startup and other tabs get loaded on selection. When a new tab is selected, its content is loaded into the scenegraph and the content of the previously selected tab is unloaded from the scenegraph. SELECTED_TAB, //Only the content of the selected tab will be loaded at startup and content of other tabs get loaded lazily in the background. Hence there is no loading and unloading of tab content when different tabs are selected as in the case of SELECTED_TAB option. SELECTED_TAB_WITH_LAZY_LOADING }
03-07-2013

Yes, it was pushed and then backed out due to changes in semantics. Paru is going to work on adding public API to toggle this on (but to have it off by default).
11-06-2013

the issue still exists
11-06-2013

Paru, why the issue is marked as resolved? I tried the latest available build controls-scrum-616 and the difference in startup time is still quite big. Ex: > time "java ... controls.TabPaneTest -numtabs 1 -currtab 1" 1.62 sec > time "java ... controls.TabPaneTest -numtabs 10 -currtab 1" 5.63 sec
11-06-2013

Startup Time : Load Selected Tab only :- 1 tab : 3 seconds 10 tabs : 3 seconds 20 tabs : 3 seconds Load All Tabs :- 1 tab : 3 seconds 10 tabs : 8 seconds 20 tabs : 13 seconds Load Selected Tab and others lazily. 1 tab : 3 seconds 10 tabs : 3 seconds 20 tabs : 3 seconds Keyboard Test : Load Selected Tab only:- 1 tab : 114.6192 Average FPS 10 tabs : 113.8018 Average FPS 20 tabs : 113.16494 Average FPS Load All Tabs :- 1 tab : 114.50438 Average FPS 10 tabs : 97.06279 Average FPS 20 tabs : 82.46283 Average FPS Load Selected Tab and others lazily. 1 tab : 115.688324 Average FPS 10 tabs : 90.17971 Average FPS 20 tabs : 73.693275 Average FPS Resize Test : Load Selected Tab only:- 1 tab : 108.15812 Average FPS 10 tabs : 106.966484 Average FPS 20 tabs : 107.53213 Average FPS Load All Tabs :- 1 tab : 108.95991 Average FPS 10 tabs : 91.38065 Average FPS 20 tabs : 73.65431 Average FPS Load Selected Tab and others lazily. 1 tab : 120.29955 Average FPS 10 tabs : 89.1564 Average FPS 20 tabs : 76.9409 Average FPS
04-06-2013

Just for information in e(fx)clipse we are creating the tab content on demand (=on first activation). A problem we had to work around (and it didn't work 100% reliable in 2.2 but seems to cause no problems anymore in 8) is that when you try to transfer focus to one of the first children of the pane content that sometimes the focus didn't get transfer. We are using a Platform.runLater for that. What would help us is an event that is delivered before the Tab switch is happening. I've filed another request (RT-27091) in this regard which requests that the TabPane is no auto-selecting the first child added because it might not be the first selected item.
26-05-2013

On my Windows laptop the startup difference between 1 tab and 10 tabs for table 150x10 is ~2.2 seconds: 1 tab: 2.30s 10 tabs: 4.43s In case of bigger table of size 150x50 the difference is more than 30 seconds: 1 tab: 2.81s 10 tabs: 38.37s
24-05-2013

I have fixed TabPaneTest created by Paru and now it can be used to measure both startup time as well as FPS. Copy this file under JFX_WS/tests/performance/Controls/src/controls/ and compile COntrols benchmark. To measure startup time of 1 tab: > time java -cp "JFX_HOME/rt/lib/ext/jfxrt.jar;./dist/Controls.jar;../FXBenchmark/dist/FXBenchmark.jar;../../../import/benchmarks-2.1.1/benchmarks-2.1.1.jar" controls.TabPaneTest -mode keyboard -usePulse true -cells 150 10 -curtab 1 -numtabs 1 -exit true To measure startup time of 10 tabs: > time java -cp "JFX_HOME/rt/lib/ext/jfxrt.jar;./dist/Controls.jar;../FXBenchmark/dist/FXBenchmark.jar;../../../import/benchmarks-2.1.1/benchmarks-2.1.1.jar" controls.TabPaneTest -mode keyboard -usePulse true -cells 150 10 -curtab 1 -numtabs 10 -exit true to measure FPS run with "-exit false" // default Note, the test uses PerformanceTracker.setOnRenderedFrameTask which was integrated into graphics-scrum-1214. So, make sure controls-scrum has these changes as well.
24-05-2013

We found that there are multiple areas of concern here. To summarise: 1) Having multiple tabs with content leads to worse performance for the visible tab (e.g. when scrolling a TableView) 2) Layout / css appears to be run on all tabs (to some degree), and this is unnecessary. Some areas of work include: 1) Finishing the TabPaneBenchmark and providing to the performance team for benchmarking (both TableView scrolling and resizing tests are useful). 2) Better understanding the implications of switching tab content at runtime (versus having it always been in the scenegraph) 3) Investigating API for specifying whether to pay the startup penalty or the runtime penalty. 4) Investigating API / best practices to allow for lazy-loading of tab pane content (rather than have developers specify it in the content property eagerly). 3) and 4) will be handled by RT-30648 5) Change how the min / max / pref widths of TabPane are changed such that it is not based on the content of tabs, but rather simply be a hard-coded value.
24-05-2013

Why not providing a property for the developer to define the strategy? This does not even have to be control API but a CSS-Property.
11-02-2013

This patch improves the startup time and also fixed the problem of slow tab switching introduced in the previous attached patch by adding all the tab content to the scene graph after the first selected tab is laid out.
16-08-2012

TabPane loads all its content on startup hence the slow startup time. The attached patch will improve startup time by only loading the selected tabs (3.7 sec down to ~1.0 sec for HelloTableView), but switching between tabs is very slow. I talked to Jasper about this and he says not to push this back into TabPane because we need to decide on slow startup or slow tab switching.
14-08-2012

re-layout of all tabs is also the issue why we see slowness when rotating the device. I looked at the profile and I see the time spent in doLayoutPass() is about 4.3 seconds. Leaving only one Timeline tab reduce doLayoutPass() time significantly. So, the issue is more critical as it affects not only startup time.
09-08-2012

helloworld/HelloTableView.java can be also used to see the issue. It uses TabPane with 3 tabs.
09-08-2012