Framework: Performance degradation when upgrading from 6.8.13 to 7.4.5

Created on 21 May 2015  路  22Comments  路  Source: vaadin/framework

Originally by _artamonov_


Our application uses Vaadin 6.8.13 and we plan to migrate to current version of 7.4 branch, but 7.4.5 is not suitable for us by performance reason. We tried 7.4.5 on typical for us screen layout and our application was rendered in 2 times slower. I've prepared two simple projects based on Vaadin 6.8.13 and 7.4.5 with same screen layout. It is usual layout for application. Both projects are Maven based Vaadin project. To run it use > mvn clean package jetty:run, or import project to your favorite IDE and run from it.

Major problem for us - time of rendering of Table inside TabSheet. To reproduce our case just click on 'Open window' menu item.

Rendering time for different browsers and Vaadin versions (includes loading of all Table rows):

. . . . . . Vaadin 6 . . Vaadin 7
Firefox . . 600ms . . 1050ms
IE10 . . . . 700ms . . 1500ms
IE9 . . . . . 800ms . . 2000ms
Chrome . . 250ms . . 500ms


Imported from https://dev.vaadin.com/ issue #17947

bug

All 22 comments

Originally by _artamonov_


Attachment added: vaadin6-performance.zip (7.9 KiB)

Originally by _artamonov_


Attachment added: vaadin7-performance.zip (7.7 KiB)

Originally by _artamonov_


To get rendering time we use Vaadin profiler (lightweight GWT events aggregation) and Processing time from client side Vaadin console

Originally by @johannest


Tried this one with 7.1.15, 7.2.7, 7.3.10, 7.4.5 with IE11. Client side performance seem to be approximately as bad with all of these versions. Vaadin 6 version is clearly the fastest one in the given use-case: processing time 50-70% of the processing time of Vaadin 7 versions.

Originally by @johannest


I can reproduce this with single simple table (no generated columns, just text and numbers) component that is showed on the screen after clicking a button. With IE11 the rendering time of table is about 30-25% less in v6 than it is in v7.

According to R&D: "The main reason is probably that legacy code in Table does not play nicely with LayoutManager. Fixing this is far from trivial since you'd need to change how Table builds and updates its internal DOM"

Originally by _artamonov_


Some details on this:

  1. If we disable generated columns time reduces on ~100ms
  2. If we don't use TabSheet and SplitPanel time reduces on ~150ms
  3. It seems Vaadin 7 measures all components after each response from server, it is performed in ApplicationConnection:1720

layoutManager.setEverythingNeedsMeasure();

Originally by @johannest


more comments from R&D:
"as for the slower table in 7.x than 6.x, IIRC one of the culprits is higher serialization and deserialization cost in V7, especially on old IEs (perhaps some optimizations would still be possible), and Table is serializing more than it would need to (which is not going to change as it would be a major overhaul of the component)"

Originally by _artamonov_


@johannest

I can reproduce this with single simple table (no generated columns, just text and numbers) component that is showed on the screen after clicking a button. With IE11 the rendering time of table is about 30-25% less in v6 than it is in v7.

Performance is bad not only in IE9-11, also in latest Firefox

Originally by _proaccountapp_


Updated prioritization date.

Originally by @johannest


Status update for the ticket.

I have made several test runs for the issue with different browsers. Here is my key observations.

rendering time of original test setup with bigger table, without debug window IE10
v6 2.1s (72%)
v7 2.9s

medium big table and button, no other components, without debug window
v6 2.3s (77%)
v7 3.0s

rendering time of one super large table without debug window and no lazy loading
(pagesize 0)
v6 28.5s
v7 29s

How the client side time is spent when rendering very large table in Vaadin 7:

Total time                              6300ms

handleUIDLMessage                   1930ms (31%)
    creating connectors         150ms
    updating connector states       100ms
    updateComponentSize         0ms
    several small things (*)        190ms
    updateFromUIDL              1500ms          

(*) most of time is spent sending state change and hierarchy change events

Layout phase/LM.doLayout                4150ms (66%)

    general layout passes           250ms                       

    Table.postLayout            3900ms
        sizeInit            3900ms  (same as in v6)

