Skip to content

Commit 08a8ebd

Browse files
perf: self-host anchor-js and add intrinsic dimensions to hero overlay image (Core Web Vitals) (#20725)
* perf: self-host anchor-js and add intrinsic dimensions to hero overlay image Two low-risk Core Web Vitals fixes surfaced while researching LCP/INP/CLS for pulumi.com against the web.dev vitals definitions: - Vendor anchor-js 4.1.0 (static/js/anchor-js.min.js) instead of loading it from cdnjs on every docs/tutorials/blog/authors/tags/registry page. The vendored copy is byte-identical to the cdnjs/jsdelivr release (verified against cdnjs's own published sha512 SRI hash). This removes a third-party DNS/TLS/connection dependency and single point of failure from every content page; it was already async+defer so this is not an LCP-blocking fix, but it does harden availability and drops one origin from the connection waterfall. - Add explicit width/height to the two call sites of the home/product-page hero overlay SVG in template-hero.html (split and centered layouts), which is frequently the LCP element. This follows the exact pattern of the already-merged PR #20561 (footer background SVG), whose partial (fingerprinted-img.html) already supports width/height -- the hero overlay call sites just weren't passing them. Eliminates a CLS source on the highest-traffic page on the site (home page: 26,424 views / 28 days, 94.9% desktop per GA4). * fix: derive hero overlay dimensions from code_aspect_ratio instead of SVG resource.Width resources.Get on an SVG returns a generic (non-image) resource with no .Width/.Height, so calling $overlayImgRes.Width/.Height on the hero code-overlay SVG broke template execution on the homepage and the /product/infrastructure-as-code/ page -- exactly the pages the CLS fix targeted. Derive the intrinsic width/height instead from the page's existing code_aspect_ratio frontmatter (e.g. "666/513"), which already drives the container's CSS aspect-ratio, so both stay in sync. Falls back to omitting width/height when the frontmatter value is absent or malformed. Fixed at both hero layout call sites (split and centered variants). Also rewrote the anchor-js vendoring comment in head.html to cite a verifiable fact (the vendored file's SHA-512 matches cdnjs's own published SRI hash for anchor-js@4.1.0/anchor.min.js) instead of an unfalsifiable "byte-identical" claim. Verified with a full `make build`: the homepage and /product/infrastructure-as-code/ now render the overlay img tag with correct width/height attributes and no template errors. --------- Co-authored-by: workprentice <257153108+workprentice@users.noreply.github.com>
1 parent b16c29f commit 08a8ebd

3 files changed

Lines changed: 39 additions & 4 deletions

File tree

layouts/partials/head.html

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,9 +507,16 @@
507507

508508
{{- end }}
509509

510-
<!-- Apply anchor links to headings in the docs, blog and taxonomy pages. -->
510+
<!-- Apply anchor links to headings in the docs, blog and taxonomy pages.
511+
Self-hosted (static/js/anchor-js.min.js, vendored from anchor-js v4.1.0's anchor.min.js)
512+
rather than loaded from cdnjs: this removes a third-party render-relevant dependency and
513+
its DNS/TLS/connection setup cost from every docs/tutorials/blog/authors/tags/registry
514+
page, and eliminates the single point of failure where a cdnjs slowdown or outage delayed
515+
anchors sitewide. The vendored file's SHA-512 matches cdnjs's own published SRI hash for
516+
anchor-js@4.1.0/anchor.min.js (sha512-8IXYpHF8LXD5JYo9bhj3ja2uLOJ7QJ/o+F1DSitgu0HmT5W0Vv3vTi+p5nn9jbi/cPnskPO9qT0RY5VAdofRJQ==,
517+
per https://api.cdnjs.com/libraries/anchor-js/4.1.0), confirming it is unmodified. -->
511518
{{ if and (not .IsHome) (.Section) (in "docs tutorials blog authors tags registry" .Section) }}
512-
<script async defer src="//cdnjs.cloudflare.com/ajax/libs/anchor-js/4.1.0/anchor.min.js"></script>
519+
<script async defer src="{{ "js/anchor-js.min.js" | relURL }}"></script>
513520
<script>
514521
// Wait for the window's `load` event to ensure the deferred anchor.js script has finished loading as well.
515522
window.addEventListener("load", function (event) {

layouts/partials/template-partials/template-hero.html

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,18 @@ <h1 class="product-hero-heading text-left">
171171
{{ partial "code-snippets.html" (dict "code_snippets" $codeSnippets "title" $codeTitle) }}
172172
</div>
173173
{{ if $overlayImage }}
174-
{{ partial "fingerprinted-img.html" (dict "src" $overlayImage "alt" $overlayAlt "class" "hero-code-overlay" "loading" "eager" "fetchpriority" "high" "ariaHidden" "true") }}
174+
{{ $overlayImgArgs := dict "src" $overlayImage "alt" $overlayAlt "class" "hero-code-overlay" "loading" "eager" "fetchpriority" "high" "ariaHidden" "true" }}
175+
{{/* The overlay is an SVG, which resources.Get returns as a generic (non-image)
176+
resource with no .Width/.Height. Derive intrinsic dimensions instead from the
177+
page's code_aspect_ratio frontmatter (e.g. "666/513"), which already drives the
178+
container's CSS aspect-ratio above, so both stay in sync. */}}
179+
{{ with $codeAspectRatio }}
180+
{{ $ratioParts := strings.Split . "/" }}
181+
{{ if eq (len $ratioParts) 2 }}
182+
{{ $overlayImgArgs = merge $overlayImgArgs (dict "width" (index $ratioParts 0) "height" (index $ratioParts 1)) }}
183+
{{ end }}
184+
{{ end }}
185+
{{ partial "fingerprinted-img.html" $overlayImgArgs }}
175186
{{ end }}
176187
</div>
177188
{{ else }}
@@ -245,7 +256,18 @@ <h1 class="product-hero-heading">
245256
{{ partial "code-snippets.html" (dict "code_snippets" $codeSnippets "title" $codeTitle) }}
246257
</div>
247258
{{ if $overlayImage }}
248-
{{ partial "fingerprinted-img.html" (dict "src" $overlayImage "alt" $overlayAlt "class" "hero-code-overlay" "loading" "eager" "fetchpriority" "high" "ariaHidden" "true") }}
259+
{{ $overlayImgArgs := dict "src" $overlayImage "alt" $overlayAlt "class" "hero-code-overlay" "loading" "eager" "fetchpriority" "high" "ariaHidden" "true" }}
260+
{{/* The overlay is an SVG, which resources.Get returns as a generic (non-image)
261+
resource with no .Width/.Height. Derive intrinsic dimensions instead from the
262+
page's code_aspect_ratio frontmatter (e.g. "666/513"), which already drives the
263+
container's CSS aspect-ratio above, so both stay in sync. */}}
264+
{{ with $codeAspectRatio }}
265+
{{ $ratioParts := strings.Split . "/" }}
266+
{{ if eq (len $ratioParts) 2 }}
267+
{{ $overlayImgArgs = merge $overlayImgArgs (dict "width" (index $ratioParts 0) "height" (index $ratioParts 1)) }}
268+
{{ end }}
269+
{{ end }}
270+
{{ partial "fingerprinted-img.html" $overlayImgArgs }}
249271
{{ end }}
250272
</div>
251273
</div>

static/js/anchor-js.min.js

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)