performance optimierungen, lazy loads etc. - plus requesttimingmiddleware, die lokal die performance trackt und loggt.
This commit is contained in:
45
app/Http/Middleware/RequestTimingMiddleware.php
Normal file
45
app/Http/Middleware/RequestTimingMiddleware.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RequestTimingMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$request->attributes->set('_timing_start', microtime(true));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
public function terminate(Request $request, Response $response): void
|
||||
{
|
||||
if (! app()->environment('local')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$start = $request->attributes->get('_timing_start');
|
||||
|
||||
if (! is_float($start)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$duration = microtime(true) - $start;
|
||||
|
||||
Log::debug('request_timing', [
|
||||
'path' => $request->path(),
|
||||
'method' => $request->method(),
|
||||
'status' => $response->getStatusCode(),
|
||||
'duration_ms' => round($duration * 1000, 2),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
\App\Http\Middleware\ContentSecurityPolicy::class,
|
||||
HandleInertiaRequests::class,
|
||||
AddLinkHeadersForPreloadedAssets::class,
|
||||
\App\Http\Middleware\RequestTimingMiddleware::class,
|
||||
]);
|
||||
|
||||
$middleware->api(append: []);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { Suspense } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { RouterProvider } from 'react-router-dom';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
@@ -9,7 +9,8 @@ import './i18n';
|
||||
import './dev-tools';
|
||||
import { initializeTheme } from '@/hooks/use-appearance';
|
||||
import { OnboardingProgressProvider } from './onboarding';
|
||||
import { DevTenantSwitcher } from './components/DevTenantSwitcher';
|
||||
|
||||
const DevTenantSwitcher = React.lazy(() => import('./components/DevTenantSwitcher'));
|
||||
|
||||
const enableDevSwitcher = import.meta.env.DEV || import.meta.env.VITE_ENABLE_TENANT_SWITCHER === 'true';
|
||||
|
||||
@@ -28,10 +29,22 @@ createRoot(rootEl).render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AuthProvider>
|
||||
<OnboardingProgressProvider>
|
||||
<Suspense
|
||||
fallback={(
|
||||
<div className="flex min-h-screen items-center justify-center text-sm text-muted-foreground">
|
||||
Oberfläche wird geladen …
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<RouterProvider router={router} />
|
||||
</Suspense>
|
||||
</OnboardingProgressProvider>
|
||||
</AuthProvider>
|
||||
{enableDevSwitcher ? <DevTenantSwitcher /> : null}
|
||||
{enableDevSwitcher ? (
|
||||
<Suspense fallback={null}>
|
||||
<DevTenantSwitcher />
|
||||
</Suspense>
|
||||
) : null}
|
||||
</QueryClientProvider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
@@ -1,26 +1,5 @@
|
||||
import React from 'react';
|
||||
import { createBrowserRouter, Outlet, Navigate, useLocation } from 'react-router-dom';
|
||||
import LoginPage from './pages/LoginPage';
|
||||
import DashboardPage from './pages/DashboardPage';
|
||||
import EventsPage from './pages/EventsPage';
|
||||
import SettingsPage from './pages/SettingsPage';
|
||||
import EventFormPage from './pages/EventFormPage';
|
||||
import EventPhotosPage from './pages/EventPhotosPage';
|
||||
import EventDetailPage from './pages/EventDetailPage';
|
||||
import EventMembersPage from './pages/EventMembersPage';
|
||||
import EventTasksPage from './pages/EventTasksPage';
|
||||
import EventToolkitPage from './pages/EventToolkitPage';
|
||||
import EventInvitesPage from './pages/EventInvitesPage';
|
||||
import EngagementPage from './pages/EngagementPage';
|
||||
import BillingPage from './pages/BillingPage';
|
||||
import TasksPage from './pages/TasksPage';
|
||||
import TaskCollectionsPage from './pages/TaskCollectionsPage';
|
||||
import EmotionsPage from './pages/EmotionsPage';
|
||||
import AuthCallbackPage from './pages/AuthCallbackPage';
|
||||
import WelcomeTeaserPage from './pages/WelcomeTeaserPage';
|
||||
import LoginStartPage from './pages/LoginStartPage';
|
||||
import ProfilePage from './pages/ProfilePage';
|
||||
import LogoutPage from './pages/LogoutPage';
|
||||
import { useAuth } from './auth/context';
|
||||
import {
|
||||
ADMIN_BASE_PATH,
|
||||
@@ -31,10 +10,31 @@ import {
|
||||
ADMIN_PUBLIC_LANDING_PATH,
|
||||
} from './constants';
|
||||
import { consumeLastDestination } from './lib/returnTo';
|
||||
import WelcomeLandingPage from './onboarding/pages/WelcomeLandingPage';
|
||||
import WelcomePackagesPage from './onboarding/pages/WelcomePackagesPage';
|
||||
import WelcomeEventSetupPage from './onboarding/pages/WelcomeEventSetupPage';
|
||||
import WelcomeOrderSummaryPage from './onboarding/pages/WelcomeOrderSummaryPage';
|
||||
const LoginPage = React.lazy(() => import('./pages/LoginPage'));
|
||||
const DashboardPage = React.lazy(() => import('./pages/DashboardPage'));
|
||||
const EventsPage = React.lazy(() => import('./pages/EventsPage'));
|
||||
const SettingsPage = React.lazy(() => import('./pages/SettingsPage'));
|
||||
const EventFormPage = React.lazy(() => import('./pages/EventFormPage'));
|
||||
const EventPhotosPage = React.lazy(() => import('./pages/EventPhotosPage'));
|
||||
const EventDetailPage = React.lazy(() => import('./pages/EventDetailPage'));
|
||||
const EventMembersPage = React.lazy(() => import('./pages/EventMembersPage'));
|
||||
const EventTasksPage = React.lazy(() => import('./pages/EventTasksPage'));
|
||||
const EventToolkitPage = React.lazy(() => import('./pages/EventToolkitPage'));
|
||||
const EventInvitesPage = React.lazy(() => import('./pages/EventInvitesPage'));
|
||||
const EngagementPage = React.lazy(() => import('./pages/EngagementPage'));
|
||||
const BillingPage = React.lazy(() => import('./pages/BillingPage'));
|
||||
const TasksPage = React.lazy(() => import('./pages/TasksPage'));
|
||||
const TaskCollectionsPage = React.lazy(() => import('./pages/TaskCollectionsPage'));
|
||||
const EmotionsPage = React.lazy(() => import('./pages/EmotionsPage'));
|
||||
const AuthCallbackPage = React.lazy(() => import('./pages/AuthCallbackPage'));
|
||||
const WelcomeTeaserPage = React.lazy(() => import('./pages/WelcomeTeaserPage'));
|
||||
const LoginStartPage = React.lazy(() => import('./pages/LoginStartPage'));
|
||||
const ProfilePage = React.lazy(() => import('./pages/ProfilePage'));
|
||||
const LogoutPage = React.lazy(() => import('./pages/LogoutPage'));
|
||||
const WelcomeLandingPage = React.lazy(() => import('./onboarding/pages/WelcomeLandingPage'));
|
||||
const WelcomePackagesPage = React.lazy(() => import('./onboarding/pages/WelcomePackagesPage'));
|
||||
const WelcomeEventSetupPage = React.lazy(() => import('./onboarding/pages/WelcomeEventSetupPage'));
|
||||
const WelcomeOrderSummaryPage = React.lazy(() => import('./onboarding/pages/WelcomeOrderSummaryPage'));
|
||||
|
||||
function RequireAuth() {
|
||||
const { status } = useAuth();
|
||||
|
||||
@@ -308,7 +308,7 @@ export const messages: Record<LocaleCode, NestedMessages> = {
|
||||
limitWarning: 'Nur noch {remaining} von {max} Fotos möglich. Bitte kontaktiere die Veranstalter für ein Upgrade.',
|
||||
galleryWarningDay: 'Galerie läuft in {days} Tag ab. Teile deine Fotos rechtzeitig!',
|
||||
galleryWarningDays: 'Galerie läuft in {days} Tagen ab. Teile deine Fotos rechtzeitig!',
|
||||
status: {
|
||||
packageStatus: {
|
||||
title: 'Dein Paketstatus',
|
||||
subtitle: 'Behalte deine Kontingente im Blick, bevor es eng wird.',
|
||||
badges: {
|
||||
@@ -736,7 +736,7 @@ export const messages: Record<LocaleCode, NestedMessages> = {
|
||||
limitWarning: 'Only {remaining} of {max} photos left. Please contact the organizers for an upgrade.',
|
||||
galleryWarningDay: 'Gallery expires in {days} day. Upload your photos soon!',
|
||||
galleryWarningDays: 'Gallery expires in {days} days. Upload your photos soon!',
|
||||
status: {
|
||||
packageStatus: {
|
||||
title: 'Your package status',
|
||||
subtitle: 'Keep an eye on your remaining allowances.',
|
||||
badges: {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { Suspense } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { RouterProvider } from 'react-router-dom';
|
||||
import { router } from './router';
|
||||
@@ -28,7 +28,15 @@ createRoot(rootEl).render(
|
||||
<React.StrictMode>
|
||||
<LocaleProvider>
|
||||
<ToastProvider>
|
||||
<Suspense
|
||||
fallback={(
|
||||
<div className="flex min-h-screen items-center justify-center text-sm text-muted-foreground">
|
||||
Erlebnisse werden geladen …
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<RouterProvider router={router} />
|
||||
</Suspense>
|
||||
</ToastProvider>
|
||||
</LocaleProvider>
|
||||
</React.StrictMode>
|
||||
|
||||
@@ -8,27 +8,28 @@ import { AlertTriangle, Loader2 } from 'lucide-react';
|
||||
import { EventStatsProvider } from './context/EventStatsContext';
|
||||
import { GuestIdentityProvider } from './context/GuestIdentityContext';
|
||||
import { EventBrandingProvider } from './context/EventBrandingContext';
|
||||
import LandingPage from './pages/LandingPage';
|
||||
import ProfileSetupPage from './pages/ProfileSetupPage';
|
||||
import HomePage from './pages/HomePage';
|
||||
import TaskPickerPage from './pages/TaskPickerPage';
|
||||
import TaskDetailPage from './pages/TaskDetailPage';
|
||||
import UploadPage from './pages/UploadPage';
|
||||
import UploadQueuePage from './pages/UploadQueuePage';
|
||||
import GalleryPage from './pages/GalleryPage';
|
||||
import PhotoLightbox from './pages/PhotoLightbox';
|
||||
import AchievementsPage from './pages/AchievementsPage';
|
||||
import SlideshowPage from './pages/SlideshowPage';
|
||||
import SettingsPage from './pages/SettingsPage';
|
||||
import LegalPage from './pages/LegalPage';
|
||||
import PublicGalleryPage from './pages/PublicGalleryPage';
|
||||
import NotFoundPage from './pages/NotFoundPage';
|
||||
import { LocaleProvider } from './i18n/LocaleContext';
|
||||
import { DEFAULT_LOCALE, isLocaleCode } from './i18n/messages';
|
||||
import { useTranslation, type TranslateFn } from './i18n/useTranslation';
|
||||
import type { EventBranding } from './types/event-branding';
|
||||
import type { EventBrandingPayload, FetchEventErrorCode } from './services/eventApi';
|
||||
|
||||
const LandingPage = React.lazy(() => import('./pages/LandingPage'));
|
||||
const ProfileSetupPage = React.lazy(() => import('./pages/ProfileSetupPage'));
|
||||
const HomePage = React.lazy(() => import('./pages/HomePage'));
|
||||
const TaskPickerPage = React.lazy(() => import('./pages/TaskPickerPage'));
|
||||
const TaskDetailPage = React.lazy(() => import('./pages/TaskDetailPage'));
|
||||
const UploadPage = React.lazy(() => import('./pages/UploadPage'));
|
||||
const UploadQueuePage = React.lazy(() => import('./pages/UploadQueuePage'));
|
||||
const GalleryPage = React.lazy(() => import('./pages/GalleryPage'));
|
||||
const PhotoLightbox = React.lazy(() => import('./pages/PhotoLightbox'));
|
||||
const AchievementsPage = React.lazy(() => import('./pages/AchievementsPage'));
|
||||
const SlideshowPage = React.lazy(() => import('./pages/SlideshowPage'));
|
||||
const SettingsPage = React.lazy(() => import('./pages/SettingsPage'));
|
||||
const LegalPage = React.lazy(() => import('./pages/LegalPage'));
|
||||
const PublicGalleryPage = React.lazy(() => import('./pages/PublicGalleryPage'));
|
||||
const NotFoundPage = React.lazy(() => import('./pages/NotFoundPage'));
|
||||
|
||||
function HomeLayout() {
|
||||
const { token } = useParams();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user