Geekflare est soutenu par son public. Nous pouvons percevoir des commissions d'affiliation sur les liens d'achat présents sur ce site.
En Développement Dernière mise à jour : 16 septembre 2023
Partager sur :
Invicti Web Application Security Scanner - la seule solution qui offre une vérification automatique des vulnérabilités avec Proof-Based Scanning™.

Laravel est beaucoup de choses. Mais la rapidité n'en fait pas partie. Apprenons quelques astuces pour aller plus vite !

Aucun développeur PHP n'est épargné par Laravel de nos jours. Il s'agit soit d'un développeur junior ou intermédiaire qui aime le développement rapide qu'offre Laravel, soit d'un développeur senior qui est contraint d'apprendre Laravel en raison de la pression du marché.

Quoi qu'il en soit, il est indéniable que Laravel a revitalisé l'écosystème PHP (pour ma part, j'aurais quitté le monde PHP depuis longtemps si Laravel n'avait pas existé).

Un peu d'autosatisfaction (quelque peu justifiée) de la part de Laravel

Cependant, comme Laravel se plie en quatre pour vous faciliter les choses, cela signifie qu'en dessous, il fait des tonnes et des tonnes de travail pour s'assurer que vous avez une vie confortable en tant que développeur. Toutes les fonctionnalités "magiques" de Laravel qui semblent fonctionner ont des couches et des couches de code qui doivent être élaborées à chaque fois qu'une fonctionnalité est exécutée. Même une simple exception montre à quel point le trou du lapin est profond (remarquez où l'erreur commence, jusqu'au noyau principal) :

Pour ce qui semble être une erreur de compilation dans l'une des vues, il y a 18 appels de fonction à tracer. J'en ai personnellement rencontré 40, et il pourrait facilement y en avoir plus si vous utilisez d'autres bibliothèques et plugins.

Le fait est que, par défaut, ces couches de code rendent Laravel lent.

Quelle est la lenteur de Laravel ?

Honnêtement, il est tout simplement impossible de répondre à cette question pour plusieurs raisons.

PremièreIl n'existe pas de norme acceptée, objective et sensée pour mesurer la vitesse des applications Web. Plus rapide ou plus lent par rapport à quoi ? Dans quelles conditions ?

DeuxièmeUne application Web dépend de tellement de choses (base de données, système de fichiers, réseau, cache, etc.) qu'il est tout simplement idiot de parler de vitesse. Une application Web très rapide avec une base de données très lente est une application Web très lente 🙂 .

Mais cette incertitude est précisément la raison pour laquelle les critères de référence sont populaires. Même s'ils ne signifient rien (voir cette), ils fournissent certains La vitesse est un cadre de référence qui nous aide à ne pas devenir fous. C'est pourquoi, avec plusieurs pincées de sel, nous allons nous faire une idée erronée et approximative de la vitesse parmi les éléments suivants Cadres PHP.

Si l'on se réfère à ce GitHub plutôt respectable sourceVoici comment les frameworks PHP se comparent entre eux :

Il se peut que vous ne remarquiez même pas Laravel ici (même si vous louchez très fort), à moins que vous n'alliez jusqu'au bout de la queue. Oui, chers amis, Laravel arrive en dernier ! Il est vrai que la plupart de ces "frameworks" ne sont pas très pratiques ou même utiles, mais cela nous montre à quel point Laravel est lent par rapport à d'autres frameworks plus populaires.

Normalement, cette "lenteur" n'apparaît pas dans les applications, car nos applications web quotidiennes atteignent rarement des chiffres élevés. Mais lorsque c'est le cas (disons plus de 200-500 simultanés), les serveurs commencent à s'étouffer et à mourir. C'est le moment où même le fait d'ajouter du matériel au problème ne suffit pas, et où les factures d'infrastructure grimpent si vite que vos grands idéaux en matière d'informatique dématérialisée s'effondrent.

Mais bon, courage ! Cet article ne parle pas de ce qui ne peut pas être fait, mais de ce qui peut être fait 🙂 .

La bonne nouvelle, c'est que vous pouvez faire beaucoup pour accélérer votre application Laravel. Plusieurs fois plus rapide. Oui, sans blague. Vous pouvez faire en sorte que la même base de code devienne balistique et économiser plusieurs centaines de dollars sur les factures d'infrastructure et d'hébergement chaque mois. Comment faire ? Allons-y.

