Skip to content

Commit 1ef499c

Browse files
Experimental optimisation
1 parent e47cfdc commit 1ef499c

File tree

3 files changed

+196
-49
lines changed

3 files changed

+196
-49
lines changed

src/components/homepage/Audiodotcom.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const optimizedBg = await getImage({
1818
const releaseVideoPlaceholderImage = await getImage({
1919
src: VideoPlaceholder,
2020
format: "webp",
21-
width: 736,
21+
width: 732,
2222
quality: 80,
2323
});
2424

src/components/homepage/ReleaseVideo.astro

Lines changed: 102 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,119 @@ import ReleaseVideoPlaceholder from "../../assets/img/audacity-placeholder.webp"
44
import PromoVideoPlaceholder from "../../assets/img/promo/ace-placeholder.webp";
55
import FeaturedVideo from "../video/FeaturedVideo";
66
7+
// Generate WebP format thumbnails
78
const releaseVideoPlaceholderImage = await getImage({
89
src: ReleaseVideoPlaceholder,
910
format: 'webp',
10-
width: 736,
11-
quality: 80,
11+
width: 732,
12+
height: 412, // 16:9 aspect ratio
13+
quality: 75,
14+
});
15+
16+
const releaseVideoPlaceholderImageMobile = await getImage({
17+
src: ReleaseVideoPlaceholder,
18+
format: 'webp',
19+
width: 400,
20+
height: 225, // Maintaining the same aspect ratio
21+
quality: 75,
1222
});
1323
1424
const featuredVideoPlaceholderImage = await getImage({
1525
src: PromoVideoPlaceholder,
1626
format: 'webp',
17-
width: 736,
18-
quality: 80,
27+
width: 732,
28+
height: 412,
29+
quality: 75,
30+
});
31+
32+
const featuredVideoPlaceholderImageMobile = await getImage({
33+
src: PromoVideoPlaceholder,
34+
format: 'webp',
35+
width: 400,
36+
height: 225,
37+
quality: 75,
38+
});
39+
40+
// Generate AVIF format thumbnails (superior compression)
41+
const releaseVideoPlaceholderImageAvif = await getImage({
42+
src: ReleaseVideoPlaceholder,
43+
format: 'avif',
44+
width: 732,
45+
height: 412,
46+
quality: 70,
47+
});
48+
49+
const releaseVideoPlaceholderImageMobileAvif = await getImage({
50+
src: ReleaseVideoPlaceholder,
51+
format: 'avif',
52+
width: 400,
53+
height: 225,
54+
quality: 70,
55+
});
56+
57+
const featuredVideoPlaceholderImageAvif = await getImage({
58+
src: PromoVideoPlaceholder,
59+
format: 'avif',
60+
width: 732,
61+
height: 412,
62+
quality: 70,
63+
});
64+
65+
const featuredVideoPlaceholderImageMobileAvif = await getImage({
66+
src: PromoVideoPlaceholder,
67+
format: 'avif',
68+
width: 400,
69+
height: 225,
70+
quality: 70,
1971
});
2072
2173
const releaseVideo = {
22-
title:"Our latest release",
23-
label:"Master channel, new realtime effects & more!",
24-
placeholderImage: releaseVideoPlaceholderImage.src,
25-
imageAltText: "Video thumbnial: Audacity 3.6 - New effects",
26-
videoURL:"https://www.youtube-nocookie.com/embed/f5TXPUOFH6A?autoplay=1",
74+
title: "Our latest release",
75+
label: "Master channel, new realtime effects & more!",
76+
placeholderImages: {
77+
webp: {
78+
default: releaseVideoPlaceholderImage.src,
79+
mobile: releaseVideoPlaceholderImageMobile.src,
80+
},
81+
avif: {
82+
default: releaseVideoPlaceholderImageAvif.src,
83+
mobile: releaseVideoPlaceholderImageMobileAvif.src,
84+
}
85+
},
86+
imageAltText: "Video thumbnail: Audacity 3.6 - New effects",
87+
videoURL: "https://www.youtube-nocookie.com/embed/f5TXPUOFH6A?autoplay=1",
88+
dimensions: {
89+
width: 732,
90+
height: 412,
91+
mobileWidth: 400,
92+
mobileHeight: 225
93+
}
2794
}
2895
2996
const promoVideo = {
30-
title:"ACE Studio showcase",
31-
label:"Ad: Turn your lyrics into song with ACE Studio, the AI singing voice generator.",
32-
placeholderImage: featuredVideoPlaceholderImage.src,
97+
title: "ACE Studio showcase",
98+
label: "Ad: Turn your lyrics into song with ACE Studio, the AI singing voice generator.",
99+
placeholderImages: {
100+
webp: {
101+
default: featuredVideoPlaceholderImage.src,
102+
mobile: featuredVideoPlaceholderImageMobile.src,
103+
},
104+
avif: {
105+
default: featuredVideoPlaceholderImageAvif.src,
106+
mobile: featuredVideoPlaceholderImageMobileAvif.src,
107+
}
108+
},
33109
imageAltText: "Video thumbnail: What is ACE studio?",
34-
videoURL:"https://www.youtube-nocookie.com/embed/QTlB5UR-IEE?autoplay=1",
35-
CTA: true,
110+
videoURL: "https://www.youtube-nocookie.com/embed/QTlB5UR-IEE?autoplay=1",
111+
dimensions: {
112+
width: 732,
113+
height: 412,
114+
mobileWidth: 400,
115+
mobileHeight: 225
116+
},
117+
CTA: true,
36118
ctaText: "Try for free",
37-
ctaURL:"https://www.musehub.com/app/ace-studio?utm_source=au-web&utm_medium=mh-app-cta&utm_campaign=au-web-mh-app-ace-studio"
119+
ctaURL: "https://www.musehub.com/app/ace-studio?utm_source=au-web&utm_medium=mh-app-cta&utm_campaign=au-web-mh-app-ace-studio"
38120
}
39121
---
40122

@@ -46,22 +128,24 @@ const promoVideo = {
46128
client:load
47129
title={releaseVideo.title}
48130
label={releaseVideo.label}
49-
placeholderImage={releaseVideo.placeholderImage}
131+
placeholderImages={releaseVideo.placeholderImages}
50132
imageAltText={releaseVideo.imageAltText}
51133
videoURL={releaseVideo.videoURL}
134+
dimensions={releaseVideo.dimensions}
52135
matomoEventName={releaseVideo.title}
53136
/>
54137
<FeaturedVideo
55138
client:load
56139
title={promoVideo.title}
57140
label={promoVideo.label}
58-
placeholderImage={promoVideo.placeholderImage}
141+
placeholderImages={promoVideo.placeholderImages}
59142
imageAltText={promoVideo.imageAltText}
60143
videoURL={promoVideo.videoURL}
144+
dimensions={promoVideo.dimensions}
61145
CTA={promoVideo.CTA}
62146
ctaText={promoVideo.ctaText}
63147
ctaURL={promoVideo.ctaURL}
64148
matomoEventName={promoVideo.title}
65149
/>
66150
</div>
67-
</section>
151+
</section>

src/components/video/FeaturedVideo.jsx

Lines changed: 93 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ function FeaturedVideo(props) {
55
const [isClicked, setIsClicked] = useState(false);
66

77
const {
8-
placeholderImage,
9-
imageAltText,
8+
placeholderImages,
9+
placeholderImage, // For backward compatibility
1010
videoURL,
1111
label,
1212
title,
13+
imageAltText,
14+
dimensions,
1315
CTA,
1416
ctaText,
1517
ctaURL = "",
@@ -19,53 +21,114 @@ function FeaturedVideo(props) {
1921

2022
function handleVideoClick() {
2123
setIsClicked(true);
22-
trackEvent("Video embed", "Watch release video", matomoEventName);
24+
trackEvent("Video embed", "Watch video", matomoEventName || title);
2325
}
26+
2427
function handleCTAClick() {
2528
trackEvent("Promo CTA", "Promo CTA video button", ctaText);
2629
}
2730

31+
// Render the optimized responsive image with picture element
32+
function renderThumbnail() {
33+
// Check if we're using the new optimized structure or the legacy format
34+
const isOptimizedFormat = placeholderImages &&
35+
placeholderImages.avif &&
36+
placeholderImages.webp;
37+
38+
// If using the legacy format, render a simple image
39+
if (!isOptimizedFormat) {
40+
return (
41+
<img
42+
tabIndex="0"
43+
src={placeholderImage}
44+
alt={imageAltText || "Video thumbnail"}
45+
className="w-full aspect-video rounded-md shadow-xl cursor-pointer"
46+
width={dimensions?.width || 732}
47+
height={dimensions?.height || 412}
48+
loading="lazy"
49+
decoding="async"
50+
onClick={() => handleVideoClick()}
51+
onKeyDown={(e) => e.key === "Enter" && handleVideoClick()}
52+
/>
53+
);
54+
}
55+
56+
// Otherwise use the optimized picture element with multiple formats
57+
return (
58+
<picture>
59+
{/* AVIF format - best compression, newer browsers */}
60+
<source
61+
media="(min-width: 768px)"
62+
srcSet={placeholderImages.avif.default}
63+
type="image/avif"
64+
/>
65+
<source
66+
media="(max-width: 767px)"
67+
srcSet={placeholderImages.avif.mobile}
68+
type="image/avif"
69+
/>
70+
71+
{/* WebP format - good compression, wider support */}
72+
<source
73+
media="(min-width: 768px)"
74+
srcSet={placeholderImages.webp.default}
75+
type="image/webp"
76+
/>
77+
<source
78+
media="(max-width: 767px)"
79+
srcSet={placeholderImages.webp.mobile}
80+
type="image/webp"
81+
/>
82+
83+
{/* Fallback image */}
84+
<img
85+
tabIndex="0"
86+
src={placeholderImages.webp.default}
87+
alt={imageAltText || "Video thumbnail"}
88+
className="w-full aspect-video rounded-md shadow-xl cursor-pointer"
89+
width={dimensions?.width || 732}
90+
height={dimensions?.height || 412}
91+
loading="lazy"
92+
decoding="async"
93+
onClick={() => handleVideoClick()}
94+
onKeyDown={(e) => e.key === "Enter" && handleVideoClick()}
95+
/>
96+
</picture>
97+
);
98+
}
99+
28100
return (
29-
<div className="flex flex-col gap-2 lg:gap-4 w-full">
30-
{title && (
31-
<div className="flex flex-col xs:flex-row xs:justify-between md:h-10">
32-
<h3 className={`content-center ${textColor}`}>{title}</h3>
33-
{CTA && (
34-
<a
35-
className="py-3 px-4 rounded-md justify-center bg-yellow-300 hover:bg-yellow-400 active:bg-yellow-500 w-fit"
36-
href={ctaURL}
37-
onClick={() => handleCTAClick()}
38-
>
39-
<p className={`text-slate-900 leading-none font-semibold`}>
40-
{ctaText}
41-
</p>
42-
</a>
43-
)}
44-
</div>
45-
)}
101+
<div className="flex flex-col gap-2 lg:gap-4">
102+
<div className="flex flex-col xs:flex-row xs:justify-between md:h-10">
103+
<h3 className={`${textColor} content-center`}>{title}</h3>
104+
{CTA && (
105+
<a
106+
className="py-3 px-4 rounded-md justify-center bg-yellow-300 hover:bg-yellow-400 active:bg-yellow-500 w-fit"
107+
href={ctaURL}
108+
onClick={() => handleCTAClick()}
109+
>
110+
<p className="text-slate-900 leading-none font-semibold">{ctaText}</p>
111+
</a>
112+
)}
113+
</div>
46114

47115
{isClicked ? (
48116
<iframe
49117
className="w-full aspect-video rounded-md shadow-xl"
50118
loading="lazy"
51119
src={videoURL}
52120
title={title}
121+
width={dimensions?.width || 732}
122+
height={dimensions?.height || 412}
53123
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
54124
allowFullScreen
55125
></iframe>
56126
) : (
57-
<img
58-
tabIndex="0"
59-
src={placeholderImage}
60-
alt={imageAltText}
61-
className="w-full aspect-video rounded-md shadow-xl cursor-pointer"
62-
onClick={() => handleVideoClick()}
63-
onKeyDown={(e) => e.key === "Enter" && handleVideoClick()}
64-
/>
127+
renderThumbnail()
65128
)}
66-
{label && <p className={`${textColor}`}>{label}</p>}
129+
<p className={textColor}>{label}</p>
67130
</div>
68131
);
69132
}
70133

71-
export default FeaturedVideo;
134+
export default FeaturedVideo;

0 commit comments

Comments
 (0)