state changes to the console (debug logging)        210ms   (3%)

Originally by @johannest


Same analysis for more realistic case

medium sized table (with lazy loading)

total time                              234ms

handleUIDLMessage                   186ms (80%)
    creating connectors         6ms
    updating connector states       5ms
    several small things (*)        30ms
    updateFromUIDL              143ms (61%)     


Layout phase/LM.doLayout                31ms (13%)
    general layout passes       30ms    
    Table.postLayout        1ms

state changes to the console                13ms (6%)

According to these analysis, the place where the optimisation attempts should be directed is the updateFromUIDL method. I will start investigating it more now.

Originally by @johannest


Investigating TableConnector's updateFromUIDL

  • about 40% of time is spent on VScrollTable's renderRows method

    • tested this also with v6 and it is only about 5% faster there

  • about 60% of time is spent on VScrollTable's setProperTabIndex

    • e.g. in v7 98ms (avg of 8 repeats) and in v6 30ms (avg of 8 repeats)

Thus, it seems that this is at least one place which is clearly slower in v7 than in v6.
Example calculation effect of this difference to the total rendering time:

                v7      v6
total time          284     213
total time if this fixed    216     213 

I will try to find why this method is so much slower in v7.

Originally by @johannest


It seem that the slowness came from finding the offsetWidth of table component
setProperTabIndex()
-isFocusable()
-hasHorizontalScrollbar
-scrollBody.getOffsetWidth()
-getElement().getPropertyInt("offsetWidth");

Probably the browser at this point does the reflow which will take the time, but why it is slower in v7 than in v6 is yet unknown,

Originally by @johannest


After disabling the initial lazy loading, it seems that the difference between setProperTabIndex times in v6 and v7 diminishes to negligible
Medium sized table with longer page length (no initial lazy loading) (15 cols, 300rows, pagelenght 50)

Chrome

    total(ms)   setProperTabIndex(ms)
v6  137 (49%)   17
v7  277     19

I did execution time analysis (avg of three repeats) for this case too, since here the rendering time in v6 is less than half of v7's rendering time.

total time                          ~250ms  (v6 ~140ms)

handleUIDLMessage               137 (55%)   
    creating connectors     21
    updating connector states    8
    send hierarchy change events     4
    send state change events    30
    updateFromUIDL          66      
        non partial update  44  
        setProperTabIndex   13


Layout phase/LM.doLayout            81 (32%)
    general layout passes       36
    Table.postLayout        41

state changes to the console            29 (12%)

Originally by @johannest


I tested the effect of enabling/disabling vaadin profiler (avg of 16 repeats)

enabled     262ms
disabled    238ms  --> profiler overhead 24ms

Current estimate what takes more time in v7 in earlier example (see above) where the client side time of v7 was 250ms and v6 140ms (v7 tooks 110ms more time)

  • more extensive debug logging (+ about 20ms) << this is not issue debug console is not open
  • vaadin profiler (+ about 20-25ms) << this is not issue if profiler is not enabled
  • different layout mechanism: layout passes? (+ about 20ms)
  • connector creation (+ about 20ms)
  • different event serialisation (state change events) (+ about 15ms)
  • several smaller differences (+ about 10-15ms)

Originally by @johannest


