← dompdf.js Studio

dompdf.js Image Formats: PNG, JPG, SVG, and WebP Explained

When you convert a web page to PDF, images are usually the make-or-break factor. Choose the wrong format and the output is either bloated, blurry, or simply broken; choose well and the document stays small, sharp, and faithful to the original design. dompdf.js takes a pure frontend approach: its Rust-powered WebAssembly core decodes images directly in the browser and embeds them into a vector PDF, with native support for the four mainstream formats — PNG, JPG, SVG, and WebP. That coverage maps cleanly onto real-world needs: PNG for screenshots and transparent assets, JPG for photographs, SVG for graphics that must scale without losing quality, and WebP for the smallest possible payloads. But support is only half the story. Each format carries a distinct trade-off between file size, quality, and capability, and the right choice depends on the content of the image and the document you are producing. This guide breaks down each format in turn: how it behaves inside a PDF render, where it shines, where it hurts, and the exact code needed to use it with dompdf.js. Along the way you will see a real example of embedding a transparent PNG, inlining an SVG chart as a data URL, and a decision checklist that turns format selection from guesswork into a repeatable engineering decision. By the end you will know which format to reach for in every situation, and why, so the PDFs your application generates are consistently small, sharp, and correct. The four formats are also the four you will meet in real asset pipelines, so the knowledge transfers directly to your existing image handling code, and the checklist at the end gives you a decision rule you can apply without re-deriving the trade-offs every time.

The Role of Each Format in PDF Rendering

A PDF is a vector document, but the images inside it can exist in several forms: lossless bitmaps, lossy bitmaps, and true vector graphics. When dompdf.js renders, it decodes each image according to its own encoding and embeds the result, which means the source format directly determines the quality, size, and scalability of that region inside the final file. Choose the right format and the output is both small and sharp; choose wrong and the region is either fuzzy, overweight, or a compatibility risk waiting to surface in a customer-facing document.

Before comparing formats, keep one mental model in mind: photographs are about compression efficiency, interface elements are about sharpness and transparency, and graphics are about vector fidelity. JPG trades quality for size through lossy compression, which suits photographs perfectly. PNG is lossless and carries an alpha channel, which makes it the standard for screenshots, icons, and logos. SVG describes shapes as vectors, so it scales to any size without pixelation. WebP is the modern contender, typically producing the smallest file at equivalent visual quality while also supporting transparency.

dompdf.js supports all four formats out of the box: put an img tag or a CSS background-image in your template and the engine handles the rest, with no conversion step and no extra configuration. The only real requirement is that the source file itself is valid and reachable: if an image renders correctly in the browser, it will render correctly in the PDF. Validate your assets in the page first, then hand them to the render pipeline, and the output will match what the user already saw on screen.

One more point worth keeping in mind: format support is not the same as format quality. The sharpness of a rendered PNG depends on the source file's own resolution and compression settings, because the pipeline faithfully reproduces what it is given. Standardizing image processing upstream — consistent export sizes, sane compression, clean sources — does more for PDF quality than debating format differences ever will.

PNG: Lossless Pixels and Transparent Backgrounds

PNG uses lossless compression, which makes it the right choice whenever pixels must be reproduced exactly: UI screenshots, diagrams, icons, and logos with transparent backgrounds. Inside the PDF, the alpha channel is preserved correctly, so transparent areas stay transparent against the white page instead of being filled with a matte color the way a JPG would force them to be. Design assets exported from Figma or Sketch are typically PNG already, so the format usually arrives with the asset rather than as a deliberate decision.

The cost of PNG is size. A photograph stored as PNG can be an order of magnitude larger than the same photo as JPG, and that waste becomes pure payload in your delivered PDF. PNG also comes in indexed 8-bit and truecolor 24-bit variants: palette PNGs are smaller but limit colors, so for screenshots and gradients prefer 24-bit. The simple rule is to never store photographs as PNG; keep PNG for the sharp-edged, transparent content it was designed for, and your files stay lean.

