Performance: Code-Splitting pro Seite, KI-Chat lazy, Bilder als WebP (Einstieg 1071->285 kB)

This commit is contained in:
2026-10-04 21:49:22 +02:00
parent 844657e622
commit 38e681dce7
6 changed files with 47 additions and 22 deletions
+16 -4
View File
@@ -1,9 +1,11 @@
import { useEffect, useState } from 'react'
import { Suspense, lazy, useEffect, useState } from 'react'
import { useLocation } from 'react-router'
import { Sparkles, X } from 'lucide-react'
import AssistChat from './AssistChat'
import { useStore } from '../../store/store'
// Chat-Code erst laden, wenn die Verwaltung den Assistenten das erste Mal öffnet
const AssistChat = lazy(() => import('./AssistChat'))
/** KI-Assistent als einblendbares Widget (v1.38):
* Vertikale Lasche am rechten Rand öffnet ein Chat-Panel über der aktuellen Seite.
* Nur für die Verwaltung (role admin); auf der Assistenten-Seite selbst ausgeblendet. */
@@ -11,6 +13,9 @@ export default function AssistWidget() {
const { role } = useStore()
const location = useLocation()
const [offen, setOffen] = useState(false)
// Chat bleibt nach dem ersten Öffnen gemountet (Verlauf erhalten), wird aber
// vorher nicht geladen – der Chunk kommt erst bei Bedarf über die Leitung.
const [warOffen, setWarOffen] = useState(false)
// Bei Seitenwechsel Panel schließen (außer manuell wieder geöffnet)
useEffect(() => {
@@ -34,7 +39,10 @@ export default function AssistWidget() {
{/* Lasche am rechten Rand */}
<button
type="button"
onClick={() => setOffen(true)}
onClick={() => {
setWarOffen(true)
setOffen(true)
}}
aria-label="KI-Assistent öffnen"
className={`fixed right-0 top-1/2 z-40 flex -translate-y-1/2 flex-col items-center gap-2 rounded-l-xl bg-teal-600 py-4 pl-2.5 pr-2 text-white shadow-lg transition-all hover:bg-teal-500 hover:pr-3 ${
offen ? 'pointer-events-none translate-x-full opacity-0' : 'translate-x-0 opacity-100'
@@ -76,7 +84,11 @@ export default function AssistWidget() {
</header>
<div className="flex min-h-0 flex-1 flex-col p-4">
<AssistChat />
{warOffen ? (
<Suspense fallback={<div className="py-8 text-center text-sm text-slate-400">Assistent wird geladen …</div>}>
<AssistChat />
</Suspense>
) : null}
<p className="mt-2 text-[11px] leading-snug text-slate-400 dark:text-slate-500">
Antworten können fehlerhaft sein – kritische Daten bitte prüfen.
</p>