Output panel is a container element with several use cases such as autoUpdate and deferred loading. This example demonstrates the deferred loading feature with two modes where the content of the panel is loaded after the page itself is loaded to speed up initial page load time. There are two deferred modes, "load" (after page load) and "visible" (after page load and visible after page scroll). A progress indicator is also provided while loading the content.
<h:form>
<div class="card" style="min-height: 175px">
<p:outputPanel deferred="true">
<h5>Loaded after page load</h5>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</p:outputPanel>
</div>
<div class="card" style="min-height: 230px">
<p:tabView dynamic="true">
<p:tab title="Skeletons">
<p:outputPanel deferred="true" class="mt-2">
<p:ajax event="load" listener="#{outputPanelView.loadData}"/>
<f:facet name="loading">
<p:skeleton width="200px" height="21px" class="mb-4"/>
<p:skeleton width="100%" height="42px"/>
</f:facet>
<h5>#{outputPanelView.data.title}</h5>
<p>#{outputPanelView.data.body}</p>
</p:outputPanel>
</p:tab>
<p:tab title="Ajax / Loaded">
<p:outputPanel deferred="true" loaded="#{not empty outputPanelView.data2}" class="mt-2">
<p:ajax event="load" listener="#{outputPanelView.loadData2}"/>
<f:facet name="loading">
<p:skeleton width="200px" height="21px" class="mb-4"/>
<p:skeleton width="100%" height="42px"/>
</f:facet>
<h5>#{outputPanelView.data2.title}</h5>
<p>#{outputPanelView.data2.body}</p>
</p:outputPanel>
</p:tab>
</p:tabView>
</div>
<div style="height:1000px"></div>
<div class="card">
<p:outputPanel deferred="true" deferredMode="visible">
<h5>Loaded after the panel becomes visible on page scroll</h5>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</p:outputPanel>
</div>
</h:form>
package org.primefaces.showcase.view.panel;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import io.quarkus.runtime.annotations.RegisterForReflection;
@Named
@ViewScoped
@RegisterForReflection(serialization = true)
public class OutputPanelView implements Serializable {
private final Map<String, String> data = new HashMap<>();
private final Map<String, String> data2 = new HashMap<>();
public void loadData() throws InterruptedException {
Thread.sleep(1000); // Sleep a bit to show the skeletons
data.put("title", "OutputPanel loading facet");
data.put("body", """
Deferred loading can be used with the "loading" facet to show UI while the data is being \
loaded. This is normally combined with the load ajax event with a listener which loads the data you \
want to show in your panel. See xhtml and OutputPanelView.java\
""");
}
public void loadData2() throws InterruptedException {
Thread.sleep(1000); // Sleep a bit to show the skeletons
data2.put("title", "Deferred loading in Ajax requests");
data2.put("body", """
By default deferred loading does not work with Ajax requests. As a solution you can use the \
"loaded" boolean attribute to enforce loading (even in Ajax requests). Normally you would use \
an expression here checking if your data is empty. See xhtml and OutputPanelView.java\
""");
}
public Map<String, String> getData() {
return data;
}
public Map<String, String> getData2() {
return data2;
}
}