Using browser context for social cards

Scott Hanselman recommended using the context instead of the browser object. Browser object creates a new context on each call which is a new process. Obviously we don't want that. 

Also added an extra check for a load based on network idle. This will not only ensure things are loaded, but there is a built in 500ms timeout looking for inactivity which will let the font rendering process do it's thing which seems to lag a tad with Chromium.

And while we are at it, preloading the font can't hurt.
This commit is contained in:
Phil Scott 2021-07-17 22:33:04 -04:00 committed by Patrik Svensson
parent 223642b797
commit c2b25eea8a
2 changed files with 14 additions and 7 deletions

View File

@ -51,6 +51,7 @@ namespace Docs.Pipelines
private IPlaywright _playwright;
private IBrowser _browser;
private WebApplication _app;
private IBrowserContext _context;
protected override async Task BeforeExecutionAsync(IExecutionContext context)
{
@ -74,10 +75,14 @@ namespace Docs.Pipelines
_playwright = await Playwright.CreateAsync().ConfigureAwait(false);
_browser = await _playwright.Chromium.LaunchAsync().ConfigureAwait(false);
_context = await _browser.NewContextAsync(new BrowserNewContextOptions {
ViewportSize = new ViewportSize { Width = 1200, Height = 618 },
}).ConfigureAwait(false);
}
protected override async Task FinallyAsync(IExecutionContext context)
{
await _context.DisposeAsync().ConfigureAwait(false);
await _browser.DisposeAsync().ConfigureAwait(false);
_playwright.Dispose();
await _app.DisposeAsync().ConfigureAwait(false);
@ -87,18 +92,19 @@ namespace Docs.Pipelines
protected override async Task<IEnumerable<IDocument>> ExecuteInputAsync(IDocument input, IExecutionContext context)
{
var url = _app.Urls.FirstOrDefault(u => u.StartsWith("http://"));
var page = await _browser.NewPageAsync(new BrowserNewPageOptions
{
ViewportSize = new ViewportSize { Width = 1200, Height = 618 },
}
);
var page = await _context.NewPageAsync().ConfigureAwait(false);
var title = input.GetString("Title");
var description = input.GetString("Description");
var highlights = input.GetList<string>("Highlights") ?? Array.Empty<string>();
await page.GotoAsync($"{url}/?title={title}&desc={description}&highlights={string.Join("||", highlights)}");
var bytes = await page.ScreenshotAsync();
// This will not just wait for the page to load over the network, but it'll also give
// chrome a chance to complete rendering of the fonts while the wait timeout completes.
await page.WaitForLoadStateAsync(LoadState.NetworkIdle).ConfigureAwait(false);
var bytes = await page.ScreenshotAsync().ConfigureAwait(false);
await page.CloseAsync().ConfigureAwait(false);
var destination = input.Destination.InsertSuffix("-social").ChangeExtension("png");
var doc = context.CreateDocument(

View File

@ -8,6 +8,7 @@
<html>
<head>
<link rel="preload" as="font" href="/static/CascadiaCodePL.woff2">
<link rel="stylesheet" href="static/styles.css" />
</head>
<body>