PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Short answer: scroll a PuppeteerSharp page only when scrolling is needed to trigger the site’s lazy loading, then wait for a concrete ready condition and call PdfAsync. Scrolling does not have a documented, general effect of cropping the PDF to the visible viewport. PuppeteerSharp generates PDFs with print CSS media by default; call EmulateMediaTypeAsync(MediaType.Screen) first when the page’s screen styles are required.
What scrolling does—and does not do
A Chromium PDF is a print rendering of the document, not a screenshot of whatever pixels are currently visible. The PuppeteerSharp Page API describes PdfAsync as generating a PDF with print CSS media. The documentation does not promise that window.scrollTo, a wheel event, or the current scroll offset becomes PDF crop bounds. The result can vary with the page layout, Chromium build, and PuppeteerSharp version.
Therefore decide which output you need before writing code:
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →- Whole printable document: load the required content, optionally scroll to activate lazy loading, then call
PdfAsync. - Screen-styled document: emulate screen media before calling
PdfAsync. - One visible scrolled viewport: treat this as a separate capture problem. The consulted API references do not document a PDF viewport-clipping option, so validate your exact runtime and inspect the generated file rather than assuming the scroll offset is honored.
For a guaranteed single viewport image, use a screenshot workflow instead of presenting an ordinary PDF as a crop.
#1 Best Overall
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Minimal PuppeteerSharp PDF workflow
The official examples show the essential sequence: launch a headless browser, create a page, navigate, wait for a known selector, and generate the file (official examples).
using PuppeteerSharp;
var url = "https://example.com/article";
await new BrowserFetcher().DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
});
await using var page = await browser.NewPageAsync();
await page.GoToAsync(url, new NavigationOptions
{
WaitUntil = new[] { WaitUntilNavigation.Networkidle0 }
});
await page.WaitForSelectorAsync("main");
await page.PdfAsync("article.pdf");
Networkidle0 is useful for pages that settle network requests, but it is not proof that every application has rendered its lower sections. A selector representing the actual finished content is a stronger readiness check.
Use screen CSS when the print stylesheet is wrong
Print media is the default. If the page’s print stylesheet hides navigation, changes colors, or rearranges columns in a way you do not want, select screen media immediately before PDF generation:
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →await page.EmulateMediaTypeAsync(MediaType.Screen);
await page.PdfAsync("screen-styled.pdf", new PdfOptions
{
PrintBackground = true,
WaitForFonts = true
});
The PdfOptions reference documents WaitForFonts as waiting for document.fonts.ready and defaulting to true. It also documents PrintBackground as defaulting to false and Scale as defaulting to 1, with a range of 0.1 to 2.
Rank #2
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Loading content revealed by scrolling
Infinite feeds, image lazy loading, and intersection-observer components may not fetch lower content until it enters or approaches the viewport. In that case scrolling is a loading trigger, not a PDF crop instruction.
Scroll incrementally and wait for growth
async Task ScrollToLoadEverythingAsync(IPage page)
{
var previousHeight = 0L;
for (var pass = 0; pass < 30; pass++)
{
var height = await page.EvaluateExpressionAsync<long>(
"document.documentElement.scrollHeight");
await page.EvaluateExpressionAsync(
"window.scrollTo(0, document.documentElement.scrollHeight)");
await Task.Delay(300);
var newHeight = await page.EvaluateExpressionAsync<long>(
"document.documentElement.scrollHeight");
if (newHeight == height && newHeight == previousHeight)
break;
previousHeight = height;
}
}
This loop is a generic trigger, not a guarantee. A site may paginate through a button, require a particular scroll container, or stop loading after a server-side limit. Prefer the site’s own completion signal when one exists.
Wait for a concrete completion condition
Wait for a final card, an application-specific “loaded” marker, or a known count of items. For example:
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsawait page.WaitForSelectorAsync("article[data-loaded='true']");
// Or wait for a site-specific marker:
await page.WaitForSelectorAsync("#feed-finished");
A fixed delay can be useful as a small settling pause, but it cannot establish that a slow request, failed image, or deferred JavaScript operation completed. Generate the PDF only after the condition that matters to your document is true.
Rank #3
A complete scrolled-page example
using PuppeteerSharp;
var url = "https://example.com/long-page";
await new BrowserFetcher().DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
});
await using var page = await browser.NewPageAsync();
await page.SetViewportAsync(new ViewPortOptions
{
Width = 1440,
Height = 900,
DeviceScaleFactor = 1
});
await page.GoToAsync(url, new NavigationOptions
{
WaitUntil = new[] { WaitUntilNavigation.Networkidle0 },
Timeout = 60_000
});
await page.WaitForSelectorAsync("main");
await ScrollToLoadEverythingAsync(page);
await page.WaitForSelectorAsync("#feed-finished");
await page.EmulateMediaTypeAsync(MediaType.Screen);
await page.PdfAsync("long-page.pdf", new PdfOptions
{
Format = PaperFormat.A4,
PrintBackground = true,
WaitForFonts = true,
Scale = 1
});
static async Task ScrollToLoadEverythingAsync(IPage page)
{
var previousHeight = 0L;
for (var pass = 0; pass < 30; pass++)
{
var height = await page.EvaluateExpressionAsync<long>(
"document.documentElement.scrollHeight");
await page.EvaluateExpressionAsync(
"window.scrollTo(0, document.documentElement.scrollHeight)");
await Task.Delay(300);
var newHeight = await page.EvaluateExpressionAsync<long>(
"document.documentElement.scrollHeight");
if (newHeight == height && newHeight == previousHeight) break;
previousHeight = height;
}
}
For a page whose lazy loader listens to an inner element, replace window.scrollTo with JavaScript that updates that element’s scrollTop. For a “Load more” control, click it and wait for the item count to increase instead of repeatedly scrolling the document.
PDF options that affect appearance
Keep rendering style, content readiness, and page geometry as separate decisions. The API reference includes options for paper size, custom width and height, scale, margins, backgrounds, tagged output, headers and footers, page ranges, and font readiness.
- Paper and margins: choose a format such as A4 or set explicit dimensions; margins prevent headers, footers, and body content from colliding.
- Scale: stay within the documented 0.1–2 range. Lower values fit more content but reduce legibility.
- PrintBackground: enable it when colored panels or background images are part of the intended design.
- WaitForFonts: leave the documented default of
trueunless you have a measured reason to change it. - Headers and footers: remember that templates use print-time markup and may need their own CSS.
- Page ranges: use them after verifying pagination; they do not turn a scroll position into a crop rectangle.
When you need one visible viewport
If the requirement is “the region shown after scrolling to 2,000 pixels,” do not infer that PdfAsync supports it. The available Page and PdfOptions references describe document PDF generation, not a scroll-offset clipping parameter (Page API, Page source). Test the installed PuppeteerSharp and Chrome versions, and inspect page boundaries, fixed elements, and scaling in the output. A screenshot of a controlled viewport is usually the more direct artifact; convert that image to a PDF only if your workflow specifically requires a PDF container.
Troubleshooting
The PDF contains only the initial items
The loader probably needs a scroll event, an inner scroll container, a button click, or a completion wait. Inspect which element actually scrolls, trigger that element, and wait for a selector or item-count change. Do not rely on a longer arbitrary delay.
Rank #4
The PDF looks different from the browser
Print CSS is active by default. Call EmulateMediaTypeAsync(MediaType.Screen) before PdfAsync, and enable PrintBackground if backgrounds are intentionally part of the output.
Fonts or icons are missing
Keep WaitForFonts = true, wait for a stable content marker, and verify that the headless browser can reach the font origin. A font request blocked by authentication, CSP, or a network policy cannot be repaired by PDF options.
Navigation times out
Set a timeout appropriate for the site, log the URL and exception, and use a narrower readiness strategy when the page keeps long-lived analytics connections open. Waiting for the required selector can be more reliable than requiring global network idleness.
Content is duplicated after scrolling
Virtualized lists may recycle DOM nodes. Capture after the application reports its settled state, and verify the PDF text or page count. If the list is intentionally virtualized, use the application’s export endpoint or pagination rather than assuming all records exist in the DOM.
Best Value
- JavaScript Jquery
- Introduces core programming concepts in JavaScript and jQuery
- Uses clear descriptions, inspiring examples, and easy-to-follow diagrams
The output is blank or missing protected content
Check authentication, cookies, redirects, bot checks, and resource requests in the same headless context. Confirm the page reached the expected URL and selector before generating the file.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Performance, reliability, and cost considerations
- Reuse a browser process for multiple pages, but create an isolated page or context per job so cookies and navigation state do not leak.
- Set an upper bound on scroll passes and overall job time; an endless feed otherwise creates an unbounded PDF.
- Capture at the smallest viewport and scale that meets readability requirements. Large dimensions and background images increase rendering and file time.
- Save diagnostic metadata such as final URL, page title, scroll passes, and the readiness condition used. Keep the PDF itself as the verification artifact.
- PuppeteerSharp PDF generation runs in Chrome headless, as stated by the Page API. Pin and test the PuppeteerSharp and Chromium versions used in production.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server when you need a rendered capture without maintaining PuppeteerSharp and Chromium. Its clean-shot pipeline accepts consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
For API parameters and all options, see the ScreenshotNeo documentation. A one-call PDF or image request can look like this (change the target URL as needed):
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo supports full-page captures with lazy images loaded, CSS-selector element captures, device presets or custom viewports, retina scale, PDF paper and margin controls, custom CSS and JavaScript, click and wait conditions, request blocking, headers and cookies, timezone and geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, and a usage API. The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Choosing the right approach
| Requirement | Best starting point | Important qualification |
|---|---|---|
| Control over .NET page logic and authentication | PuppeteerSharp | You own Chromium lifecycle, waits, and maintenance. |
| Print document with dynamic sections | PuppeteerSharp plus explicit readiness checks | Scrolling triggers loading; it is not documented as a crop control. |
| Screen-style rendering | PuppeteerSharp with screen media emulation | Call EmulateMediaTypeAsync(MediaType.Screen) before PDF generation. |
| Managed capture, clean pages, or AI-agent access | ScreenshotNeo | Use its API or MCP tools and inspect verdict/billing headers. |
Frequently Asked Questions
Does PuppeteerSharp PDF generation capture only the current scroll position?
No general behavior is documented. Treat scrolling as a way to trigger page code, not as a PDF crop instruction, and verify the output for your installed versions.
How can I force screen media for a PDF?
Call await page.EmulateMediaTypeAsync(MediaType.Screen) immediately before PdfAsync.
What is the safest wait condition for an infinite page?
Use a site-specific finished marker, final selector, or item-count condition, together with a maximum number of scroll passes and a job timeout.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Can I generate a PDF of just one scrolled viewport?
The cited PuppeteerSharp PDF references do not document viewport clipping by scroll offset. Validate a custom approach in your runtime, or capture a viewport screenshot and package it as a PDF if that meets your requirement.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

