Wie kann man die PHP Laravel-Webanwendung für hohe Leistung optimieren?

Laravel ist vieles. Aber schnell gehört nicht dazu. Lassen Sie uns einige Tricks des Handels lernen, damit es schneller geht!

Kein PHP-Entwickler bleibt davon unberührt Laravel heutzutage. Sie sind entweder ein Junior- oder Mid-Level-Entwickler, der die schnelle Entwicklung liebt, die Laravel bietet, oder sie sind ein Senior-Entwickler, der aufgrund des Marktdrucks gezwungen ist, Laravel zu lernen.

Wie auch immer, es ist nicht zu leugnen, dass Laravel das PHP-Ökosystem wiederbelebt hat (ich hätte die PHP-Welt sicher schon vor langer Zeit verlassen, wenn es Laravel nicht gegeben hätte).

Ein Ausschnitt aus (etwas berechtigtem) Eigenlob von Laravel

Da sich Laravel jedoch nach hinten beugt, um es Ihnen leicht zu machen, bedeutet dies, dass darunter Unmengen an Arbeit geleistet werden, um sicherzustellen, dass Sie als Entwickler ein angenehmes Leben führen. Alle „magischen“ Funktionen von Laravel, die einfach zu funktionieren scheinen, haben Schichten über Schichten von Code, die jedes Mal, wenn eine Funktion ausgeführt wird, aufgepeppt werden müssen. Sogar eine einfache Ausnahme verfolgt, wie tief das Kaninchenloch ist (beachten Sie, wo der Fehler beginnt, bis hinunter zum Hauptkernel):

Für einen scheinbaren Kompilierungsfehler in einer der Ansichten müssen 18 Funktionsaufrufe nachverfolgt werden. Ich persönlich bin auf 40 gestoßen, und es könnten leicht mehr sein, wenn Sie andere Bibliotheken und Plugins verwenden.

Der Punkt ist, dass standardmäßig diese Schichten auf Codeschichten Laravel langsam machen.

Wie langsam ist Laravel?

Ehrlich gesagt ist es aus mehreren Gründen einfach unmöglich, diese Frage zu beantworten.

Erstens gibt es keinen akzeptierten, objektiven und vernünftigen Standard zur Messung der Geschwindigkeit von Web-Apps. Schneller oder langsamer im Vergleich zu was? Unter welchen Bedingungen?

Zweitens hängt eine Webanwendung von so vielen Dingen ab (Datenbank, Dateisystem, Netzwerk, Cache usw.), dass es einfach albern ist, über Geschwindigkeit zu sprechen. Eine sehr schnelle Web-App mit einer sehr langsamen Datenbank ist eine sehr langsame Web-App. 🙂

Aber genau diese Ungewissheit ist der Grund, warum Benchmarks so beliebt sind. Auch wenn sie nichts bedeuten (vgl Dies und Dies), bieten sie einen Bezugsrahmen und helfen uns, nicht verrückt zu werden. Lassen Sie uns daher, mit einigen Prisen Salz bereit, eine falsche, grobe Vorstellung von der Geschwindigkeit unter PHP-Frameworks bekommen.

Gehen Sie von diesem ziemlich respektablen GitHub aus Quelleso schneiden die PHP-Frameworks im Vergleich ab:

Sie werden Laravel hier vielleicht nicht einmal bemerken (selbst wenn Sie wirklich hart blinzeln), es sei denn, Sie werfen Ihren Koffer bis zum Ende des Schwanzes. Ja, liebe Freunde, Laravel kommt zuletzt! Nun, zugegeben, die meisten dieser „Frameworks“ sind nicht sehr praktisch oder sogar nützlich, aber es sagt uns, wie träge Laravel im Vergleich zu anderen populäreren ist.

Normalerweise tritt diese „Langsamkeit“ in Anwendungen nicht auf, da unsere alltäglichen Web-Apps selten hohe Zahlen erreichen. Aber sobald sie dies tun (z. B. ab 200-500 gleichzeitig), beginnen die Server zu ersticken und zu sterben. Es ist die Zeit, in der es nicht einmal mehr hilft, das Problem mit mehr Hardware zu lösen, und die Infrastrukturrechnungen steigen so schnell, dass Ihre hohen Ideale des Cloud Computing zusammenbrechen.

