From c2b25eea8a2a55905d70b77601e0f12c75a482a1 Mon Sep 17 00:00:00 2001 From: Phil Scott Date: Sat, 17 Jul 2021 22:33:04 -0400 Subject: [PATCH] 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. --- docs/src/Pipelines/SocialCardPipeline.cs | 20 +++++++++++++------- docs/src/SocialCards/index.cshtml | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/src/Pipelines/SocialCardPipeline.cs b/docs/src/Pipelines/SocialCardPipeline.cs index 85a11b1..1ef0f70 100644 --- a/docs/src/Pipelines/SocialCardPipeline.cs +++ b/docs/src/Pipelines/SocialCardPipeline.cs @@ -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> 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("Highlights") ?? Array.Empty(); 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( @@ -107,7 +113,7 @@ namespace Docs.Pipelines new MetadataItems { { "DocId", input.Id }}, context.GetContentProvider(bytes)); - return new[] { doc }; + return new[] { doc }; } } } \ No newline at end of file diff --git a/docs/src/SocialCards/index.cshtml b/docs/src/SocialCards/index.cshtml index c851190..43868ed 100644 --- a/docs/src/SocialCards/index.cshtml +++ b/docs/src/SocialCards/index.cshtml @@ -8,6 +8,7 @@ +