In this page

Overview

This page describes tuning Better PDF Exporter for Jira for improved performance. It most importantly explains techniques to create custom PDF templates that can efficiently export large amount of data from Jira. By "large amount" we mean PDF files with 500 - 10,000 pages.

If you export smaller data sets using your custom template, you will unlikely face performance problems. In that case, you can just skip this page.

Please note that albeit we do our best to make sure that the Better PDF Exporter app performs well under a wide variety of circumstances and the techniques below are generally good practices, every template and every situation may have its unique performance characteristics.

If you are having performance problems:

  1. Read this page and make those practical changes that are applicable to your template
  2. Ask for our help

Techniques

Use short page sequences

The <fo:page-sequence> FO object is used as a container for page output elements. A page sequence specifies how a series of pages is created (e.g. page dimensions) and laid out within the document.

Somewhat similar to database transactions, this is adviced to close page sequences as fast as possible for efficient resource management. When you close a page sequence, the followings happen:

  1. Visible: with the next page sequence a new page will start, effectively resulting in a page break.
  2. Invisible: the PDF renderer's layout engine releases all the memory that was previously allocated to calculate the layout for the current page sequence. With many pages, many paragraphs and other page elements, many words to break, this can grow very large.

Therefore a scalable PDF template should create a larger number of short page sequences instead of a lower number of long ones.

For example, the default issue-fo.vm template creates one page sequence per issue. (If the user wants to avoid the page breaks between the issues, this is possible to configure the template that way. In that case, the document will be a single page sequence, eventually putting higher load for the layout engine.)

Use auto-paging

Before this technique, please make sure that you understood the previous one and the importance of short page sequences.

There are situations when creating multiple page sequences is necessary, but not intuitive! For instance, the issue-navigator-fo.vm exports a potentially long table (with one row per issue) which is not straight-forward to break into page sequences. Where would you intuitively break a table with 10,000 rows?

The problem is that a table that spans over 200 pages requires quite some memory to be laid out correctly: when the renderer is creating the 200th page, it still needs to maintain and eventually re-layout the very first one! To lower the load by creating shorter page sequences, we implemented a simple technique called "auto-paging" in issue-navigator-fo.vm. You can use this as sample when facing similar problems in your custom template.

The idea of "auto-paging" is actually very simple:

  1. If the number of issues is less than a configurable limit specified by $startAutoPagingAt, the whole table is a single page sequence. We don't expect any problem for a smaller data set.
  2. If the number of issue exceeds that limit, the template will create a new page sequence after every Nth issue. The batch size can be configured via $rowsPerPage.

That's it. If you export 5000 issues, then the first 32 will go into the first page sequence, second 32 into the second, and so on. In other words, there is an "upper limit" set for a page sequence's complexity.

It scales really nicely to even tens of thousands of pages with one minor issue. Evey time the batch size is reached, the template will start a new page sequence which will cause a page break at that point. If this happens in the middle of the current page, then you will get a half-page blank area. This is the price of linear scaling, and you only need to pay it for large exports exceeding the configurable limit. So it makes sense.

You can configure it via the following variables in issue-navigator-fo.vm:

#set($startAutoPagingAt = 1000) ## when issue count is equal to or greater than this, the template will start "auto paging" for optimization
#set($rowsPerPage = 32) ## number of rows per page at "auto paging" (see previous)

Use "wide" blocks

To reduce the load on the text breaking engine, use "wide" blocks (i.e. blocks with an appropriate horizontal dimension) instead of narrow ones. When you force long piences of texts into narrow (even if tall) blocks, the engine will evaluate lots of potential solutions to find the best way to break the text. This is inefficient and should be avoided.

Important: by "block" we mean not only <fo:block> elements, but all non-inline elements, including table cells, as well.

For example, if the columns in your table become narrow when rendered in "A4" page size, you could:

  1. Turn the page to landscape orientation.
  2. Change to "A3" page size.
  3. Change to landscape orientation and "A3" page size.

Abbreviate long texts

As mentioned in the previous technique, long texts in narrow blocks are killing performance. (Long texts in wide blocks are no problem.) So, if you have little space, you could keep the text short by cutting that after the Nth character.

For example, keeping only the first 100 characters of the issue summary is as simple as:

<fo:block>$xmlutils.escape($stringutils.abbreviate($issue.summary, 100))</fo:block>

Disable complex scripts

Complex scripts is a feature in the PDF renderer that helps working with right-to-left writing (e.g. Arabic) and South-Asian languages (e.g. Thai). This is enabled by default and it will somewhat increase the memory requirements for processing documents.

If you are working with European languages only, you may want to turn it off:

  1. Login to Jira as administrator.
  2. Go to AppsManage your appsPDF Templates.
  3. Open the fop-config.xml file.
  4. Apply the change explained at point 3 in the Disabling complex scripts section.
  5. Save your changes.

Although it may not make a big difference, this is easy to turn it off, so it is worth to try.

Questions?

Ask us any time.