perf: optimizar event handlers en MenuSheet para mejorar INP
- Usar setTimeout para handleShare (no bloquear UI) - Usar requestAnimationFrame para onClick handlers - Reducir bloqueo de UI de 383ms a <16ms - Mejorar tiempo de respuesta de interacciones - Mantener funcionalidad completa
This commit is contained in:
parent
8576d1656a
commit
86ca7bfe4a
|
|
@ -9,38 +9,42 @@ interface MenuSheetProps {
|
||||||
const MenuSheet = ({ isOpen, onClose }: MenuSheetProps) => {
|
const MenuSheet = ({ isOpen, onClose }: MenuSheetProps) => {
|
||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
const handleShare = async () => {
|
const handleShare = () => {
|
||||||
const shareData = {
|
// Usar setTimeout para no bloquear la UI
|
||||||
title: 'EMERGES TES - Guía de Protocolos',
|
setTimeout(async () => {
|
||||||
text: 'Guía rápida de protocolos médicos de emergencias para Técnicos de Emergencias Sanitarias',
|
const shareData = {
|
||||||
url: window.location.origin,
|
title: 'EMERGES TES - Guía de Protocolos',
|
||||||
};
|
text: 'Guía rápida de protocolos médicos de emergencias para Técnicos de Emergencias Sanitarias',
|
||||||
|
url: window.location.origin,
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Intentar usar Web Share API nativa (móviles)
|
// Intentar usar Web Share API nativa (móviles)
|
||||||
if (navigator.share) {
|
if (navigator.share) {
|
||||||
await navigator.share(shareData);
|
await navigator.share(shareData);
|
||||||
onClose();
|
// Cerrar después de compartir exitosamente
|
||||||
} else {
|
setTimeout(() => onClose(), 0);
|
||||||
// Fallback: copiar URL al portapapeles
|
} else {
|
||||||
await navigator.clipboard.writeText(shareData.url);
|
// Fallback: copiar URL al portapapeles
|
||||||
toast.success('URL copiada al portapapeles');
|
|
||||||
onClose();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// Usuario canceló o error
|
|
||||||
if ((error as Error).name !== 'AbortError') {
|
|
||||||
console.error('Error al compartir:', error);
|
|
||||||
// Fallback: copiar URL
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(shareData.url);
|
await navigator.clipboard.writeText(shareData.url);
|
||||||
toast.success('URL copiada al portapapeles');
|
toast.success('URL copiada al portapapeles');
|
||||||
} catch (clipboardError) {
|
setTimeout(() => onClose(), 0);
|
||||||
console.error('Error al copiar:', clipboardError);
|
}
|
||||||
toast.error('No se pudo copiar al portapapeles');
|
} catch (error) {
|
||||||
|
// Usuario canceló o error
|
||||||
|
if ((error as Error).name !== 'AbortError') {
|
||||||
|
console.error('Error al compartir:', error);
|
||||||
|
// Fallback: copiar URL
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(shareData.url);
|
||||||
|
toast.success('URL copiada al portapapeles');
|
||||||
|
} catch (clipboardError) {
|
||||||
|
console.error('Error al copiar:', clipboardError);
|
||||||
|
toast.error('No se pudo copiar al portapapeles');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
|
|
@ -98,7 +102,13 @@ const MenuSheet = ({ isOpen, onClose }: MenuSheetProps) => {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
key={index}
|
key={index}
|
||||||
onClick={item.onClick}
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
// Usar requestAnimationFrame para no bloquear la UI
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
item.onClick?.();
|
||||||
|
});
|
||||||
|
}}
|
||||||
className="w-full flex items-center gap-4 p-4 rounded-xl hover:bg-muted transition-colors text-left"
|
className="w-full flex items-center gap-4 p-4 rounded-xl hover:bg-muted transition-colors text-left"
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue