authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-09-04 07:13:22-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-04 07:13:22-07:00
log8e3aa324b57dd645980b203d5f8a5b9f9dc53a84
tree4d554b6f266679a37fecded80aff958980e110bc
parent7cf5b284e6e37895f535433c77f728b3e4292c9b
signature Signed by PGP key B5690EEEBB952194

perf(marketing): serve images at their display size (#9682)


8 files changed, 45 insertions(+), 13 deletions(-)

apps/marketing/package.json+2-1
...@@ -11,7 +11,8 @@...@@ -11,7 +11,8 @@
11 },11 },
12 "dependencies": {12 "dependencies": {
13 "@t3tools/shared": "workspace:*",13 "@t3tools/shared": "workspace:*",
14 "astro": "^7.0.3"14 "astro": "^7.0.3",
15 "sharp": "0.34.5"
15 },16 },
16 "devDependencies": {17 "devDependencies": {
17 "@astrojs/check": "^0.9.7",18 "@astrojs/check": "^0.9.7",
apps/marketing/public/app-desktop.webp deleted
Binary files a/apps/marketing/public/app-desktop.webp and /dev/null differ
apps/marketing/public/icon.webp deleted
Binary files a/apps/marketing/public/icon.webp and /dev/null differ
apps/marketing/src/assets/app-desktop.webp created
Binary files /dev/null and b/apps/marketing/src/assets/app-desktop.webp differ
apps/marketing/src/assets/icon.webp created
Binary files /dev/null and b/apps/marketing/src/assets/icon.webp differ
apps/marketing/src/layouts/Layout.astro+13-1
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1---1---
2import { Image } from "astro:assets";
3import appIcon from "../assets/icon.webp";
2import {4import {
3 ANDROID_PLAY_STORE_URL,5 ANDROID_PLAY_STORE_URL,
4 GITHUB_REPOSITORY_URL,6 GITHUB_REPOSITORY_URL,
...@@ -67,7 +69,17 @@ const {...@@ -67,7 +69,17 @@ const {
67 <footer class="footer">69 <footer class="footer">
68 <div class="footer-inner">70 <div class="footer-inner">
69 <div class="footer-brand">71 <div class="footer-brand">
70 <img src="/icon.webp" alt="" />72 <Image
73 src={appIcon}
74 alt=""
75 width={20}
76 height={20}
77 densities={[1, 2, 3]}
78 format="webp"
79 quality={90}
80 loading="lazy"
81 decoding="async"
82 />
71 <span>&copy; {new Date().getFullYear()} T3 Tools Inc · MIT licensed</span>83 <span>&copy; {new Date().getFullYear()} T3 Tools Inc · MIT licensed</span>
72 </div>84 </div>
73 <div class="footer-links">85 <div class="footer-links">
apps/marketing/src/pages/index.astro+26-8
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1---1---
2import { getImage } from "astro:assets";
3import desktopScreenshot from "../assets/app-desktop.webp";
2import Layout from "../layouts/Layout.astro";4import Layout from "../layouts/Layout.astro";
3import {5import {
4 ANDROID_PLAY_STORE_URL,6 ANDROID_PLAY_STORE_URL,
...@@ -8,6 +10,13 @@ import {...@@ -8,6 +10,13 @@ import {
8} from "../lib/site";10} from "../lib/site";
9import { tweets } from "../lib/tweets";11import { tweets } from "../lib/tweets";
1012
13const screenshot = await getImage({
14 src: desktopScreenshot,
15 widths: [864, 1180, 1728, 2360],
16 format: "webp",
17 quality: 90,
18});
19
11const desktopEndorsementRows = [20const desktopEndorsementRows = [
12 tweets.filter((_, index) => index % 2 === 0),21 tweets.filter((_, index) => index % 2 === 0),
13 tweets.filter((_, index) => index % 2 === 1),22 tweets.filter((_, index) => index % 2 === 1),
...@@ -80,14 +89,23 @@ const mobileEndorsementRows = [...@@ -80,14 +89,23 @@ const mobileEndorsementRows = [
80 <div data-rise style="--d:520ms">89 <div data-rise style="--d:520ms">
81 <div class="hero-preview">90 <div class="hero-preview">
82 <figure class="hero-screenshot-frame">91 <figure class="hero-screenshot-frame">
83 <img92 <picture>
84 src="/app-desktop.webp"93 <!-- Match the hidden mobile layout without requesting a screenshot. -->
85 alt="T3 Code with a settled thread beside its pull request diff"94 <source
86 width="2880"95 media="(max-width: 820px)"
87 height="1800"96 srcset="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
88 loading="eager"97 />
89 decoding="async"98 <img
90 />99 src={desktopScreenshot.src}
100 srcset={`${screenshot.srcSet.attribute}, ${desktopScreenshot.src} ${desktopScreenshot.width}w`}
101 sizes="(max-width: 960px) min(864px, calc(100vw - 20px)), min(1180px, calc(100vw - 60px))"
102 alt="T3 Code with a settled thread beside its pull request diff"
103 width={desktopScreenshot.width}
104 height={desktopScreenshot.height}
105 loading="eager"
106 decoding="async"
107 />
108 </picture>
91 </figure>109 </figure>
92 </div>110 </div>
93 </div>111 </div>
pnpm-lock.yaml+4-3
...@@ -206,6 +206,9 @@ importers:...@@ -206,6 +206,9 @@ importers:
206 astro:206 astro:
207 specifier: ^7.0.3207 specifier: ^7.0.3
208 version: 7.0.3(@astrojs/markdown-remark@7.2.0)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(aws4fetch@1.0.20)(idb-keyval@6.2.1)(ioredis@5.11.0)(jiti@2.7.0)(rollup@4.61.0)(terser@5.48.0)(typescript@6.0.3)(unrun@0.2.39)(yaml@2.9.0)208 version: 7.0.3(@astrojs/markdown-remark@7.2.0)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(aws4fetch@1.0.20)(idb-keyval@6.2.1)(ioredis@5.11.0)(jiti@2.7.0)(rollup@4.61.0)(terser@5.48.0)(typescript@6.0.3)(unrun@0.2.39)(yaml@2.9.0)
209 sharp:
210 specifier: 0.34.5
211 version: 0.34.5
209 devDependencies:212 devDependencies:
210 '@astrojs/check':213 '@astrojs/check':
211 specifier: ^0.9.7214 specifier: ^0.9.7
...@@ -12787,8 +12790,7 @@ snapshots:...@@ -12787,8 +12790,7 @@ snapshots:
1278712790
12788 '@iarna/toml@2.2.5': {}12791 '@iarna/toml@2.2.5': {}
1278912792
12790 '@img/colour@1.1.0':12793 '@img/colour@1.1.0': {}
12791 optional: true
1279212794
12793 '@img/sharp-darwin-arm64@0.34.5':12795 '@img/sharp-darwin-arm64@0.34.5':
12794 optionalDependencies:12796 optionalDependencies:
...@@ -20293,7 +20295,6 @@ snapshots:...@@ -20293,7 +20295,6 @@ snapshots:
20293 '@img/sharp-win32-arm64': 0.34.520295 '@img/sharp-win32-arm64': 0.34.5
20294 '@img/sharp-win32-ia32': 0.34.520296 '@img/sharp-win32-ia32': 0.34.5
20295 '@img/sharp-win32-x64': 0.34.520297 '@img/sharp-win32-x64': 0.34.5
20296 optional: true
2029720298
20298 shebang-command@2.0.0:20299 shebang-command@2.0.0:
20299 dependencies:20300 dependencies: