如何使用 WaitFor 类延迟 C# PDF 渲染

This article was translated from English: Does it need improvement?
Translated
View the article in English

查克尼特·宾

在渲染PDF文档时,常见的问题是渲染过程在所有必要的资产和javascript动画完成加载之前就发生了。 这可能导致PDF文档的渲染不完整或错误。 最初,我们通过允许用户设置任意延迟来解决这个问题。 然而,依赖于任意的延迟并不是一种可靠或有效的方法。

为了提供更强大的解决方案,我们实现了一个WaitFor类,用以增强PDF的渲染过程。 RenderOptions 中的 WaitFor 对象提供了多个选项,包括:

默认立即渲染示例

默认情况下,页面加载完成后立即开始渲染过程。 如果您想要正常渲染,不需要调用PageLoad方法。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-pageload.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render as soon as the page is loaded
renderer.RenderingOptions.WaitFor.PageLoad();

PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

自定义渲染延迟示例

在需要在渲染PDF之前特定延迟的情况下,您可以设置任意数量的毫秒作为延迟。 这提供了灵活性以适应任何特定的时间要求。

此选项的工作方式与使用 RenderingOptions.RenderDelay 属性的旧实现相同。 但是,旧属性已被弃用,强烈建议使用新的 API,RenderingOptions.WaitFor.RenderDelay

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-delay-time.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render after 3000ms
renderer.RenderingOptions.WaitFor.RenderDelay(3000);

PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");
Imports IronPdf

Private renderer As New ChromePdfRenderer()

' Render after 3000ms
renderer.RenderingOptions.WaitFor.RenderDelay(3000)

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>testing</h1>")
VB   C#

所有字体已加载示例

"(《世界人权宣言》) 已加载所有字体 方法中的 等待 class 允许 PDF 渲染过程暂停,直到从 Google Fonts 或其他服务器加载所有字体。 这确保最终的PDF包含所有必需的字体,保留了文档预期的排版和视觉外观。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-all-fonts.cs
using IronPdf;

string htmlContent = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
  <meta charset=""UTF-8"">
  <title>Test Registration of Extension</title>
  <!-- for google web fonts -->
  <link rel=""preconnect"" href=""https://fonts.googleapis.com"">
  <link rel=""preconnect"" href=""https://fonts.gstatic.com"" crossorigin>
  <link rel=""stylesheet"" href=""https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"" >

  <style>
  /* for remote fonts */
  @font-face {
    font-family: 'CustomFont';
    src: url('https://stage.gradfinale.co.uk/tcpdf/fonts/avgr65wttf.ttf');
  }
  p#p1 { font-family: CustomFont, sans-serif; }

  /* for local fonts */
  @font-face {
    font-family: 'LocalCustomFont';
    src: local('Arial');
  }
  p#p3 { font-family: LocalCustomFont, sans-serif; }
  </style>
</head>
<body>
	<h1>This is Delayed Render Test!</h1>
	<p style=""font-family: Roboto, monospace;"">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla scelerisque ligula venenatis erat <strong>scelerisque</strong> auctor.</p>
	<p id=""p1"">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla scelerisque ligula venenatis erat <strong>scelerisque</strong> auctor.</p>
	<p id=""p3"">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla scelerisque ligula venenatis erat <strong>scelerisque</strong> auctor.</p>
</body>
</html>)";

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

PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

自定义JavaScript执行示例

为了更好地控制渲染过程,我们的功能允许您指定一个自定义的JavaScript函数,在渲染PDF文档之前需要执行该函数。 这使您可以在启动渲染过程之前执行任何必要的任务或检查。 这使用户可以控制何时触发渲染。

在JavaScript中,函数window.ironpdf.notifyRender()用于触发渲染任务。 一旦notifyRender()`被调用时,渲染过程将开始。 您可以完全控制何时调用该函数。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-javascript.cs
using IronPdf;

string html = @"<!DOCTYPE html>
<html>
<body>
<h1>Testing</h1>
<script type='text/javascript'>

// Set delay
setTimeout(function() {
    window.ironpdf.notifyRender();
}, 1000);

</script>
</body>
</html>";

ChromePdfRenderOptions renderingOptions = new ChromePdfRenderOptions();

// Set rendering to wait for the notifyRender function
renderingOptions.WaitFor.JavaScript(5000);

PdfDocument pdf = ChromePdfRenderer.StaticRenderHtmlAsPdf(html, renderingOptions);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

HTML 元素示例

使用此选项,渲染过程可以设置为等待特定的HTML元素,例如元素ID、名称、标签名称,甚至使用查询选择器来定位元素。

等待元素ID

在下面的代码示例中,渲染将等待特定的元素 ID。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-html-element-id.cs
using IronPdf;

string htmlContent = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
  <meta charset=""UTF-8"">
  <title>Delayed render tests</title>
  <script type=""text/javascript"">
	setTimeout(function() {
		var h1Tag = document.createElement(""h1"");
		h1Tag.innerHTML = ""bla bla bla"";
		h1Tag.setAttribute(""id"", ""myid"");

        var block = document.querySelector(""div#x"");
		block.appendChild(h1Tag);
	}, 1000);
  </script>
</head>
<body>
	<h1>This is Delayed Render Test!</h1>
    <div id=""x""></div>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.HtmlElementById("myid", 5000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

等待元素名称

在下面的代码示例中,渲染过程将等待特定的元素名称。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-html-element-name.cs
using IronPdf;

string htmlContent = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
  <meta charset=""UTF-8"">
  <title>Delayed render tests</title>
  <script type=""text/javascript"">
	setTimeout(function() {
		var h1Tag = document.createElement(""h1"");
		h1Tag.innerHTML = ""bla bla bla"";
		h1Tag.setAttribute(""name"", ""myName"");

        var block = document.querySelector(""div#x"");
		block.appendChild(h1Tag);
	}, 1000);
  </script>
</head>
<body>
	<h1>This is Delayed Render Test!</h1>
    <div id=""x""></div>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.HtmlElementByName("myName", 5000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

等待元素标签名

在下面的代码示例中,渲染过程将等待特定的元素标签名称。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-html-element-tag-name.cs
using IronPdf;

string htmlContent = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
  <meta charset=""UTF-8"">
  <title>Delayed render tests</title>
  <script type=""text/javascript"">
	setTimeout(function() {
		var newElem = document.createElement(""h2"");
		newElem.innerHTML = ""bla bla bla"";

        var block = document.querySelector(""div#x"");
		block.appendChild(newElem);
	}, 1000);
  </script>
</head>
<body>
	<h1>This is Delayed Render Test!</h1>
    <div id=""x""></div>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.HtmlElementByTagName("h2", 5000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

使用查询选择器

在以下代码示例中,渲染过程将等待查询选择器选择的元素。 HtmlQuerySelector 方法将等待一个 img 标签,具有 id 为 'myid'class 为 'blablastyle'

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-html-element-query-selector.cs
using IronPdf;

string htmlContent = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
  <meta charset=""UTF-8"">
  <title>Test Registration of Extension</title>
  <script type=""text/javascript"">
	setTimeout(function() {
		var img = document.createElement(""img"");
		img.onload = function() {
			img.setAttribute(""id"", ""myid"");
			img.setAttribute(""class"", ""blablastyle"");
			var block = document.getElementById(""x"");
			block.appendChild(img);
		};
		img.src = ""https://www.w3schools.com/images/picture.jpg"";	// .src after .onload to ignore cached, if any
	}, 1000);
  </script>
</head>
<body>
	<h1>This is Delayed Render Test!</h1>
    <div id=""x""></div>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("img#myid.blablastyle", 5000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

网络空闲示例

无网络活动

此类型的网络空闲状态允许您等待直到没有网络活动,这通常表明内容已完全加载。 这适用于单页应用程序。(SPA)或一个简单的网页,没有任何长轮询网络请求或持续的网络活动。

渲染过程将仅在网络活动至少500毫秒没有进行中时开始。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-network-idle-0.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render unless there has been no network activity for at least 500ms
renderer.RenderingOptions.WaitFor.NetworkIdle0();

PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

两种网络活动被允许

NetworkIdle2方法适用于具有长轮询网络请求或心跳ping的Web应用程序或网页。 通常涉及1-2个请求。 在这种情况下,即使这些请求正在进行,也不会被认为是使网络空闲事件触发无效,因为最多允许有两个这样的请求。

在开始渲染过程前,至少应有500毫秒内最多剩余两个网络活动。 此选项提供了一个快速配置,用于处理固定数量的网络活动。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-network-idle-2.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render unless there are at most 2 network activities for at least 500ms
renderer.RenderingOptions.WaitFor.NetworkIdle2();

PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

自定义网络活动限额

在涉及多个网络请求的情况下,您可以自定义网络空闲持续时间允许的网络请求数量,这些请求不会导致网络空闲事件的触发失效。 此选项适用于具有特定要求的 Web 应用程序或网页,不符合前两种方法。 通过提供这种定制,我们确保在不同情况下能够应对广泛的用例。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-customize-network.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render unless there are at most 5 network activities for at least 1000ms
renderer.RenderingOptions.WaitFor.NetworkIdle(1000, 5);

PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");
Imports IronPdf

Private renderer As New ChromePdfRenderer()

' Render unless there are at most 5 network activities for at least 1000ms
renderer.RenderingOptions.WaitFor.NetworkIdle(1000, 5)

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>testing</h1>")
VB   C#

设置最长等待时间

此外,JavaScriptNetworkIdleNetworkIdle0NetworkIdle2 方法也允许您设置最大等待时间,以确保等待不会无休止。这些方法的 maxWaitTime 参数可用于此目的。

请注意
所有指定的时间值均以毫秒为单位。

查克尼特·宾

软件工程师

Chaknith 是开发者中的福尔摩斯。他第一次意识到自己可能在软件工程方面有前途,是在他出于乐趣做代码挑战的时候。他的重点是 IronXL 和 IronBarcode,但他为能帮助客户解决每一款产品的问题而感到自豪。Chaknith 利用他从直接与客户交谈中获得的知识,帮助进一步改进产品。他的轶事反馈不仅仅局限于 Jira 票据,还支持产品开发、文档编写和市场营销,从而提升客户的整体体验。当他不在办公室时,他可能会在学习机器学习、编程或徒步旅行。