Aber hey, Kopf hoch! In diesem Artikel geht es nicht darum, was nicht getan werden kann, sondern darum, was getan werden kann. 🙂

Die gute Nachricht ist, dass Sie viel tun können, um Ihre Laravel-App schneller zu machen. Mehrmals schnell. Ja, kein Scherz. Sie können die gleiche Codebasis ballistisch machen und jeden Monat mehrere hundert Dollar an Infrastruktur-/Hosting-Rechnungen sparen. Wie? Lasst uns anfangen.

Vier Arten von Optimierungen

Meiner Meinung nach kann die Optimierung auf vier verschiedenen Ebenen erfolgen (das heißt, wenn es um PHP-Anwendungen geht):

  • Sprachniveau: Dies bedeutet, dass Sie eine schnellere Version der Sprache verwenden und bestimmte Funktionen/Codierungsstile in der Sprache vermeiden, die Ihren Code langsam machen.
  • Framework-Ebene: Dies sind die Dinge, die wir in diesem Artikel behandeln werden.
  • Infrastrukturebene: Optimieren Sie Ihren PHP-Prozessmanager, Webserver, Ihre Datenbank usw.
  • Hardware-Ebene: Wechsel zu einem besseren, schnelleren und leistungsfähigeren Hardware-Hosting-Anbieter.

Alle diese Arten von Optimierungen haben ihren Platz (zum Beispiel ist die PHP-fpm-Optimierung ziemlich kritisch und leistungsstark). Aber der Schwerpunkt dieses Artikels liegt auf reinen Optimierungen vom Typ 2: solche, die sich auf das Framework beziehen.

Übrigens gibt es keine Begründung für die Nummerierung, und es ist kein akzeptierter Standard. Ich habe mir diese gerade ausgedacht. Bitte zitieren Sie mich niemals und sagen Sie: „Wir brauchen eine Typ-3-Optimierung auf unserem Server“, oder Ihr Teamleiter wird Sie töten, mich finden und mich dann auch töten. 😀

Und jetzt kommen wir endlich im gelobten Land an.

Achten Sie auf n+1 Datenbankabfragen

Das n+1-Abfrageproblem tritt häufig auf, wenn ORMs verwendet werden. Laravel hat sein leistungsstarkes ORM namens Eloquent, das so schön und praktisch ist, dass wir oft vergessen, zu sehen, was vor sich geht.

Stellen Sie sich ein sehr häufiges Szenario vor: die Anzeige der Liste aller Bestellungen, die von einer bestimmten Kundenliste aufgegeben wurden. Dies ist ziemlich üblich in E-Commerce-Systemen und allen Berichtsschnittstellen im Allgemeinen, wo wir alle Entitäten anzeigen müssen, die sich auf einige Entitäten beziehen.

In Laravel könnten wir uns eine Controller-Funktion vorstellen, die die Aufgabe wie folgt erledigt:

class OrdersController extends Controller 
{
    // ... 

    public function getAllByCustomers(Request $request, array $ids) {
        $customers = Customer::findMany($ids);        
        $orders = collect(); // new collection
        
        foreach ($customers as $customer) {
            $orders = $orders->merge($customer->orders);
        }
        
        return view('admin.reports.orders', ['orders' => $orders]);
    }
}

Süss! Und vor allem elegant, schön. 🤩🤩

  Was zu tun ist, bevor (und nachdem) Ihr Telefon gestohlen wird

Leider ist es eine katastrophale Art, Code in Laravel zu schreiben.

Hier ist der Grund.

Wenn wir das ORM bitten, nach den angegebenen Kunden zu suchen, wird eine SQL-Abfrage wie diese generiert:

SELECT * FROM customers WHERE id IN (22, 45, 34, . . .);

Was genau wie erwartet ist. Als Ergebnis werden alle zurückgegebenen Zeilen in der Sammlung $customers innerhalb der Controller-Funktion gespeichert.

Jetzt durchlaufen wir jeden Kunden einen nach dem anderen und erhalten seine Bestellungen. Dies führt die folgende Abfrage aus. . .

SELECT * FROM orders WHERE customer_id = 22;

. . . so oft wie es Kunden gibt.

Mit anderen Worten, wenn wir die Bestelldaten für 1000 Kunden abrufen müssen, beträgt die Gesamtzahl der ausgeführten Datenbankabfragen 1 (zum Abrufen aller Kundendaten) + 1000 (zum Abrufen von Bestelldaten für jeden Kunden) = 1001. Dies daher kommt der Name n+1.

Können wir es besser machen? Sicherlich! Durch die Verwendung des sogenannten Eager Loading können wir das ORM zwingen, einen JOIN durchzuführen und alle erforderlichen Daten in einer einzigen Abfrage zurückzugeben! So was:

$orders = Customer::findMany($ids)->with('orders')->get();

Die resultierende Datenstruktur ist natürlich verschachtelt, aber die Auftragsdaten können einfach extrahiert werden. Die resultierende einzelne Abfrage sieht in diesem Fall etwa so aus:

SELECT * FROM customers INNER JOIN orders ON customers.id = orders.customer_id WHERE customers.id IN (22, 45, . . .);

Eine einzige Abfrage ist natürlich besser als tausend zusätzliche Abfragen. Stellen Sie sich vor, was passieren würde, wenn 10.000 Kunden bearbeitet werden müssten! Oder Gott bewahre, wenn wir die in jeder Bestellung enthaltenen Artikel auch anzeigen wollten! Denken Sie daran, dass der Name der Technik Eifriges Laden ist, und es ist fast immer eine gute Idee.

Cachen Sie die Konfiguration!

Einer der Gründe für die Flexibilität von Laravel sind die unzähligen Konfigurationsdateien, die Teil des Frameworks sind. Möchten Sie ändern, wie/wo die Bilder gespeichert werden?

Nun, ändern Sie einfach die Datei config/filesystems.php (zumindest zum Zeitpunkt des Schreibens). Möchten Sie mit mehreren Warteschlangentreibern arbeiten? Fühlen Sie sich frei, sie in config/queue.php zu beschreiben. Ich habe gerade gezählt und festgestellt, dass es 13 Konfigurationsdateien für verschiedene Aspekte des Frameworks gibt, um sicherzustellen, dass Sie nicht enttäuscht werden, egal was Sie ändern möchten.

Angesichts der Natur von PHP wacht Laravel jedes Mal auf, wenn eine neue Webanforderung eingeht, bootet alles und analysiert all diese Konfigurationsdateien, um herauszufinden, wie die Dinge diesmal anders gemacht werden können. Nur dass es blöd ist, wenn sich in den letzten Tagen nichts geändert hat! Die Konfiguration bei jeder Anfrage neu zu erstellen, ist eine Verschwendung, die vermieden werden kann (eigentlich muss), und der Ausweg ist ein einfacher Befehl, den Laravel anbietet:

php artisan config:cache

Dadurch werden alle verfügbaren Konfigurationsdateien zu einer einzigen kombiniert, und der Cache befindet sich irgendwo zum schnellen Abrufen. Bei der nächsten Webanfrage liest Laravel einfach diese einzelne Datei und legt los.

Das Konfigurations-Caching ist jedoch eine äußerst heikle Operation, die Ihnen in die Luft sprengen kann. Das größte Problem ist, dass die env()-Funktion, sobald Sie diesen Befehl ausgegeben haben, von überall aufgerufen wird, außer dass die Konfigurationsdateien null zurückgeben!

Es macht Sinn, wenn man darüber nachdenkt. Wenn Sie Konfigurations-Caching verwenden, sagen Sie dem Framework: „Weißt du was, ich denke, ich habe die Dinge gut eingerichtet und bin mir zu 100 % sicher, dass ich nicht möchte, dass sie sich ändern.“ Mit anderen Worten, Sie erwarten, dass die Umgebung statisch bleibt, wofür .env-Dateien da sind.