Quatre types d'optimisations

Selon moi, l'optimisation peut se faire à quatre niveaux distincts (lorsqu'il s'agit de Applications PHPc'est-à-dire) :

  • Niveau de langue : Cela signifie que vous utilisez une version plus rapide du langage et que vous évitez les caractéristiques/styles de codage spécifiques du langage qui rendent votre code lent.
  • Niveau du cadre : Ce sont les points que nous allons aborder dans cet article.
  • Au niveau de l'infrastructure : Optimisation du gestionnaire de processus PHP, du serveur web, de la base de données, etc.
  • Au niveau du matériel : Passer à un matériel plus performant, plus rapide et plus puissant fournisseur d'hébergement.

Tous ces types d'optimisations ont leur place (par exemple, Optimisation de PHP-fpm est assez critique et puissant). Mais cet article se concentrera sur les optimisations de type 2 : celles liées au framework.

D'ailleurs, la numérotation n'a pas de raison d'être et n'est pas une norme acceptée. Je viens de les inventer. S'il vous plaît, ne me citez jamais en disant "Nous avons besoin d'une optimisation de type 3 sur notre serveur", ou votre chef d'équipe vous tuera, me trouvera et me tuera également. 😀

Et maintenant, nous arrivons enfin à la terre promise.

Attention aux requêtes de base de données n+1

Le problème des requêtes n+1 est courant lorsque l'on utilise des ORMs. Laravel dispose d'un ORM puissant appelé Eloquent, qui est si beau, si pratique, que nous oublions souvent de regarder ce qui se passe.

Considérons un scénario très courant : afficher la liste de toutes les commandes passées par une liste donnée de clients. Ce scénario est assez courant dans les systèmes de commerce électronique et dans toutes les interfaces de création de rapports en général, où nous devons afficher toutes les entités liées à certaines entités.

Dans Laravel, nous pourrions imaginer une fonction de contrôleur qui ferait le travail comme ceci :

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]);
    }
}

Douceur ! Et surtout, élégant, magnifique. 🤩🤩

Malheureusement, il s'agit d'une désastreux d'écrire du code dans Laravel.

Voici pourquoi.

Lorsque nous demandons à l'ORM de rechercher les clients donnés, une requête SQL comme celle-ci est générée :

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

Ce qui est exactement comme prévu. Par conséquent, toutes les lignes retournées sont stockées dans la collection $customers à l'intérieur de la fonction contrôleur.

Nous allons maintenant parcourir chaque client un par un et obtenir ses commandes. Cela exécute la requête suivante . . .

SELECT * FROM orders WHERE customer_id = 22;

. . autant de fois qu'il y a de clients.

En d'autres termes, si nous devons obtenir les données de commande de 1000 clients, le nombre total de requêtes exécutées dans la base de données sera de 1 (pour récupérer les données de tous les clients) + 1000 (pour récupérer les données de commande de chaque client) = 1001. C'est de là que vient le nom n+1.

Pouvons-nous faire mieux ? Certainement ! En utilisant ce que l'on appelle le chargement anticipé, nous pouvons forcer l'ORM à effectuer un JOIN et à renvoyer toutes les données nécessaires en une seule requête ! Voici ce que cela donne :

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

La structure de données résultante est imbriquée, certes, mais les données relatives à l'ordre peuvent être facilement extraites. La requête unique qui en résulte, dans ce cas, ressemble à quelque chose comme ceci :

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

Une seule requête vaut bien sûr mieux que mille requêtes supplémentaires. Imaginez ce qui se passerait s'il y avait 10 000 clients à traiter ! Ou, Dieu nous en préserve, si nous voulions également afficher les articles contenus dans chaque commande ! N'oubliez pas que le nom de la technique est "eager loading" et que c'est presque toujours une bonne idée.

Mettez la configuration en cache !

L'une des raisons de la flexibilité de Laravel est la multitude de fichiers de configuration qui font partie du framework. Vous voulez changer la façon dont les images sont stockées ?

Il suffit de modifier le config/filesystems.php (du moins à ce jour). Vous souhaitez travailler avec plusieurs gestionnaires de file d'attente ? N'hésitez pas à les décrire dans config/queue.php. J'ai compté et j'ai trouvé qu'il y avait 13 fichiers de configuration pour différents aspects du framework, ce qui garantit que vous ne serez pas déçu, quel que soit l'aspect que vous souhaitez modifier.

Compte tenu de la nature de PHP, chaque fois qu'une nouvelle requête Web arrive, Laravel se réveille, démarre tout, et analyse tous de ces fichiers de configuration pour savoir comment faire différemment cette fois-ci. Sauf que c'est stupide si rien n'a changé depuis quelques jours ! Reconstruire la configuration à chaque requête est un gâchis qui peut être (en fait, doit être) évité, et la solution est une simple commande offerte par Laravel :

php artisan config:cache

Cela permet de combiner tous les fichiers de configuration disponibles en un seul et de le mettre en cache quelque part pour une récupération rapide. La prochaine fois qu'il y aura une requête Web, Laravel lira simplement ce fichier unique et commencera à travailler.

Cela dit, la mise en cache de la configuration est une opération extrêmement délicate qui peut vous exploser à la figure. Le plus gros problème est qu'une fois que vous avez lancé cette commande, la commande env() partout, sauf dans les fichiers de configuration, renverront les données suivantes null!

C'est logique quand on y pense. Si vous utilisez la mise en cache de la configuration, vous dites au framework : "Vous savez quoi, je pense que j'ai bien configuré les choses et je suis 100% sûr que je ne veux pas qu'elles changent". En d'autres termes, vous vous attendez à ce que l'environnement reste statique, ce qui est le cas de .env sont destinés à.

Ceci étant dit, voici quelques règles inflexibles, sacrées et inébranlables de la mise en cache de la configuration :

  1. Ne le faites que sur un système de production.
  2. Ne le faites que si vous êtes vraiment, vraiment sûr de vouloir geler la configuration.
  3. En cas de problème, il est possible d'annuler le réglage à l'aide de la touche php artisan cache:clear
  4. Priez pour que les dommages causés à l'entreprise ne soient pas trop importants !

Réduire les services chargés automatiquement

Pour être utile, Laravel charge une tonne de services lorsqu'il se réveille. Ceux-ci sont disponibles dans le fichier config/app.php dans le cadre de la 'providers' clé de tableau. Voyons ce que j'ai dans mon cas :

/*
    |--------------------------------------------------------------------------
    | 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...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        Illuminate\Bus\BusServiceProvider::class,
        Illuminate\Cache\CacheServiceProvider::class,
        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
        Illuminate\Cookie\CookieServiceProvider::class,
        Illuminate\Database\DatabaseServiceProvider::class,
        Illuminate\Encryption\EncryptionServiceProvider::class,
        Illuminate\Filesystem\FilesystemServiceProvider::class,
        Illuminate\Foundation\Providers\FoundationServiceProvider::class,
        Illuminate\Hashing\HashServiceProvider::class,
        Illuminate\Mail\MailServiceProvider::class,
        Illuminate\Notifications\NotificationServiceProvider::class,
        Illuminate\Pagination\PaginationServiceProvider::class,
        Illuminate\Pipeline\PipelineServiceProvider::class,
        Illuminate\Queue\QueueServiceProvider::class,
        Illuminate\Redis\RedisServiceProvider::class,
        Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
        Illuminate\Session\SessionServiceProvider::class,
        Illuminate\Translation\TranslationServiceProvider::class,
        Illuminate\Validation\ValidationServiceProvider::class,
        Illuminate\View\ViewServiceProvider::class,

        /*
         * Package Service Providers...
         */

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

    ],

Une fois de plus, j'ai compté, et il y a 27 services répertoriés ! Il se peut que vous ayez besoin de tous ces services, mais c'est peu probable.

Par exemple, il se trouve que je construis une API REST en ce moment, ce qui signifie que je n'ai pas besoin du Session Service Provider, du View Service Provider, etc. Et comme je fais certaines choses à ma façon et que je ne suis pas les valeurs par défaut du framework, je peux aussi désactiver Auth Service Provider, Pagination Service Provider, Translation Service Provider, et ainsi de suite. Dans l'ensemble, près de la moitié de ces éléments sont inutiles pour mon cas d'utilisation.

