Improve AdSense loading speed and performance

Implement lazy loading for AdSense ads using IntersectionObserver to defer loading until the ad is visible on the screen, and optimize ad initialization logic.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 45a1dcfc-f8a2-475a-a6b9-96fbb841dc27
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/60d372ff-2c10-46c7-b01b-10c3435136b0/45a1dcfc-f8a2-475a-a6b9-96fbb841dc27/JMKe3od
This commit is contained in:
sebastjanartic 2025-09-27 05:09:34 +00:00
parent dc93a02fff
commit 2994138b00
3 changed files with 41 additions and 39 deletions

View File

@ -23,6 +23,10 @@ externalPort = 3001
localPort = 35637
externalPort = 3000
[[ports]]
localPort = 36095
externalPort = 3002
[env]
PORT = "5000"

View File

@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from 'react';
import { useEffect, useRef } from 'react';
interface AdSenseAdProps {
adSlot: string;
@ -6,6 +6,7 @@ interface AdSenseAdProps {
width?: number;
height?: number;
className?: string;
lazy?: boolean;
}
export default function AdSenseAd({
@ -13,62 +14,56 @@ export default function AdSenseAd({
adFormat = 'auto',
width,
height,
className = ''
className = '',
lazy = false
}: AdSenseAdProps) {
const adRef = useRef<HTMLDivElement>(null);
const [isInitialized, setIsInitialized] = useState(false);
useEffect(() => {
if (isInitialized) return;
const initializeAd = () => {
const insElement = adRef.current?.querySelector('ins');
if (!insElement) return;
if (!insElement || insElement.dataset.adsbygoogleStatus === 'done') return;
// Check if element has width > 0
const clientWidth = insElement.clientWidth;
if (clientWidth > 0) {
try {
// @ts-ignore
(window.adsbygoogle = window.adsbygoogle || []).push({});
setIsInitialized(true);
} catch (error) {
console.error('AdSense initialization error:', error);
}
try {
// @ts-ignore
(window.adsbygoogle = window.adsbygoogle || []).push({});
} catch (error) {
console.error('AdSense initialization error:', error);
}
};
// Try immediate initialization after short delay
const timer = setTimeout(initializeAd, 100);
// Use ResizeObserver as fallback
if (typeof window !== 'undefined' && window.ResizeObserver) {
const observer = new ResizeObserver(() => {
if (!isInitialized) {
initializeAd();
}
});
if (lazy) {
// Lazy load with IntersectionObserver
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
initializeAd();
observer.disconnect();
}
});
},
{ threshold: 0.1 }
);
if (adRef.current) {
observer.observe(adRef.current);
}
return () => {
clearTimeout(timer);
observer.disconnect();
};
return () => observer.disconnect();
} else {
// Immediate initialization
initializeAd();
}
}, [adSlot, lazy]);
return () => clearTimeout(timer);
}, [adSlot, isInitialized]);
// Fixed size configuration
const isFixedSize = width && height;
const adStyle: React.CSSProperties = {
display: 'block',
maxWidth: '728px',
maxHeight: '90px'
display: 'inline-block'
};
if (adFormat !== 'auto' && width && height) {
if (isFixedSize) {
adStyle.width = `${width}px`;
adStyle.height = `${height}px`;
} else {
@ -87,8 +82,10 @@ export default function AdSenseAd({
style={adStyle}
data-ad-client="ca-pub-4465464714854276"
data-ad-slot={adSlot}
data-ad-format={adFormat}
data-full-width-responsive="true"
{...(isFixedSize ? {} : {
'data-ad-format': adFormat,
'data-full-width-responsive': 'true'
})}
/>
</div>
);

View File

@ -237,6 +237,7 @@ export default function Home() {
width={728}
height={90}
className="max-w-full"
lazy={true}
/>
</div>
</div>