When you add any Wicket component library e.g.  Wicket-Bootstrap to your project, usually it adds some JavaScript and CSS resources to every page or panel. But the problem is that these JS files are added in the <head> section of your page while all Internet knowledge says that JS should be placed at the bottom of the page for a better performance and faster loading times. In this post I will show how we could configure Wicket to place JS files wherever we want.

Initial project setup

Let’s start with a simple one-page-one-form Wicket application counting days from user’s birthday:

It has a dependency to mentioned earlier Wicket-Bootstrap because we need its DatePicker component:

Our web page contains a form, one text field and one date picker:

Problem

When we run our application we will see that all Bootstrap related JS files are placed in the page header:

It is not what we wanted, so we need to configure our application to add JS files somewhere at the bottom.

Solution

First, let’s start with some background. Each time when a component wants to add something to page header (for example using IHeaderContributor) it creates a new instance of HeaderItem object. By default all HeaderItems are rendered in <head>, but we could modify this behaviour using IHeaderResponseDecorator and FilteringHeaderResponse to separate HeaderItems into two places to render: header and defined place in our page body.

First, we should define a place where all JS files should be rendered by adding a <wicket:container> element with id:

and add it to the Page class:

Next step is to configure a response decorator and response filter that will direct some items to our footer-container bucket. This should be done in init() method of our WicketApplication class:

Our decorator should use a filter that is already in Wicket core module, a JavaScriptFilteredIntoFooterHeaderResponse that does exactly what we need:

A header response that creates two buckets. The header bucket will contain all references to CSS and markup from the <head> section from the page. The other bucket will contain all other header items, and you will need to add a HeaderResponseContainer to the footer of your page (typically just before the end body tag) to render those items.

So it will split all our HeaderItems into two buckets, one (default) that will be rendered in page header and second rendered where we placed footer-container element. Working version of our decorator looks as presented below:

After that we can rebuild our application and see that all our Bootstrap related JS files are rendered at the bottom of our page, improving performance and overall user experience of our users.

  • Sven Meier

    Thanks Tomasz!

    In case any Wicket 8 user is reading your blog entry, the usage has changed slightly:

    return new ResourceAggregator(new JavaScriptFilteredIntoFooterHeaderResponse(response, bucketName));

    Or – if you’re more adventurous – try out the new JavaScriptDeferHeaderResponse which defers all JavaScript while keeping it in the page’s header.