Examinez attentivement votre application. A-t-elle besoin de tous ces fournisseurs de services ? Mais pour l'amour de Dieu, ne commentez pas aveuglément ces services et ne les mettez pas en production ! Exécutez tous les tests, vérifiez les choses manuellement sur les machines de développement et de mise en scène, et soyez très très paranoïaque avant d'appuyer sur la gâchette 🙂 .

Faire preuve de sagesse avec les piles d'intergiciels

Lorsque vous avez besoin d'un traitement personnalisé de la requête Web entrante, la création d'un nouvel intergiciel est la solution. Aujourd'hui, il est tentant d'ouvrir un app/Http/Kernel.php et coller l'intergiciel dans le web ou api De cette façon, elle devient disponible dans toute l'application et si elle ne fait pas quelque chose d'intrusif (comme enregistrer ou notifier, par exemple).

Cependant, au fur et à mesure que l'application se développe, cette collection d'intergiciels globaux peut devenir un fardeau silencieux pour l'application si tous (ou la majorité) sont présents dans chaque requête, même s'il n'y a pas de raison professionnelle pour cela.

En d'autres termes, faites attention à l'endroit où vous ajoutez/appliquez un nouvel intergiciel. Il peut être plus pratique d'ajouter quelque chose globalement, mais la pénalité de performance est très élevée à long terme. Je connais la douleur que vous auriez à subir si vous deviez appliquer sélectivement un intergiciel à chaque nouveau changement, mais c'est une douleur que j'accepterais volontiers et que je recommanderais !

Éviter l'ORM (parfois)

Bien qu'Eloquent rende de nombreux aspects de l'interaction avec la base de données agréables, cela se fait au détriment de la vitesse. En tant que mappeur, l'ORM doit non seulement récupérer les enregistrements de la base de données, mais aussi instancier les objets du modèle et les hydrater (les remplir) avec les données des colonnes.

Ainsi, si vous effectuez une simple $users = User::all() et qu'il y a, disons, 10 000 utilisateurs, le cadre récupérera 10 000 lignes de la base de données et fera en interne 10 000 new User() et de remplir leurs propriétés avec les données pertinentes. Il s'agit là d'un travail considérable effectué en coulisses, et si la base de données est le goulot d'étranglement de votre application, il est parfois judicieux de contourner le mécanisme de gestion des bases de données (ORM).

C'est particulièrement vrai pour les requêtes SQL complexes, pour lesquelles il faudrait sauter beaucoup de cerceaux et écrire des fermetures sur des fermetures pour aboutir à une requête efficace. Dans de tels cas, l'exécution d'un DB::raw() et il est préférable d'écrire la requête à la main.

Aller par cette L'étude des performances montre que même pour des insertions simples, Eloquent est beaucoup plus lent à mesure que le nombre d'enregistrements augmente :

Utiliser la mise en cache autant que possible

L'un des secrets les mieux gardés de l'optimisation des applications Web est la mise en cache.

Pour les non-initiés, la mise en cache consiste à précalculer et à stocker des résultats coûteux (coûteux en termes d'utilisation de l'unité centrale et de la mémoire), et à les renvoyer simplement lorsque la même requête est répétée.

Par exemple, dans un magasin de commerce électronique, on peut constater que sur les 2 millions de produits, la plupart du temps, les gens s'intéressent à ceux qui sont fraîchement stockés, dans une certaine fourchette de prix et pour un groupe d'âge particulier. Interroger la base de données pour obtenir ces informations est un gaspillage - puisque la requête ne change pas souvent, il est préférable de stocker ces résultats à un endroit où nous pouvons y accéder rapidement.

Laravel prend en charge de manière intégrée plusieurs types de cache. En plus d'utiliser un pilote de mise en cache et de construire le système de mise en cache à partir de la base, vous pourriez vouloir utiliser certains paquets Laravel qui facilitent la mise en place d'un système de mise en cache. mise en cache du modèle, mise en cache des requêtes, etc.

Notez toutefois qu'au-delà d'un certain cas d'utilisation simplifié, les paquets de mise en cache préconstruits peuvent causer plus de problèmes qu'ils n'en résolvent.