The example below embeds a transparent PNG logo into a template and hands it to addPage. The logo keeps its transparency in the generated PDF, with clean edges and no background fill. A relative path works fine here because the template and the page share an origin, which also means no CORS complications; the rendered result matches exactly what the browser shows, and the code remains short enough to read at a glance.

The scale option in the constructor is worth a mention here: passing scale: 2 doubles the render resolution, which makes icon edges crisper when the output is zoomed. It does not, however, improve the intrinsic quality of the source image — the bitmap's own resolution remains the ceiling, so downsampled sources stay soft no matter how high the scale goes.

import { DomPDF } from 'dompdf.js';

const html = `
  <style>
    body { font-family: 'Source Han Sans SC', sans-serif; }
    .logo { width: 120px; height: 40px; }
  </style>
  <h2>Order Confirmation</h2>
  <img class="logo" src="images/logo.png" alt="Company logo">
  <p>This document was generated in the browser with dompdf.js.</p>`;

const pdf = new DomPDF({ format: 'A4', margin: '20mm', scale: 2 });
pdf.addPage(html, { format: 'A4' });
pdf.save('order-png-demo.pdf');

JPG: Photographs and the Lossy Trade-off

JPG achieves small files through lossy compression, which is exactly what photographs, scans, and gradient-heavy backgrounds need. At equivalent visual quality a JPG is typically five to ten times smaller than a PNG, and in a document packed with images that difference decides the overall file size and the generation time. dompdf.js decodes JPG files natively, so the compression quality of the output is inherited from the source; if you need tighter control, re-encode before embedding rather than after.

The weaknesses are equally clear: no alpha channel, and visible artifacts under compression. Sharp-edged content — text, line art, screenshots — looks visibly degraded as JPG, and artifacts become more obvious when the image is enlarged in the PDF. The practical rule is simple: photographs use JPG, interface elements use PNG. If you must put text-heavy content through JPG, raise the export scale or lower the compression ratio, but understand that you are trading size for quality either way and plan accordingly.

A short preprocessing pass before embedding pays off: draw the image to a canvas and export it with canvas.toDataURL('image/jpeg', 0.85) to normalize the compression ratio across all assets. Quality between 0.8 and 0.9 is visually indistinguishable from the original for most purposes while cutting payload noticeably. The compressed version then flows into the template, making generation faster and the final PDF smaller, without a visible quality cost in the delivered document.

There is also a workflow argument for preprocessing JPGs centrally rather than per template: a single normalization function that decodes, re-encodes, and optionally downsizes every photo keeps quality consistent across documents and makes the generation pipeline's inputs predictable. It also gives you one place to change the compression policy when storage or bandwidth priorities shift.

SVG: Vector Graphics and a Data-URL Example

SVG describes graphics as paths, shapes, and text rather than pixels, so it stays perfectly sharp at any size. That makes it the natural choice for charts, maps, and logos that must look crisp both on screen and in print. dompdf.js renders SVG directly: your template can reference an svg file, or you can inline the SVG markup as a data URL and make the template fully self-contained, with no external resource to load, no path to break, and no network dependency at generation time.

The scaling advantage is the headline: the same chart can serve as a small thumbnail or a full-page figure with zero quality loss, where a bitmap would show visible pixelation at the larger size. The trade-off is parse and render cost — a chart with a few hundred nodes is cheap, but SVG files with tens of thousands of nodes can slow the layout stage noticeably. For very large diagrams, split them into smaller pieces or rasterize the parts that do not need to scale.

Two cautions apply when using SVG in templates. First, make sure the SVG does not reference external images or fonts, because those references can fail to resolve during parsing and leave gaps in the output. Second, advanced features such as complex filters and blend modes may be simplified by the PDF pipeline, so verify the final rendering with a real document before you commit to shipping an unmodified SVG, especially for client-facing deliverables.

When an SVG carries text, check the fonts it references as well: if the SVG relies on a font that is not loaded in the document, the text may fall back to a default face inside the PDF, which changes the visual weight of the chart. Embedding the text as paths, or ensuring the font is loaded and declared, keeps the rendered chart faithful to the design.

import { DomPDF } from 'dompdf.js';

