title: Lazy DataTable rendering is very slow
body: <h1>Environment:</h1>
  
  <ul>
  <li>PrimeFaces 5.1</li>
  <li>Mojarra 2.2.2</li>
  <li>Spring 4.0.2</li>
  </ul>
  
  <h1>Problem:</h1>
  
  <p>I use a <code>p:dataTable</code> with <code>lazy=true</code> and I have implemented a LazyDataModel.
  All works perfectly well (pagination, filtering, etc.), but it is very slow...</p>
  
  <p>The <code>load</code> method is called, it performes the call to the DB and returns in 3sec max. But after that, it takes up to <strong>20sec</strong> for the page to load (render?)...</p>
  
  <p>For information, the page loads through ajax: a listener give informations to the LazyModel (setters), then change the page to insert (<code>ui:insert</code>, value stored in the controller), and finally update the form (<code>update=":form"</code>).</p>
  
  <p>After debugging it seems that I have no control on this...</p>
  
  <h1>Code:</h1>
  
  <pre><code>&lt;p:dataTable id="storeTable"
          value="#{dashboard.stores}"
          var="store"
          lazy="true"
          paginator="true" rows="30"
          paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
          paginatorPosition="bottom"&gt;
  
      ...
      &lt;!-- Columns --&gt;
      ...
      &lt;c:forEach var="date" items="#{dashboard.days}"&gt;
          &lt;c:set var="day" value="#{store.getDay(date)}"/&gt;
  
          &lt;p:column styleClass="store-day open-#{store.isAmOpen(date.date)} store-day-available-#{store.isAvailable(date.date)} #{store.storeKey} #{day.date.time} am" 
                  width="30"&gt;
              &lt;h:outputText value="&amp;#160;" title="#{day.amComment}" /&gt;
              &lt;h:outputText styleClass="store" value="#{store.storeKey}" style="display: none" /&gt;
              &lt;h:outputText styleClass="date" value="#{day.date.time}" style="display: none" /&gt;
              &lt;h:outputText styleClass="am_pm" value="am" style="display: none" /&gt;
          &lt;/p:column&gt;
  
          &lt;p:column styleClass="store-day open-#{store.isPmOpen(date.date)} store-day-available-#{store.isAvailable(date.date)} #{store.storeKey} #{day.date.time} pm" 
                  width="30"&gt;
              &lt;h:outputText value="&amp;#160;" title="#{day.pmComment}" /&gt;
  
              &lt;h:outputText styleClass="store" value="#{store.storeKey}" style="display: none" /&gt;
              &lt;h:outputText styleClass="date" value="#{day.date.time}" style="display: none" /&gt;
              &lt;h:outputText styleClass="am_pm" value="pm" style="display: none" /&gt;
          &lt;/p:column&gt;
  
      &lt;/c:forEach&gt;
  
  &lt;/p:dataTable&gt;
  </code></pre>
  
  <p>Relevant code of the controller:</p>
  
  <pre><code>@Controller("dashboard")
  @Scope("session")
  public class DashboardController implements Serializable {
      private static final long serialVersionUID = 1971543164359627877L;
  
      private LazyStoreWebModel stores;
      // Some more attributes
  
      @PostConstruct
      public void postCtr() {
          stores = new LazyStoreWebModel(restit);
          update();
      }
  
      private void updateGroupList() {
          groupList.clear();
          groupList.addAll(groupDao.findByCountry(countryFilter));
      }
  
      public void updateStoreChainTypeList() {
          storeChainTypeList.clear();
          storeChainTypeList.addAll(storeTypeDao.findByCountry(countryFilter));
      }
  
      public void updateStoreZoneList() {
          storeZoneList.clear();
          storeZoneList.addAll(storeZoneDao.findByCountryAndChainType(
                  countryFilter, chainTypeFilter));
      }
  
      public void updateStoreRegionList() {
          storeRegionList.clear();
          if (storeZoneFilter != null) {
              storeRegionList.addAll(storeRegionDao.findByCountryAndZone(
                      countryFilter, storeZoneFilter));
          }
      }
  
      public void updateDays() {
          days.clear();
          days.addAll(calendar.generateListDateFromMonthAndYear(
                  yearFilter, monthFilter.getCode()));
          stores.setYear(yearFilter);
          stores.setMonth(monthFilter.getCode());
  
          Collections.sort(days);
      }
  
      public void update() {    
          updateGroupList();
          updateStoreChainTypeList();
          updateStoreZoneList();
          updateStoreRegionList();
          updateDays();
  
          stores.setCountry(countryFilter);
          stores.setChainType(chainTypeFilter);
          stores.setRegion(storeRegionFilter);
          stores.setZone(storeZoneFilter);
      }
  
      public LazyDataModel&lt;StoreWeb&gt; getStores() {
          return stores;
      }
  }
  </code></pre>
  
  <p>The LazyDataModel</p>
  
  <pre><code>public class LazyStoreWebModel extends LazyDataModel&lt;StoreWeb&gt; {
      private static final long serialVersionUID = -4318420518897167924L;
  
      private RestitService restit;
  
      private Country country;
      private StoreChainType chainType;
      private StoreZone zone;
      private StoreRegion region;
      private Integer storeIntFlagFilter;
      private Integer year;
      private Integer month;
  
      public LazyStoreWebModel(RestitService restit) {
          this.restit = restit;
      }
  
      @Override
      public StoreWeb getRowData(String key) {
          try {
              return restit.visualisationStoreById(key, year, month);
          } catch (CalendarException e) {
              e.printStackTrace();
          } catch (NotExistStoreException e) {
              e.printStackTrace();
          }
          StoreWeb sto = new StoreWeb();
          sto.setStoreDesc("Should be null");
          sto.setStoreKey("NULL:" + key);
          return sto;
      }
  
      @Override
      public Object getRowKey(StoreWeb sto) {
          return sto.getStoreKey();
      }
  
      @Override
      public List&lt;StoreWeb&gt; load(int first, int pageSize, String sortField,
              SortOrder sortOrder, Map&lt;String, Object&gt; fieldFilters) {
          List&lt;StoreWeb&gt; result = new ArrayList&lt;StoreWeb&gt;();
  
          Map&lt;String, Object&gt; mainFilters = new HashMap&lt;String, Object&gt;();
          mainFilters.put(RestitService.COUNTRY_KEY, country);
          mainFilters.put(RestitService.CHAIN_TYPE_KEY, chainType);
          mainFilters.put(RestitService.ZONE_KEY, zone);
          mainFilters.put(RestitService.REGION_KEY, region);
          mainFilters.put(RestitService.INT_FLAG_KEY, storeIntFlagFilter);
          mainFilters.put(RestitService.YEAR_KEY, year);
          mainFilters.put(RestitService.MONTH_KEY, month);
  
          try {
              result.addAll(restit.load(first, pageSize, sortField, sortOrder,
                      mainFilters, fieldFilters));
          } catch (CalendarException e) {
              e.printStackTrace();
          } catch (NotExistStoreException e) {
              e.printStackTrace();
          }
  
          setRowCount(restit.count(mainFilters, fieldFilters));
          return result;
      }
  }
  </code></pre>
  
  <p>The <code>restit</code> attribute do the calls to the DB.</p>
  
  <p>Any idea?</p>
  
  <p>Thanks.</p>
  
  <h1>Edits:</h1>
  
  <ol>
  <li>Added relevant code of the controller</li>
  <li>Added code of the LazyDataModel</li>
  <li>Added code inside the HTML: Problem seems to come from the amount of columns (60+), more precisely from the quantity of attribute access done to build those. </li>
  </ol>