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