const chartSvg = `
  <svg xmlns="http://www.w3.org/2000/svg" width="480" height="240" viewBox="0 0 480 240">
    <rect x="0" y="0" width="480" height="240" fill="#f5f7fa"/>
    <rect x="40" y="120" width="80" height="90" fill="#4c6ef5"/>
    <rect x="140" y="80" width="80" height="130" fill="#4c6ef5"/>
    <rect x="240" y="60" width="80" height="150" fill="#4c6ef5"/>
    <rect x="340" y="100" width="80" height="110" fill="#4c6ef5"/>
  </svg>`;

const html = `
  <style>body { font-family: 'Source Han Sans SC', sans-serif; }</style>
  <h2>Quarterly Sales Comparison</h2>
  <img src="data:image/svg+xml;base64,${btoa(chartSvg)}" style='width:100%'>`;

const pdf = new DomPDF({ format: 'A4', margin: '20mm' });
pdf.addPage(html, { format: 'A4' });
pdf.save('chart-svg-demo.pdf');

WebP: The Modern Format's Size Advantage

WebP supports both lossy and lossless compression and includes an alpha channel, which gives it an unusual combination of capabilities: at equivalent quality it is typically 25 to 35 percent smaller than JPG and often less than half the size of PNG. For image-heavy documents that difference shows up directly in the size of the delivered PDF, which in turn affects upload, download, and storage costs across the whole system. dompdf.js decodes WebP natively, so a template can reference webp files directly with no conversion and no loss of fidelity.

The caveat is compatibility. Modern browsers and toolchains handle WebP without issue, but older environments and downstream processing systems may not. If your users or your document pipeline are conservative, provide a PNG or JPG fallback. The picture element switches sources based on support cleanly, and the PDF pipeline consumes whichever resource is actually available, so you get the size win where it works and a safe fallback everywhere else without complicating the template.

The size benefit compounds in batch scenarios: a document with dozens of images can shrink by nearly half after switching to WebP, which makes every downstream step faster. Teams can build a single image pipeline that converts uploads to WebP while keeping the originals, then let PDF generation consume the WebP versions directly. One pipeline then optimizes both the website and the exports at once, which is the kind of shared infrastructure that pays for itself quickly.

A practical note on tooling: most asset pipelines now convert to WebP at upload time, which means the format decision happens once in the pipeline rather than in every template. The PDF generator then consumes the already-optimized files, and the whole organization benefits from the smaller payload without any per-document configuration. That is the highest-leverage way to adopt WebP.

Format Selection Checklist and Best Practices

Putting the comparisons together produces a practical decision checklist: photographs and scans go to JPG; screenshots, icons, logos, and transparent assets go to PNG; charts, maps, and badges that need to scale go to SVG; and anything where smallest size matters goes to WebP when the environment supports it. Following this checklist, most documents land on the optimal size-quality point without much deliberation, and new assets stop triggering format debates entirely.

A few universal rules round out the best practices. Normalize image dimensions before they enter a template: anything more than about twice the display size should be downsampled first, because the extra pixels buy nothing in the PDF. Serve images from a stable, cacheable path so repeated generation hits the cache instead of re-downloading. And gate generation on resource readiness — fonts via document.fonts.ready and images via decode() — so rendering never starts before assets actually exist, eliminating the most common source of broken output.

Finally, let data decide. Before committing to a format strategy, run a benchmark across format combinations and record the resulting PDF size and generation time for your real content. dompdf.js keeps a stable API, so switching formats is a template change, not a code change: the optimization is cheap to try and its benefits last. One measured round of tuning is enough to set a format policy the whole team can follow without revisiting the decision on every project.

One more practice worth adopting: keep a small format decision record for the team. When a new asset type appears, the record says which format family it belongs to and why, so the choice does not get re-litigated in every code review. Combined with the benchmark data, it turns format selection from tribal knowledge into an auditable engineering decision that new team members can follow without a long onboarding conversation.

⚡ 现场演示(点击生成 PDF)

下面的按钮用 dompdf.js 在浏览器端实时生成 PDF,无需后端:

Hello from dompdf.js!

这是由 dompdf.js 渲染的示例 PDF 内容。