Summary this far

  1. It seems that there no single bottle neck, but in different scenarios the the extra client side time of Vaadin 7's is spent in different places.
  2. It seems that using Vaadin Profiler and Debug window in Vaadin 7 has rather big overhead and thus biases the performance measurement: For example there was case where there the client side processing time of a Table in Vaadin 6 (140ms) was almost half of one in Vaadin 7 (250ms). If we took the profiling and debugging overhead in account the difference was much smaller 140ms vs 205ms, though the v6 table was still faster (68% of v7's rendering time)
  3. Below is listed code blocks that are almost similar between v6's and v7's tables with their execution time (avg of 7 repeats) in the latest example. Note. in v6 sizeInit was executed inside intializeRows, thus its time was subtracted from time of initializeRows total time to make results comparable (e,g, total time of intializeRows 97 = 60 + 37)
execution time      v6      v7

initializeRows      60      44
setProperTabIndex   16      14
sizeInit        37      42
  1. As there is not single bottle neck that could be optimised, I suppose that the best approach to this issue would be converting the Vaadin 7's Table to use Vaadin 7 style communication.

Originally by @johannest


Convert V7's Table to V7's communication mode

Quick Plan

  1. Create a separate branch into git such as table_communication_upgrade
  2. Create com.vaadin.shared.ui.table.TableState class (extends AbstractComponentState)
  3. Move variables such as visibleColumns, pageLenght, etc. from com.vaadin.ui.Table to TableState

    • there is a lot of these, use Grid and GridState as a reference

    • annotate variables with @NoLayout, if change of it should not trigger a layout phase

    • annotate variables with @DelegateToWidget, if there is (or will be) a separate setter for this var in the VScrollTable class

    • -
  4. Find out is there need for a ServerRPC for example for clickevents, column resizes, etc.?

    • implement needed TableServerRPC interface and class

  5. Find out is there need for a ClientRPC for example for the sort method?

    • implement probably needed TableClientRPC interface and class

  6. Refactor logic from TableConnector's updateFromUIDL to separate @DelegateToWidget setters, RPC's etc
  7. Do lot of testing

    • run current testbench test

    • try old version side by side with this new one and measure the clint side performance (do several test runs and average the results)

Originally by @Legioth


There are some similar investigations going on in #17679.

Originally by @johannest


I continued working on this after vacation. After discussing with R&D, I discarded my "Quick Plan" (above), since it most probably will not make table faster, instead the time of first rendering of table might even increase.

First, one important note about the vaadin 7 performance test application attached to the ticket: it uses draft gwt compilation where as the vaadin 6 test app does not use. This does bias performance testing by making Vaadin 7 figures to look worse than what they really are.

I have continued on detailed performance profiling. One key finding this far has been that a plain table (no components inside) is almost equally fast in Vaadin 6 and 7. Thus, if one is not using much components in the Table, there should not be a need to worry the performance degradation.

But, the more component you add into a Table the more prominent the performance difference will be between Vaadin 6 and 7 version. For example adding two button columns to test table almost doubles the initial rendering time in Vaadin 7 where as in Vaadin 6 the increase is only about 20%.

Below is summarized what operations take more time when adding buttons into the Table

                    time (ms)
plain table
total time                  155
Creating connectors         5
updateConnectorState            2
sendStateChangeEvents           2
updateVaadin6StyleConnectors        57
Layout processing           70
      Layout pass       13
      PostLayoutListener    56
Dumping state changes to the console    9

with two button cols    
total time                  270
Creating connectors         23
updateConnectorState            9
sendStateChangeEvents           27
updateVaadin6StyleConnectors        76
Layout processing       84
      Layout pass       30
      PostLayoutListener        52
Dumping state changes to the console    35

Unfortunately, the data above shows that, again, there is no single point where the increase in rendering time is spent.

On ticket #17679, an idea was proposed where the measuring child components of a table could be skipped in certain cases. I tested that and it will optimize the situation a bit (about 15% in best case), but much better optimisation are still needed to make a V7 Table with lot of components at least almost as fast as it is in Vaadin 6.

Originally by @johannest


I was able to find another part of code that should be possible to optimise, but I have to test will my optimisation break existing functionality. After testing I will implement it and try to implement one mentioned in #17679 too. These two optimisations should increase the performance of first rendering of table about 20% in total. Unfortunately, that will not make Table of Vaadin 7 as fast as in Vaadin 6.

Originally by @johannest


Review link https://dev.vaadin.com/review/#/c/12024/

Originally by @samie


Some significant improvement to Table performance were achieved (up to 20% faster). While there still are other upcoming framework improvements that will make also Table performance better, we have no further speed improvements specifically for the Table.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

TatuLund picture TatuLund  路  3Comments

tomislavi picture tomislavi  路  6Comments

jbreitung picture jbreitung  路  6Comments

focbenz picture focbenz  路  3Comments

sarahfuchs picture sarahfuchs  路  6Comments