Préférer la mise en cache en mémoire

Lorsque vous mettez quelque chose en cache dans Laravel, vous avez plusieurs options pour stocker le calcul résultant qui doit être mis en cache. Ces options sont également connues sous le nom de pilotes de cache. Ainsi, bien qu'il soit possible et parfaitement raisonnable d'utiliser le système de fichiers pour stocker les résultats de la mise en cache, ce n'est pas vraiment ce que la mise en cache est censée être.

L'idéal est d'utiliser un cache en mémoire (vivant entièrement dans la RAM) comme Redis, Memcached, MongoDB, etc., de sorte qu'en cas de charge élevée, le cache serve à une utilisation vitale plutôt que de devenir lui-même un goulot d'étranglement.

On pourrait penser qu'avoir un disque SSD est presque la même chose qu'utiliser une clé RAM, mais c'est loin d'être le cas. Même les critères de référence montrent que la RAM est 10 à 20 fois plus performante que le SSD en termes de vitesse.

Mon système préféré en matière de mise en cache est Redis. Il est ridiculement rapide (100 000 opérations de lecture par seconde sont courantes) et, pour les très grands systèmes de cache, il peut être transformé en un système d'archivage de données. groupe facilement.

Mise en cache des itinéraires

Tout comme la configuration de l'application, les routes ne changent pas beaucoup avec le temps et sont un candidat idéal pour la mise en cache. C'est particulièrement vrai si, comme moi, vous ne supportez pas les gros fichiers et que vous finissez par diviser votre fichier web.php et api.php sur plusieurs fichiers. Une seule commande Laravel rassemble tous les itinéraires disponibles et les garde à portée de main pour un accès ultérieur :

php artisan route:cache

Et si vous devez ajouter ou modifier des itinéraires, faites-le :

php artisan route:clear

Optimisation des images et CDN

Les images sont le cœur et l'âme de la plupart des applications web. Par coïncidence, elles sont aussi les plus gros consommateurs de bande passante et l'une des principales raisons de la lenteur des applications/sites web. Si vous vous contentez de stocker naïvement les images téléchargées sur le serveur et de les renvoyer dans les réponses HTTP, vous laissez passer une énorme opportunité d'optimisation.

Ma première recommandation est de ne pas stocker les images localement - il y a le problème de la perte de données et, selon la région géographique dans laquelle se trouve votre client, le transfert de données peut être terriblement lent.

Optez plutôt pour une solution telle que Cloudinary qui redimensionne et optimise automatiquement les images à la volée.

Si ce n'est pas possible, utilisez quelque chose comme Cloudflare pour mettre en cache et servir les images pendant qu'elles sont stockées sur votre serveur.

Et si cela n'est pas possible, le fait de modifier légèrement le logiciel de votre serveur web pour compresser les fichiers et demander au navigateur du visiteur de les mettre en cache peut faire une grande différence. Voici un exemple de configuration de Nginx :

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";
    }
}

Je suis conscient que l'optimisation des images n'a rien à voir avec Laravel, mais c'est une astuce tellement simple et puissante (et si souvent négligée) que je n'ai pas pu m'en empêcher.

Optimisation de l'autochargeur

L'auto-chargement est une fonctionnalité intéressante et pas si ancienne de PHP qui a sans doute sauvé le langage de la mort. Cela dit, le processus de recherche et de chargement de la classe pertinente en déchiffrant une chaîne d'espace de noms donnée prend du temps et peut être évité dans les déploiements de production où de hautes performances sont souhaitables. Une fois de plus, Laravel propose une solution à commande unique :

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

Faites-vous des amis avec les files d'attente

Files d'attente sont la façon de traiter les choses lorsqu'elles sont nombreuses et que chacune d'entre elles prend quelques millisecondes. Un bon exemple est l'envoi de courriels - un cas d'utilisation très répandu dans les applications web consiste à envoyer quelques courriels de notification lorsqu'un utilisateur effectue certaines actions.

