DEV Community

IronSoftware
IronSoftware

Posted on

Wait For [PDF Rendering] in C# (Using IronPDF Guide)

Our marketing team's landing pages looked perfect in browsers but terrible as PDFs. Web fonts showed as system defaults, hero images were missing, and charts rendered as empty boxes.

The issue? IronPDF was capturing PDFs before asynchronous content loaded. The WaitFor class solved this. Here's how.

Why Do PDFs Render Incorrectly?

Modern web pages load content asynchronously:

  • Web fonts from Google Fonts or Typekit
  • Images via lazy loading
  • Charts rendered by JavaScript
  • Ajax-loaded data

When you convert HTML to PDF, the renderer might capture the page before these resources finish loading.

using IronPdf;
// Install via NuGet: Install-Package IronPdf

var renderer = new ChromePdfRenderer();

// Without WaitFor: PDF renders immediately, before fonts/images load
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("incomplete.pdf");
Enter fullscreen mode Exit fullscreen mode

The PDF shows "Loading..." placeholders and fallback fonts because rendering happened too soon.

How Do I Wait for Fonts to Load?

Use WaitFor.AllFontsLoaded():

using IronPdf;

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded();

var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("with-fonts.pdf");
Enter fullscreen mode Exit fullscreen mode

IronPDF now waits until all @font-face declarations finish loading before rendering. Web fonts appear correctly in the PDF.

Can I Wait a Specific Amount of Time?

Yes. Use RenderDelay for a fixed wait:

using IronPdf;

var renderer = new ChromePdfRenderer();

// Wait 3 seconds before rendering
renderer.RenderingOptions.WaitFor.RenderDelay(3000);

var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("delayed.pdf");
Enter fullscreen mode Exit fullscreen mode

This gives JavaScript time to execute. I use 2-3 seconds for pages with moderate JS, 5+ seconds for heavy single-page applications.

How Do I Wait for Specific Elements?

Wait for an element to appear before rendering:

using IronPdf;

var renderer = new ChromePdfRenderer();

// Wait for element with ID "chart-loaded"
renderer.RenderingOptions.WaitFor.HtmlElementById("chart-loaded");

var pdf = renderer.RenderUrlAsPdf("https://example.com/dashboard");
pdf.SaveAs("with-chart.pdf");
Enter fullscreen mode Exit fullscreen mode

Your JavaScript sets an element when rendering completes:

<div id="chart-container"></div>
<script>
  renderChart().then(() => {
    // Signal to IronPDF that chart is ready
    document.body.insertAdjacentHTML('beforeend', '<div id="chart-loaded"></div>');
  });
</script>
Enter fullscreen mode Exit fullscreen mode

IronPDF waits until #chart-loaded exists before capturing the PDF.

Can I Wait for Multiple Elements?

Yes. Wait by tag name, class, or query selector:

using IronPdf;

var renderer = new ChromePdfRenderer();

// Wait for all images to have loaded attribute
renderer.RenderingOptions.WaitFor.HtmlElementByQuerySelector("img[loaded='true']");

var pdf = renderer.RenderUrlAsPdf("https://example.com/gallery");
pdf.SaveAs("with-images.pdf");
Enter fullscreen mode Exit fullscreen mode

Your page sets attributes as images load:

document.querySelectorAll('img').forEach(img => {
  img.onload = () => img.setAttribute('loaded', 'true');
});
Enter fullscreen mode Exit fullscreen mode

How Do I Wait for Network Activity to Stop?

Use NetworkIdle:

using IronPdf;

var renderer = new ChromePdfRenderer();

// Wait until network is idle (no requests for 500ms)
renderer.RenderingOptions.WaitFor.NetworkIdle();

var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("network-idle.pdf");
Enter fullscreen mode Exit fullscreen mode

This waits until all Ajax requests, image loads, and other network activity finishes. Useful for data-heavy dashboards.

Can I Customize the Network Idle Threshold?

Yes. Specify how many active requests are acceptable:

using IronPdf;

var renderer = new ChromePdfRenderer();

// Wait until 2 or fewer active requests
renderer.RenderingOptions.WaitFor.NetworkIdle(2);

var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("mostly-loaded.pdf");
Enter fullscreen mode Exit fullscreen mode

NetworkIdle(0) waits for zero active requests. NetworkIdle(2) allows up to 2 ongoing (e.g., long-polling connections).

How Do I Trigger Rendering from JavaScript?

Call a JavaScript function that signals when ready:

using IronPdf;

var renderer = new ChromePdfRenderer();

// Wait for window.ironPdfReady to be true
renderer.RenderingOptions.WaitFor.JavaScript("window.ironPdfReady === true");

var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("js-triggered.pdf");
Enter fullscreen mode Exit fullscreen mode

Your page sets the flag when rendering should begin:

<script>
  async function loadData() {
    await fetchDataFromAPI();
    await renderCharts();
    window.ironPdfReady = true; // Signal to IronPDF
  }

  loadData();
