Skip to content
PDF Optimization

PDF Optimization

Optimization in UniPDF happens on the way out of the writer. You build an optimize.Options value, hand it to optimize.New, and attach the result with PdfWriter.SetOptimizer. Each enabled option becomes a pass in an optimize.Chain, and the chain runs over the assembled object list during Write. There is no separate optimize step and no in-place optimizer for an open document.

pdfWriter, err := reader.ToWriter(nil)
if err != nil {
    return err
}

pdfWriter.SetOptimizer(optimize.New(optimize.Options{
    CompressStreams:      true,
    UseObjectStreams:     true,
    SubsetFonts:          true,
    CleanUnusedResources: true,
}))

return pdfWriter.WriteToFile(outputPath)

The same works for creator output through Creator.SetPdfWriterAccessFunc, which hands you the writer before the document is assembled.

Where the size usually is

Worth knowing before turning options on at random. In most documents the bulk is in two places: embedded font programs and images. The structural passes, which deduplicate objects and compress streams, typically recover a fifth of the file and cost almost nothing. Subsetting fonts often doubles that on text-heavy documents but has to run text extraction over every page, so it is the slowest pass by a wide margin. Re-encoding or downsampling images is where the large reductions are on image-heavy files, and it is the only part that is lossy.

Nine of the eleven options are lossless. ImageQuality and ImageUpperPPI change pixels. CleanContentstream leaves rendering alone but removes marked-content operators, which breaks tagged documents.

Errors in a pass are swallowed. Chain.Optimize logs at debug level and continues with the objects it had, so a document that fails to optimize is written correctly and is simply larger than expected. If a saving does not show up, debug logging is what tells you why.

Optimization is not linearization

Two different goals that both get called optimizing.

ChangesEffect on size
SetOptimizerWhich objects exist and how their streams are encoded.Smaller.
SetLinearizedThe order objects are written in, plus hint tables.Slightly larger.

Linearization, or Fast Web View, exists so a viewer can render page 1 from the front of the file without downloading the rest. It costs a little size and buys first-page latency over the network. The two combine: the optimizer chain still runs when linearized output is enabled.

Where to look

GuideCovers
Optimizer optionsEvery optimize.Options field, which are lossless, and what each pass skips.
Font subsettingEmbedding only the glyphs in use, and which font formats can be subset.
LinearizationFast Web View output, object streams, and the memory cost.

Reducing file size is unrelated to conformance. If the output has to stay valid PDF/A, apply the standard as well and validate afterwards, since some passes remove structure that the A conformance levels require. See PDF/A and, for tagging, accessibility.

Last updated on