Par exemple, dans le cas d'un produit nouvellement lancé, vous pouvez souhaiter que les dirigeants de l'entreprise (6 à 7 adresses électroniques) soient informés chaque fois qu'une personne passe une commande d'un montant supérieur à une certaine valeur. En supposant que votre passerelle de messagerie puisse répondre à vos SMTP Si l'on considère que la demande d'achat est de 500 ms, on parle d'une attente de 3 à 4 secondes pour l'utilisateur avant que la confirmation de la commande n'intervienne. Vous conviendrez avec moi qu'il s'agit là d'un très mauvais aspect de l'interface utilisateur.

La solution consiste à stocker les travaux au fur et à mesure qu'ils arrivent, à dire à l'utilisateur que tout s'est bien passé et à les traiter (quelques secondes) plus tard. En cas d'erreur, les travaux mis en file d'attente peuvent être relancés plusieurs fois avant d'être déclarés comme ayant échoué.

Crédits : Microsoft.com

Bien qu'un système de file d'attente complique quelque peu l'installation (et ajoute une certaine surcharge de surveillance), il est indispensable dans une application Web moderne.

Optimisation des actifs (Laravel Mix)

Pour toutes les ressources frontales de votre application Laravel, assurez-vous qu'il y a un pipeline qui compile et minifie tous les fichiers de ressources. Ceux qui sont à l'aise avec un système de bundler comme Webpack, Gulp, Parcel, etc., n'ont pas besoin de s'en préoccuper, mais si vous ne le faites pas déjà, Laravel Mix est une recommandation solide.

Mix est une enveloppe légère (et délicieuse, en toute honnêteté !) autour de Webpack qui prend en charge tous vos fichiers CSS, SASS, JS, etc. pour la production. Un exemple typique de .mix.js peut être aussi petit que celui-ci et faire des merveilles :

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

Cela prend automatiquement en charge les importations, la minification, l'optimisation et tout le reste lorsque vous êtes prêt pour la production et l'exécution. npm run production. Mix prend en charge non seulement les fichiers JS et CSS traditionnels, mais aussi les composants Vue et React que vous pourriez avoir dans le flux de travail de votre application.

Plus d'informations ici!

Conclusion

L'optimisation des performances est plus un art qu'une science - savoir comment et combien faire est plus important que de savoir quoi faire. Cela dit, il n'y a pas de limite à ce qu'il est possible d'optimiser dans une application Laravel.

Mais quoi que vous fassiez, j'aimerais vous donner un dernier conseil : l'optimisation doit être effectuée lorsqu'il y a une bonne raison de le faire, et non pas parce que cela semble bien ou parce que vous êtes paranoïaque à propos des performances de l'application pour plus de 100 000 utilisateurs alors qu'en réalité il n'y en a que 10.

Si vous n'êtes pas sûr de devoir optimiser votre application, vous n'avez pas besoin de donner un coup de pied dans le nid de frelons proverbial. Une application qui semble ennuyeuse mais qui fait exactement ce qu'elle doit faire est dix fois plus souhaitable qu'une application qui a été optimisée pour devenir une supermachine hybride mutante mais qui tombe à plat de temps en temps.

Et pour les nouveaux venus qui souhaitent devenir des maîtres de Laravel, lisez ce qui suit cours en ligne.

Que vos applications fonctionnent beaucoup, beaucoup plus vite 🙂 .

  • Ankush
    Auteur
Merci à nos sponsors
D'autres lectures intéressantes sur le développement
Alimentez votre entreprise
Quelques outils et services pour aider votre entreprise à se développer.
  • Invicti utilise le Proof-Based Scanning™ pour vérifier automatiquement les vulnérabilités identifiées et générer des résultats exploitables en quelques heures seulement.
    Essayez Invicti
  • Web scraping, proxy résidentiel, proxy manager, web unlocker, search engine crawler, et tout ce dont vous avez besoin pour collecter des données web.
    Essayez Brightdata
  • Monday.com est un système d'exploitation tout-en-un qui vous aide à gérer vos projets, vos tâches, votre travail, vos ventes, votre CRM, vos opérations, vos flux de travail et bien plus encore.
    Essayez le lundi
  • Intruder est un scanner de vulnérabilité en ligne qui détecte les faiblesses de votre infrastructure en matière de cybersécurité, afin d'éviter des violations de données coûteuses.
    Essayer l'intrus