'use client' import dynamic from 'next/dynamic' import { useEffect, useRef, useState, type ComponentProps } from 'react' import { chatText } from '@/lib/i18n/chat' import { SkeletonLine } from '@/components/Skeleton' import type { Chat } from './Chat' const ChatInner = dynamic(() => import('./Chat').then((modul) => modul.Chat), { loading: () => , // Der Chat wird ohnehin erst nach dem Scrollen gebraucht und lebt von einer // offenen Verbindung. Ihn auf dem Server mitzurendern brächte nichts und // zöge sein Bündel in die erste Ladung der Fallakte. ssr: false, }) /** * Lädt den Chat erst, wenn er in Sichtweite kommt. * * Zwei Gründe, beide handfest: die Fallakte ist das, weswegen die Seite * geöffnet wird - ihr Bündelbudget soll nicht für einen Chat draufgehen, den * viele nie aufklappen. Und der Chat hält eine offene Verbindung zum * Ereignisstrom; wer nur die Akte liest, soll sie nicht aufbauen. * * Der Platzhalter hat die Höhe des Chats, damit beim Nachladen nichts springt. * Siehe docs/09-performance-und-ux.md. */ export function ChatLazy(props: ComponentProps) { const [sichtbar, setSichtbar] = useState(false) const anker = useRef(null) useEffect(() => { const element = anker.current if (!element) return // Ohne IntersectionObserver (sehr alte Browser) sofort laden: lieber // grösser als kaputt. if (typeof IntersectionObserver === 'undefined') { setSichtbar(true) return } const beobachter = new IntersectionObserver( (eintraege) => { if (eintraege.some((eintrag) => eintrag.isIntersecting)) { setSichtbar(true) beobachter.disconnect() } }, // Etwas vorher anfangen, damit er beim Ankommen schon steht. { rootMargin: '300px' }, ) beobachter.observe(element) return () => beobachter.disconnect() }, []) return
{sichtbar ? : }
} function Platzhalter() { return (

{chatText.heading}

) }