</script>
Enter fullscreen mode Exit fullscreen mode

IronPDF polls the JavaScript expression. When it evaluates to true, rendering starts.

What's the Difference Between WaitFor Methods?

  • PageLoad: Default. Renders immediately after HTML loads (no waiting)
  • RenderDelay: Fixed time delay (e.g., 3000ms)
  • AllFontsLoaded: Waits for @font-face fonts
  • NetworkIdle: Waits for network requests to finish
  • HtmlElement...: Waits for specific DOM elements
  • JavaScript: Waits for custom JS expression to be true

Choose based on what your page needs to load.

Can I Combine Multiple WaitFor Conditions?

No. Only one WaitFor condition applies. Choose the most appropriate:

// This only uses JavaScript condition (last one set)
renderer.RenderingOptions.WaitFor.AllFontsLoaded();
renderer.RenderingOptions.WaitFor.JavaScript("window.ready");

// Only window.ready is checked
Enter fullscreen mode Exit fullscreen mode

If you need multiple conditions, implement them in your JavaScript:

window.ready = async function() {
  await document.fonts.ready; // Fonts loaded
  await waitForNetworkIdle(); // Network idle
  return true;
};
Enter fullscreen mode Exit fullscreen mode

Then use JavaScript("window.ready()").

How Long Should I Wait?

Start with these guidelines:

  • Static content: No wait needed (default PageLoad)
  • Web fonts only: AllFontsLoaded()
  • Light JavaScript: RenderDelay(1000) - 1 second
  • Ajax data: NetworkIdle() or element-based wait
  • Heavy SPAs (React/Vue/Angular): RenderDelay(3000) or JavaScript trigger
  • Complex dashboards: NetworkIdle() + RenderDelay(5000) fallback

Monitor rendering times and adjust based on results.

What Happens if WaitFor Times Out?

IronPDF has a global timeout (default 60 seconds). If WaitFor doesn't complete, rendering fails with a timeout exception.

Increase the timeout for slow pages:

using IronPdf;

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.Timeout = 120; // 120 seconds

renderer.RenderingOptions.WaitFor.NetworkIdle();

var pdf = renderer.RenderUrlAsPdf("https://slow-site.com");
Enter fullscreen mode Exit fullscreen mode

Can I Test WaitFor Locally?

Yes. Create test HTML with delays:

<!DOCTYPE html>
<html>
<head>
  <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
</head>
<body style="font-family: 'Roboto';">
  <div id="content">Loading...</div>
  <script>
    setTimeout(() => {
      document.getElementById('content').innerText = 'Content Loaded!';
      document.body.insertAdjacentHTML('beforeend', '<div id="ready"></div>');
    }, 2000);
  </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Test different WaitFor strategies:

// Without WaitFor: PDF shows "Loading..."
var pdf1 = renderer.RenderHtmlFileAsPdf("test.html");

// With WaitFor: PDF shows "Content Loaded!"
renderer.RenderingOptions.WaitFor.HtmlElementById("ready");
var pdf2 = renderer.RenderHtmlFileAsPdf("test.html");
Enter fullscreen mode Exit fullscreen mode

How Does WaitFor Affect Performance?

WaitFor adds latency proportional to wait time:

  • AllFontsLoaded: +200-500ms (font load time)
  • RenderDelay(3000): +3000ms fixed
  • NetworkIdle: Variable (depends on network activity)
  • Element-based: Variable (depends on when element appears)

For high-throughput systems, profile actual wait times and optimize:

var stopwatch = System.Diagnostics.Stopwatch.StartNew();
renderer.RenderingOptions.WaitFor.AllFontsLoaded();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
stopwatch.Stop();

Console.WriteLine($"Rendering took {stopwatch.ElapsedMilliseconds}ms");
Enter fullscreen mode Exit fullscreen mode

If avg wait time is 500ms but you're using RenderDelay(3000), you're wasting 2.5 seconds per PDF.

Can I Disable WaitFor?

Yes. Call PageLoad() (or don't set any WaitFor):

var renderer = new ChromePdfRenderer();
// No WaitFor set - renders immediately after page load

var pdf = renderer.RenderHtmlAsPdf("<h1>Static Content</h1>");
Enter fullscreen mode Exit fullscreen mode

Static HTML renders fastest without waiting.

What About Legacy RenderDelay Property?

The old RenderingOptions.RenderDelay property still works but is deprecated:

// Old (deprecated)
renderer.RenderingOptions.RenderDelay = 3000;

// New (recommended)
renderer.RenderingOptions.WaitFor.RenderDelay(3000);
Enter fullscreen mode Exit fullscreen mode

Use the new WaitFor.RenderDelay method for future compatibility.


Written by Jacob Mellor, CTO at Iron Software. Jacob created IronPDF and leads a team of 50+ engineers building .NET document processing libraries.

Top comments (0)