Reducing PDF File Size: Optimization Techniques — TongoRender Blog
Back to Blog
guidesoptimizationperformancepdf

Reducing PDF File Size: Optimization Techniques

Practical techniques for reducing PDF file size: image compression, font subsetting, CSS optimization for print, and API quality settings for optimal results.

TongoRender TeamFebruary 8, 20268 min

A PDF that should be 200 KB often ends up being 5 MB. Oversized PDFs slow down downloads, fill up inboxes, and frustrate users. If your application generates PDFs at scale — invoices, reports, certificates, or catalogs — file size optimization directly impacts storage costs, bandwidth, and user experience.

What Makes PDFs Large?

PDF file size is driven by three main factors:

  1. Images — By far the biggest contributor. A single uncompressed PNG can add megabytes to a document.
  2. Fonts — Embedding full font families (every glyph in every weight) inflates the file unnecessarily.
  3. Metadata and structure — Excessive embedded metadata, JavaScript, form fields, and annotation layers add overhead.

Image Optimization

Images typically account for 80-95% of PDF file size. Here are the key strategies:

Choose the Right Format

  • JPEG — Best for photographs and complex images with many colors. Use quality 70-85 for good balance.
  • PNG — Best for screenshots, diagrams, and images with text or sharp edges. Use PNG-8 when possible.
  • WebP — Chromium-based PDF renderers can process WebP images, which are 25-35% smaller than JPEG at equivalent quality.
  • SVG — For icons, logos, and illustrations, SVG produces the smallest output because it is vector-based.

Resize Before Rendering

Do not send a 4000x3000 pixel image when it will be displayed at 400x300. Resize images to their display dimensions before including them in the HTML:

const sharp = require('sharp');

async function optimizeImage(inputPath, maxWidth = 800) {
  const metadata = await sharp(inputPath).metadata();

  if (metadata.width <= maxWidth) {
    return sharp(inputPath).jpeg({ quality: 80 }).toBuffer();
  }

  return sharp(inputPath)
    .resize(maxWidth)
    .jpeg({ quality: 80, progressive: true })
    .toBuffer();
}

// Convert to base64 data URI for embedding in HTML
const optimized = await optimizeImage('chart.png', 600);
const dataUri = `data:image/jpeg;base64,${optimized.toString('base64')}`;

Use CSS for Decorative Elements

Gradients, borders, shadows, and simple shapes should be CSS, not images:

<!-- Instead of a gradient image -->
<div style="background: linear-gradient(135deg, #667eea, #764ba2); height: 100px;"></div>

<!-- Instead of a divider image -->
<hr style="border: none; border-top: 2px solid #e2e8f0; margin: 20px 0;">

Font Optimization

Limit Font Variants

Each font weight and style is a separate file. Load only what you use:

<!-- Bad: loading 6 weights -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900" rel="stylesheet">

<!-- Good: only the weights you actually use -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700" rel="stylesheet">

Use System Fonts When Possible

For internal documents that do not need custom branding, system font stacks eliminate font embedding entirely:

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

Subset Custom Fonts

If you must use a custom font, subset it to include only the characters you need. Tools like glyphhanger can analyze your HTML and generate a minimal font file:

npx glyphhanger --whitelist="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,!?@#$%&*()-+= " --subset=CustomFont.woff2

CSS Optimization for Print

Remove visual elements that only matter on screen:

@media print {
  /* Hide navigation, sidebars, and interactive elements */
  nav, .sidebar, .no-print, button, .tooltip { display: none !important; }

  /* Remove shadows and transitions (they add rendering complexity) */
  * { box-shadow: none !important; text-shadow: none !important; transition: none !important; }

  /* Use solid backgrounds instead of gradients where possible */
  .header { background: #1a1a2e !important; }

  /* Avoid background images in print */
  .hero { background-image: none !important; }
}

TongoRender Quality Settings

TongoRender offers several options that affect output size:

const response = await fetch('https://api.tongorender.io/v1/pdf', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': process.env.TONGORENDER_API_KEY,
  },
  body: JSON.stringify({
    html: optimizedHtml,
    format: 'A4',
    // Reduce quality for smaller files
    printBackground: false,     // Skip background colors/images if not needed
    preferCSSPageSize: false,   // Use standard page size
    scale: 1,                   // Don't upscale (scale > 1 increases size)
  }),
});

Measuring Results

Track your optimization progress by measuring file sizes before and after each technique:

const fs = require('fs');

function formatSize(bytes) {
  if (bytes < 1024) return bytes + ' B';
  if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
  return (bytes / 1048576).toFixed(1) + ' MB';
}

const pdf = await generatePDF(html);
console.log(`PDF size: ${formatSize(pdf.length)}`);

// Compare with unoptimized version
const unoptimized = await generatePDF(originalHtml);
const savings = ((1 - pdf.length / unoptimized.length) * 100).toFixed(1);
console.log(`Size reduction: ${savings}%`);

Quick Reference Checklist

  • Resize images to display dimensions before rendering
  • Use JPEG (quality 75-85) for photos, SVG for icons
  • Load only the font weights you actually use
  • Consider system fonts for internal documents
  • Use CSS instead of images for gradients, borders, and shapes
  • Add @media print rules to hide screen-only elements
  • Set printBackground: false when backgrounds are not needed
  • Measure file sizes and set target budgets

With these optimizations, most documents can be reduced by 50-80% without visible quality loss. TongoRender renders optimized HTML efficiently, so the effort you put into template optimization translates directly into smaller PDFs.

Generate optimized PDFs with TongoRender — 100 free renders per month, no credit card required.

Share this articleShare on Twitter