Vor diesem Hintergrund sind hier einige eiserne, heilige, unumstößliche Regeln des Konfigurations-Cachings:

  • Tun Sie es nur auf einem Produktionssystem.
  • Tun Sie dies nur, wenn Sie wirklich, wirklich sicher sind, dass Sie die Konfiguration einfrieren möchten.
  • Falls etwas schief geht, machen Sie die Einstellung mit php artisan cache:clear rückgängig
  • Beten Sie, dass der Schaden, der dem Geschäft zugefügt wurde, nicht erheblich war!
  • Reduzieren Sie automatisch geladene Dienste

    Um hilfreich zu sein, lädt Laravel eine Menge Dienste, wenn es aufwacht. Diese sind in der Datei config/app.php als Teil des Array-Schlüssels „providers“ verfügbar. Schauen wir uns an, was ich in meinem Fall habe:

    /*
        |--------------------------------------------------------------------------
        | Autoloaded Service Providers
        |--------------------------------------------------------------------------
        |
        | The service providers listed here will be automatically loaded on the
        | request to your application. Feel free to add your own services to
        | this array to grant expanded functionality to your applications.
        |
        */
    
        'providers' => [
    
            /*
             * Laravel Framework Service Providers...
             */
            IlluminateAuthAuthServiceProvider::class,
            IlluminateBroadcastingBroadcastServiceProvider::class,
            IlluminateBusBusServiceProvider::class,
            IlluminateCacheCacheServiceProvider::class,
            IlluminateFoundationProvidersConsoleSupportServiceProvider::class,
            IlluminateCookieCookieServiceProvider::class,
            IlluminateDatabaseDatabaseServiceProvider::class,
            IlluminateEncryptionEncryptionServiceProvider::class,
            IlluminateFilesystemFilesystemServiceProvider::class,
            IlluminateFoundationProvidersFoundationServiceProvider::class,
            IlluminateHashingHashServiceProvider::class,
            IlluminateMailMailServiceProvider::class,
            IlluminateNotificationsNotificationServiceProvider::class,
            IlluminatePaginationPaginationServiceProvider::class,
            IlluminatePipelinePipelineServiceProvider::class,
            IlluminateQueueQueueServiceProvider::class,
            IlluminateRedisRedisServiceProvider::class,
            IlluminateAuthPasswordsPasswordResetServiceProvider::class,
            IlluminateSessionSessionServiceProvider::class,
            IlluminateTranslationTranslationServiceProvider::class,
            IlluminateValidationValidationServiceProvider::class,
            IlluminateViewViewServiceProvider::class,
    
            /*
             * Package Service Providers...
             */
    
            /*
             * Application Service Providers...
             */
            AppProvidersAppServiceProvider::class,
            AppProvidersAuthServiceProvider::class,
            // AppProvidersBroadcastServiceProvider::class,
            AppProvidersEventServiceProvider::class,
            AppProvidersRouteServiceProvider::class,
    
        ],

    Noch einmal, ich habe gezählt, und es sind 27 Dienste aufgelistet! Jetzt brauchen Sie vielleicht alle, aber es ist unwahrscheinlich.

    Zum Beispiel baue ich gerade eine REST-API, was bedeutet, dass ich den Session Service Provider, View Service Provider usw. nicht benötige. Und da ich ein paar Dinge auf meine Weise mache und nicht den Standardeinstellungen des Frameworks folge , kann ich auch Auth Service Provider, Pagination Service Provider, Translation Service Provider usw. deaktivieren. Alles in allem sind fast die Hälfte davon für meinen Anwendungsfall unnötig.

      So verwenden Sie RSS-Feeds

    Schauen Sie sich Ihre Bewerbung genau an. Braucht es all diese Dienstleister? Aber um Gottes willen bitte diese Dienste nicht blind auskommentieren und auf Produktion pushen! Führen Sie alle Tests durch, überprüfen Sie die Dinge manuell auf Entwicklungs- und Staging-Maschinen und seien Sie sehr, sehr paranoid, bevor Sie den Abzug betätigen. 🙂

    Seien Sie weise mit Middleware-Stacks

    Wenn Sie eine benutzerdefinierte Verarbeitung der eingehenden Webanforderung benötigen, ist das Erstellen einer neuen Middleware die Antwort. Jetzt ist es verlockend, app/Http/Kernel.php zu öffnen und die Middleware in den Web- oder API-Stack zu stecken; Auf diese Weise wird es in der gesamten App verfügbar und wenn es sich nicht um etwas Aufdringliches handelt (z. B. Protokollieren oder Benachrichtigen).

    Wenn die App jedoch wächst, kann diese Sammlung globaler Middleware zu einer stillen Belastung für die App werden, wenn alle (oder die meisten) davon in jeder Anfrage vorhanden sind, selbst wenn es keinen geschäftlichen Grund dafür gibt.

    Mit anderen Worten: Achten Sie darauf, wo Sie eine neue Middleware hinzufügen/anwenden. Es kann bequemer sein, etwas global hinzuzufügen, aber die Leistungseinbuße ist auf lange Sicht sehr hoch. Ich kenne den Schmerz, den Sie durchmachen müssten, wenn Sie Middleware jedes Mal selektiv anwenden würden, wenn es eine neue Änderung gibt, aber ich würde diesen Schmerz bereitwillig auf mich nehmen und empfehlen!

    Vermeiden Sie das ORM (manchmal)

    Während Eloquent viele Aspekte der DB-Interaktion angenehm macht, geht dies auf Kosten der Geschwindigkeit. Als Mapper muss das ORM nicht nur Datensätze aus der Datenbank abrufen, sondern auch die Modellobjekte instanziieren und sie mit Spaltendaten hydratisieren (füllen).

    Wenn Sie also ein einfaches $users = User::all() ausführen und es beispielsweise 10.000 Benutzer gibt, ruft das Framework 10.000 Zeilen aus der Datenbank ab und führt intern 10.000 neue User() aus und füllt ihre Eigenschaften mit den relevanten Daten . Dies ist eine enorme Menge an Arbeit, die hinter den Kulissen geleistet wird, und wenn die Datenbank dort ist, wo Ihre Anwendung zu einem Engpass wird, ist es manchmal eine gute Idee, das ORM zu umgehen.

    Dies gilt insbesondere für komplexe SQL-Abfragen, bei denen Sie viele Hürden springen und Closures für Closures schreiben müssten und trotzdem eine effiziente Abfrage erhalten würden. In solchen Fällen ist es vorzuziehen, ein DB::raw() auszuführen und die Abfrage von Hand zu schreiben.

    Vorbeigehen Dies Leistungsstudie, selbst für einfache Einfügungen Eloquent ist viel langsamer, wenn die Anzahl der Datensätze steigt:

    Verwenden Sie so viel wie möglich Caching

    Eines der am besten gehüteten Geheimnisse der Optimierung von Webanwendungen ist das Caching.

    Für den Uneingeweihten bedeutet Caching, teure Ergebnisse vorab zu berechnen und zu speichern (teuer in Bezug auf CPU- und Speichernutzung) und sie einfach zurückzugeben, wenn dieselbe Abfrage wiederholt wird.

    In einem E-Commerce-Shop kann es beispielsweise vorkommen, dass von den 2 Millionen Produkten die Leute meistens frisch auf Lager sind, in einer bestimmten Preisklasse und für eine bestimmte Altersgruppe interessiert sind. Das Abfragen der Datenbank nach diesen Informationen ist verschwenderisch – da sich die Abfrage nicht oft ändert, ist es besser, diese Ergebnisse an einem Ort zu speichern, auf den wir schnell zugreifen können.

    Laravel verfügt über eine integrierte Unterstützung für verschiedene Arten von zwischenspeichern. Zusätzlich zur Verwendung eines Caching-Treibers und dem Aufbau des Caching-Systems von Grund auf möchten Sie möglicherweise einige Laravel-Pakete verwenden, die dies erleichtern Modell-Caching, Abfrage-Cachingetc.

    Beachten Sie jedoch, dass vorgefertigte Caching-Pakete über einen bestimmten vereinfachten Anwendungsfall hinaus mehr Probleme verursachen als lösen können.

    Bevorzugen Sie In-Memory-Caching

    Wenn Sie etwas in Laravel zwischenspeichern, haben Sie mehrere Möglichkeiten, wo die resultierende Berechnung gespeichert werden soll, die zwischengespeichert werden muss. Diese Optionen werden auch als Cache-Treiber. Obwohl es möglich und durchaus sinnvoll ist, das Dateisystem zum Speichern von Cache-Ergebnissen zu verwenden, ist es nicht wirklich das, was Caching sein soll.

    Idealerweise möchten Sie einen In-Memory-Cache (der vollständig im RAM lebt) wie Redis, Memcached, MongoDB usw. verwenden, damit das Caching unter höheren Lasten einen wichtigen Zweck erfüllt, anstatt selbst zum Engpass zu werden.

    Jetzt denken Sie vielleicht, dass eine SSD-Festplatte fast dasselbe ist wie die Verwendung eines RAM-Sticks, aber es ist nicht einmal annähernd so. Sogar informell Maßstäbe zeigen, dass RAM SSD um das 10-20-fache übertrifft, wenn es um Geschwindigkeit geht.

    Mein Lieblingssystem beim Caching ist Redis. Es ist lächerlich schnell (100.000 Leseoperationen pro Sekunde sind üblich) und können für sehr große Cache-Systeme zu a entwickelt werden Cluster leicht.

    Cachen Sie die Routen

    Genau wie die Anwendungskonfiguration ändern sich die Routen im Laufe der Zeit nicht wesentlich und sind ein idealer Kandidat für das Caching. Dies gilt insbesondere, wenn Sie große Dateien wie ich nicht ausstehen und am Ende Ihre web.php und api.php auf mehrere Dateien aufteilen. Ein einziger Laravel-Befehl packt alle verfügbaren Routen zusammen und hält sie für den zukünftigen Zugriff griffbereit:

    php artisan route:cache

    Und wenn Sie am Ende Routen hinzufügen oder ändern, tun Sie einfach Folgendes:

    php artisan route:clear

    Bildoptimierung und CDN

    Bilder sind das Herz und die Seele der meisten Webanwendungen. Zufälligerweise sind sie auch die größten Bandbreitenverbraucher und einer der Hauptgründe für langsame Apps/Websites. Wenn Sie die hochgeladenen Bilder einfach naiv auf dem Server speichern und sie in HTTP-Antworten zurücksenden, lassen Sie eine enorme Optimierungsmöglichkeit ungenutzt.

      Wie finde ich die externe IP der Google Cloud VM?

    Meine erste Empfehlung ist, Bilder nicht lokal zu speichern – es muss mit dem Problem des Datenverlusts umgegangen werden, und je nachdem, in welcher geografischen Region sich Ihr Kunde befindet, kann die Datenübertragung schmerzhaft langsam sein.

    Entscheiden Sie sich stattdessen für eine Lösung wie Bewölkt die Bilder im Handumdrehen automatisch in der Größe ändert und optimiert.

    Wenn dies nicht möglich ist, verwenden Sie etwas wie Cloudflare, um Bilder zwischenzuspeichern und bereitzustellen, während sie auf Ihrem Server gespeichert sind.

    Und wenn selbst das nicht möglich ist, macht es einen großen Unterschied, wenn Sie Ihre Webserver-Software ein wenig optimieren, um Assets zu komprimieren und den Browser des Besuchers anzuweisen, Dinge zwischenzuspeichern. So würde ein Ausschnitt der Nginx-Konfiguration aussehen:

    server {
    
       # file truncated
        
        # gzip compression settings
        gzip on;
        gzip_comp_level 5;
        gzip_min_length 256;
        gzip_proxied any;
        gzip_vary on;
    
       # browser cache control
       location ~* .(ico|css|js|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ {
             expires 1d;
             access_log off;
             add_header Pragma public;
             add_header Cache-Control "public, max-age=86400";
        }
    }

    Mir ist bewusst, dass Bildoptimierung nichts mit Laravel zu tun hat, aber es ist ein so einfacher und mächtiger Trick (und wird so oft vernachlässigt), dass ich mir nicht helfen konnte.

    Autoloader-Optimierung

    Autoloading ist ein nettes, gar nicht so altes Feature in PHP, das die Sprache wohl vor dem Untergang bewahrt hat. Das Suchen und Laden der relevanten Klasse durch Entschlüsseln einer bestimmten Namespace-Zeichenfolge nimmt jedoch Zeit in Anspruch und kann in Produktionsbereitstellungen vermieden werden, in denen eine hohe Leistung wünschenswert ist. Wieder einmal hat Laravel eine Ein-Befehl-Lösung dafür:

    composer install --optimize-autoloader --no-dev

    Freunde dich mit Warteschlangen an

    Warteschlangen sind, wie Sie Dinge verarbeiten, wenn es viele davon gibt, und jeder von ihnen dauert einige Millisekunden, um abgeschlossen zu werden. Ein gutes Beispiel ist das Versenden von E-Mails – ein weit verbreiteter Anwendungsfall in Web-Apps ist das Versenden einiger Benachrichtigungs-E-Mails, wenn ein Benutzer bestimmte Aktionen ausführt.

    Beispielsweise möchten Sie bei einem neu eingeführten Produkt möglicherweise, dass die Unternehmensleitung (etwa 6-7 E-Mail-Adressen) benachrichtigt wird, wenn jemand eine Bestellung über einem bestimmten Wert aufgibt. Unter der Annahme, dass Ihr E-Mail-Gateway in 500 ms auf Ihre SMTP-Anfrage antworten kann, sprechen wir von guten 3-4 Sekunden Wartezeit für den Benutzer, bevor die Auftragsbestätigung einsetzt. Ein wirklich schlechtes Stück UX, da bin ich mir sicher, dass Sie es tun werden zustimmen.

    Die Abhilfe besteht darin, eingehende Jobs zu speichern, dem Benutzer mitzuteilen, dass alles gut gelaufen ist, und sie (einige Sekunden) später zu verarbeiten. Wenn ein Fehler auftritt, können die Jobs in der Warteschlange einige Male wiederholt werden, bevor sie als fehlgeschlagen deklariert werden.

    Quellennachweis: Microsoft.com

    Während ein Warteschlangensystem die Einrichtung ein wenig komplizierter macht (und etwas Überwachungsaufwand hinzufügt), ist es in einer modernen Webanwendung unverzichtbar.

    Asset-Optimierung (Laravel Mix)

    Stellen Sie für alle Front-End-Assets in Ihrer Laravel-Anwendung sicher, dass es eine Pipeline gibt, die alle Asset-Dateien kompiliert und minimiert. Diejenigen, die mit einem Bundler-System wie Webpack, Gulp, Parcel usw. vertraut sind, müssen sich nicht darum kümmern, aber wenn Sie dies nicht bereits tun, Laravel-Mischung ist eine klare Empfehlung.

    Mix ist ein leichtgewichtiger (und ehrlich gesagt entzückender) Wrapper für Webpack, der sich um alle Ihre CSS-, SASS-, JS- usw. Dateien für die Produktion kümmert. Eine typische .mix.js-Datei kann so klein sein und trotzdem Wunder wirken:

    const mix = require('laravel-mix');
    
    mix.js('resources/js/app.js', 'public/js')
        .sass('resources/sass/app.scss', 'public/css');

    Dies kümmert sich automatisch um Importe, Minifizierung, Optimierung und den ganzen Kram, wenn Sie bereit für die Produktion sind und npm run production ausführen. Mix kümmert sich nicht nur um herkömmliche JS- und CSS-Dateien, sondern auch um Vue- und React-Komponenten, die Sie möglicherweise in Ihrem Anwendungsworkflow haben.

    Mehr Info hier!

    Fazit

    Leistungsoptimierung ist mehr Kunst als Wissenschaft – zu wissen, wie und wie viel zu tun ist, ist wichtiger als was zu tun ist. Allerdings gibt es kein Ende dafür, wie viel und was Sie alles in einer Laravel-Anwendung optimieren können.

    Aber was auch immer Sie tun, ich möchte Ihnen einen Abschiedsratschlag mit auf den Weg geben – die Optimierung sollte erfolgen, wenn es einen triftigen Grund gibt, und nicht, weil es sich gut anhört oder weil Sie in Wirklichkeit wegen der App-Leistung für mehr als 100.000 Benutzer paranoid sind es sind nur 10.

    Wenn Sie sich nicht sicher sind, ob Sie Ihre App optimieren müssen oder nicht, müssen Sie nicht ins sprichwörtliche Wespennest treten. Eine funktionierende App, die sich langweilig anfühlt, aber genau das tut, was sie tun muss, ist zehnmal wünschenswerter als eine App, die zu einer mutierten Hybrid-Supermaschine optimiert wurde, aber hin und wieder flachfällt.

    Und für Neulinge, die ein Laravel-Meister werden wollen, schau dir das an Online Kurs.

    Mögen Ihre Apps viel, viel schneller laufen! 🙂