[WICKET-7059] make easier to skip some page serializations
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/RequestPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/RequestPageStore.java
index c8034f5..d3a4244 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/RequestPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/RequestPageStore.java
@@ -21,6 +21,7 @@
 
 import org.apache.wicket.MetaDataKey;
 import org.apache.wicket.page.IManageablePage;
+import org.apache.wicket.request.IRequestCycle;
 import org.apache.wicket.request.cycle.RequestCycle;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -107,9 +108,10 @@
 	public void detach(IPageContext context)
 	{
 		RequestData requestData = getRequestData(context);
+		IRequestCycle requestCycle = RequestCycle.get();
 		for (IManageablePage page : requestData.pages())
 		{
-			if (isPageStateless(page) == false)
+			if (isPageStateless(page) == false && shouldSerializePage(requestCycle, page))
 			{
 				getDelegate().addPage(context, page);
 			}
@@ -119,6 +121,21 @@
 		getDelegate().detach(context);
 	}
 
+	/**
+	 * Give the opportunity to skip some serializations. E.g. we have some AJAX behavior that is sending some
+	 * info from client to page but page structure didn't change at all and nothing is repainted via AJAX.
+	 * But this will trigger a serialization. Returning false here would prevent that request from doing a
+	 * page serialization. For heavy pages this can really make a difference.
+	 *
+	 * @param requestCycle The request
+	 * @param page         The {@link IManageablePage}
+	 * @return <code>true</code> if page should be serialized for this request. The default is true.
+	 */
+	protected boolean shouldSerializePage(IRequestCycle requestCycle, IManageablePage page)
+	{
+		return true;
+	}
+
 	private boolean isPageStateless(final IManageablePage page) {
 		boolean isPageStateless;
 		try
diff --git a/wicket-core/src/test/java/org/apache/wicket/pageStore/RequestPageStoreTest.java b/wicket-core/src/test/java/org/apache/wicket/pageStore/RequestPageStoreTest.java
index ff02195..a9db0a0 100644
--- a/wicket-core/src/test/java/org/apache/wicket/pageStore/RequestPageStoreTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/pageStore/RequestPageStoreTest.java
@@ -23,6 +23,8 @@
 import org.apache.wicket.MockPage;
 import org.apache.wicket.mock.MockPageContext;
 import org.apache.wicket.mock.MockPageStore;
+import org.apache.wicket.page.IManageablePage;
+import org.apache.wicket.request.IRequestCycle;
 import org.junit.jupiter.api.Test;
 
 /**
@@ -62,6 +64,43 @@
 		assertNull(store.getPage(context, 2), "no page in request store");
 		assertNull(store.getPage(context, 3), "no page in request store");
 	}
+
+
+	@Test
+	void testAvoidSomePage()
+	{
+		MockPageStore mockStore = new MockPageStore();
+
+		MockPageContext context = new MockPageContext();
+
+		RequestPageStore store = new RequestPageStore(mockStore) {
+			@Override
+			protected boolean shouldSerializePage(IRequestCycle requestCycle, IManageablePage page) {
+				// we just skip serialization of third page.
+				return page.getPageId() != 3;
+			}
+		};
+
+		MockPage page1 = new MockPage(1);
+		MockPage page2 = new MockPage(2);
+		MockPage page3 = new MockPage(3);
+
+		store.addPage(context, page1);
+		store.addPage(context, page2);
+		store.addPage(context, page3);
+
+		assertTrue(mockStore.getPages().isEmpty(), "no pages delegated before detach");
+
+		store.detach(context);
+
+		assertEquals(2, mockStore.getPages().size(), "pages delegated on detach");
+
+		mockStore.getPages().clear();
+
+		assertNull(store.getPage(context, 1), "no page in request store");
+		assertNull(store.getPage(context, 2), "no page in request store");
+		assertNull(store.getPage(context, 3), "no page in request store");
+	}
 	
 	@Test
 	void testUntouch()