Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Performance of ListGrid Using ShadowDom / requestAnimationFrame for grid batching rendering

    Issue:
    There is list grid with 50 and more columns and grid has 3600 lines (showing by 300 )
    The grid is rich -> contains a lot of css per cells (we use ListGrid.getCellCSSText)
    4K monitor
    Firefox FF 52 ESR

    On such big screen scrolling is not smooth(hangs sometimes for secs) due to rendering lags and updating of dom.
    Scrolling is not smooth even thou no server side request is made

    Our analysis shows lack of batch updates on DOM but only a lot of synchronous one.
    My question is: is grid renderer adapted for massive tables ?
    If not, is it feasible for you to fix such issue ? If yes I can provide test case.

    Just what I can now provide is test case of opensource fastdom lib to be more precise what I have in mind
    http://wilsonpage.github.io/fastdom/...animation.html

    Thank you for your time

    Best
    Peter


    #2
    We are aware of deferring and avoiding DOM reads as much as possible and believe that we do close to the minimum number of DOM reads necessary to implement the active features. Some features, such as auto-sizing, do require a lot of DOM reads since we need to know how large content is. Some browser bugs also force us to do additional DOM reads as part of workarounds.

    If you find a specific case where there seem to be too many DOM reads, you can post a minimal, ready-to-run test case demonstrating the issue. However, be aware that if you just measure the number of reads and say "it seems like a lot", this is useless - you are only contributing if you do some code-level analysis and can make a clear case that some reads are not necessary.

    Comment


      #3
      Hello,

      I am attaching concrete example.

      The issue I have spotted is that you programatically initiate reflow when scrolling that slows down render. See image bellow, the hot spots are marked with red corner

      Click image for larger version

Name:	Screen Shot 2017-10-18 at 13.59.36.png
Views:	192
Size:	279.2 KB
ID:	249818

      The code called
      Click image for larger version

Name:	Screen Shot 2017-10-18 at 13.58.19.png
Views:	140
Size:	148.0 KB
ID:	249819

      From burn down chart it is clear that this is programatically intended, but my question is is there a way how to avoid it ?
      In more complicated case I have those red spots are really often.
      Click image for larger version

Name:	Screen Shot 2017-10-18 at 17.54.09.png
Views:	160
Size:	168.9 KB
ID:	249820
      My question is is this really necessary ?
      is there a way how to optimise this ?

      I am open to any suggestions and willing to provide more input.

      Tested on 6.0p-2017-01-21

      Thank you

      Code:
      import com.google.gwt.core.client.EntryPoint;
      import com.google.gwt.user.client.Random;
      import com.smartgwt.client.data.DataSource;
      import com.smartgwt.client.data.fields.DataSourceFloatField;
      import com.smartgwt.client.data.fields.DataSourceIntegerField;
      import com.smartgwt.client.data.fields.DataSourceTextField;
      import com.smartgwt.client.widgets.grid.ListGrid;
      import com.smartgwt.client.widgets.grid.ListGridRecord;
      
      
      public class Sample implements EntryPoint {
      
      class MyListGrid extends ListGrid {
      
      
      MyListGrid(final DataSource ds) {
         super(ds);
      }
      
      @Override
      protected String getCellCSSText(ListGridRecord record, int rowNum, int colNum) {
        if (colNum % 2 == 0) {
          return (rowNum/2 + colNum/4) % 3 == 1 ? "background-color:#FFC8C8" : "background-color:#C8FFC8";
        }
        String style = rowNum % 2 == 0 ? "background-color:#EEEEEE; " : "";
        if (colNum % 12 == 1) {
          style += "border-right:2px solid #808080;";
        }
        else if (colNum % 6 == 2) {
          style += "border-right:2px solid #808080;";
        }
         return style;
       }
      }
      
      @Override
      public void onModuleLoad() {
        final ListGridRecord[] records = new ListGridRecord[5000];
        for (int i = 0; i < records.length; i++) {
          final ListGridRecord r = new ListGridRecord();
          for (int j = 0 ; j < 10 ; j++) {
             r.setAttribute("text1" + j, "ABCDEFG");
             r.setAttribute("text2" + j, "abcdefg");
             r.setAttribute("int1" + j, Random.nextInt(999999));
             r.setAttribute("int2" + j, Random.nextInt(999999));
             r.setAttribute("float1" + j, "1.2345");
             r.setAttribute("float2" + j, "5.6789");
          }
        records[i] = r;
      }
      
      final DataSource ds = new DataSource();
      for (int i = 0 ; i < 10; i++) {
        final DataSourceTextField text1 = new DataSourceTextField("text1" + i);
        final DataSourceTextField text2 = new DataSourceTextField("text2"+ i);
        final DataSourceIntegerField int1 = new DataSourceIntegerField("int1"+ i);
        final DataSourceIntegerField int2 = new DataSourceIntegerField("int2"+ i);
        final DataSourceFloatField float1 = new DataSourceFloatField("float1"+ i);
        final DataSourceFloatField float2 = new DataSourceFloatField("float2"+ i);
      
        text1.setEscapeHTML(true);
        text2.setEscapeHTML(true);
        int1.setEscapeHTML(true);
        int2.setEscapeHTML(true);
        float1.setEscapeHTML(true);
        float2.setEscapeHTML(true);
      
        ds.addField(text1);
        ds.addField(text2);
        ds.addField(int1);
        ds.addField(int2);
        ds.addField(float1);
        ds.addField(float2);
      }
      
      ds.setClientOnly(true);
      ds.setCacheData(records);
      final ListGrid grid = new MyListGrid(ds);
      grid.setWidth("100%");
      grid.setHeight("100%");
      ds.getJsObj();
      
      grid.setAutoFetchData(true);
      grid.setShowFilterEditor(true);
      customizeGrid(grid);
      grid.draw();
      
      }
      
      
      
      private static void customizeGrid(ListGrid grid) {
      grid.setDataPageSize(300);
      //grid.setDrawAheadRatio(3); // SGWT default is 2
      grid.setQuickDrawAheadRatio(3);
      grid.setScrollRedrawDelay(300);
      grid.setScrollWheelRedrawDelay(350);
      //grid.setFastCellUpdates(true);
      }

      Comment


        #4
        What you seem to be seeing is that the ListGrid draws only the rows that are currently visible in the viewport, and redraws those rows as the viewport changes. This is by design, and is what allows scaling to millions of rows.

        No, there is no way to avoid drawing rows on demand if you want scalability, and in particular if you want to be able to incrementally fetch data from a server.

        This is normally very, very fast, as it is with your test case or with Showcase examples, but make sure you are running in compiled mode or you are basically just watching GWT's issues with slow Java < > JavaScript communication.

        Comment

        Working...
        X