feat: enhance OPcache preload script with performance optimizations and detailed logging
This commit is contained in:
674
preload.php
674
preload.php
@@ -1,297 +1,743 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* OPcache Preload Script for PHP 8.3-FPM
|
||||
* High-Performance OPcache Preload Script for PHP 8.3-FPM
|
||||
* Optimized for Paymenter/VirtNet with Laravel 12, Filament 3, Livewire 3, Octane
|
||||
*
|
||||
* Configure in php.ini:
|
||||
* opcache.preload=/path/to/preload.php
|
||||
* Configure in php.ini or www.conf:
|
||||
* opcache.preload=/var/www/html/preload.php
|
||||
* opcache.preload_user=www-data
|
||||
* opcache.memory_consumption=512
|
||||
* opcache.interned_strings_buffer=128
|
||||
* opcache.max_accelerated_files=50000
|
||||
* opcache.validate_timestamps=0
|
||||
* opcache.save_comments=1
|
||||
* opcache.enable_file_override=1
|
||||
* opcache.jit=1255
|
||||
* opcache.jit_buffer_size=256M
|
||||
* opcache.jit_hot_func=127
|
||||
* opcache.jit_hot_loop=127
|
||||
* opcache.jit_hot_return=8
|
||||
* opcache.jit_hot_side_exit=8
|
||||
*
|
||||
* Run after deployment: php artisan optimize && php artisan filament:optimize
|
||||
* After deployment run:
|
||||
* php artisan optimize
|
||||
* php artisan filament:optimize
|
||||
* php artisan view:cache
|
||||
* php artisan event:cache
|
||||
* php artisan icons:cache
|
||||
* sudo systemctl reload php8.3-fpm
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// Ensure OPcache is available
|
||||
if (!function_exists('opcache_compile_file')) {
|
||||
die('OPcache extension is not loaded');
|
||||
}
|
||||
|
||||
$basePath = __DIR__;
|
||||
$preloadedCount = 0;
|
||||
$skippedCount = 0;
|
||||
|
||||
// Performance tracking
|
||||
$stats = [
|
||||
'preloaded' => 0,
|
||||
'skipped' => 0,
|
||||
'errors' => [],
|
||||
'start_time' => hrtime(true),
|
||||
'start_memory' => memory_get_usage(true),
|
||||
];
|
||||
|
||||
// =============================================================================
|
||||
// PRELOAD FUNCTIONS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Compile a file into OPcache without executing it
|
||||
* Compile a single file into OPcache
|
||||
* Returns true if successfully compiled
|
||||
*/
|
||||
function preloadFile(string $path): bool
|
||||
{
|
||||
global $preloadedCount, $skippedCount;
|
||||
global $stats;
|
||||
|
||||
// Fast path checks
|
||||
if (!is_file($path) || !is_readable($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip empty files
|
||||
if (filesize($path) === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (opcache_compile_file($path)) {
|
||||
$preloadedCount++;
|
||||
if (@opcache_compile_file($path)) {
|
||||
$stats['preloaded']++;
|
||||
return true;
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
// Silently skip files that can't be preloaded (syntax errors, etc.)
|
||||
$stats['errors'][] = basename($path) . ': ' . $e->getMessage();
|
||||
}
|
||||
|
||||
$skippedCount++;
|
||||
$stats['skipped']++;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively preload all PHP files in a directory
|
||||
* Preload files from array with existence check
|
||||
*/
|
||||
function preloadDirectory(string $dir, array $excludePatterns = []): void
|
||||
function preloadFiles(array $files): void
|
||||
{
|
||||
if (!is_dir($dir)) {
|
||||
foreach ($files as $file) {
|
||||
preloadFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively preload directory with filtering
|
||||
*/
|
||||
function preloadDirectory(string $dir, array $excludePatterns = [], int $maxDepth = 20): void
|
||||
{
|
||||
if (!is_dir($dir) || !is_readable($dir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS),
|
||||
new RecursiveDirectoryIterator(
|
||||
$dir,
|
||||
FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS
|
||||
),
|
||||
RecursiveIteratorIterator::LEAVES_ONLY
|
||||
);
|
||||
$iterator->setMaxDepth($maxDepth);
|
||||
|
||||
$files = [];
|
||||
foreach ($iterator as $file) {
|
||||
if (!$file->isFile() || $file->getExtension() !== 'php') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = $file->getRealPath();
|
||||
if ($path === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip excluded patterns
|
||||
// Apply exclude patterns
|
||||
$skip = false;
|
||||
foreach ($excludePatterns as $pattern) {
|
||||
if (preg_match($pattern, $path)) {
|
||||
continue 2;
|
||||
$skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$skip) {
|
||||
$files[] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort for consistent ordering (helps with JIT optimization)
|
||||
sort($files, SORT_STRING);
|
||||
|
||||
foreach ($files as $path) {
|
||||
preloadFile($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Preload specific files from a list
|
||||
* Preload specific classes from a namespace (using Composer's classmap)
|
||||
*/
|
||||
function preloadFiles(array $files): void
|
||||
function preloadClassmap(string $classmapFile): void
|
||||
{
|
||||
foreach ($files as $file) {
|
||||
if (is_file($file)) {
|
||||
preloadFile($file);
|
||||
}
|
||||
if (!is_file($classmapFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$classmap = require $classmapFile;
|
||||
if (!is_array($classmap)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($classmap as $class => $file) {
|
||||
preloadFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
// Global exclusion patterns (tests, stubs, dev-only files)
|
||||
$excludePatterns = [
|
||||
'#[/\\\\][Tt]ests?[/\\\\]#',
|
||||
'#[/\\\\][Ss]tubs?[/\\\\]#',
|
||||
'#[/\\\\][Ff]ixtures?[/\\\\]#',
|
||||
'#[/\\\\][Mm]ocks?[/\\\\]#',
|
||||
'#[Tt]est\.php$#',
|
||||
'#[Ss]tub\.php$#',
|
||||
'#[Ss]pec\.php$#',
|
||||
'#phpunit#i',
|
||||
'#[/\\\\]\.#', // Hidden files/dirs
|
||||
];
|
||||
|
||||
// =============================================================================
|
||||
// 1. LARAVEL CACHED/COMPILED FILES (Most Critical)
|
||||
// PHASE 1: COMPOSER AUTOLOADER (Load First - Critical)
|
||||
// =============================================================================
|
||||
|
||||
$cachedFiles = [
|
||||
// Autoloader must be preloaded first for class resolution
|
||||
$composerFiles = [
|
||||
$basePath . '/vendor/composer/ClassLoader.php',
|
||||
$basePath . '/vendor/composer/InstalledVersions.php',
|
||||
$basePath . '/vendor/composer/autoload_real.php',
|
||||
$basePath . '/vendor/composer/autoload_static.php',
|
||||
$basePath . '/vendor/composer/autoload_classmap.php',
|
||||
$basePath . '/vendor/composer/autoload_files.php',
|
||||
$basePath . '/vendor/composer/autoload_namespaces.php',
|
||||
$basePath . '/vendor/composer/autoload_psr4.php',
|
||||
$basePath . '/vendor/autoload.php',
|
||||
];
|
||||
|
||||
preloadFiles($composerFiles);
|
||||
|
||||
// Preload entire Composer classmap for maximum performance
|
||||
if (is_file($basePath . '/vendor/composer/autoload_classmap.php')) {
|
||||
preloadClassmap($basePath . '/vendor/composer/autoload_classmap.php');
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// PHASE 2: LARAVEL CACHED FILES (High Priority)
|
||||
// =============================================================================
|
||||
|
||||
$laravelCacheFiles = [
|
||||
// Core cached files
|
||||
$basePath . '/bootstrap/cache/packages.php',
|
||||
$basePath . '/bootstrap/cache/services.php',
|
||||
$basePath . '/bootstrap/cache/config.php',
|
||||
$basePath . '/bootstrap/cache/routes-v7.php',
|
||||
$basePath . '/bootstrap/cache/events.php',
|
||||
|
||||
// Filament cache
|
||||
$basePath . '/bootstrap/cache/filament.php',
|
||||
$basePath . '/bootstrap/cache/filament/panels.php',
|
||||
|
||||
// Livewire cache
|
||||
$basePath . '/bootstrap/cache/livewire-components.php',
|
||||
|
||||
// Icons cache (Blade Icons)
|
||||
$basePath . '/bootstrap/cache/blade-icons.php',
|
||||
];
|
||||
|
||||
preloadFiles($cachedFiles);
|
||||
preloadFiles($laravelCacheFiles);
|
||||
|
||||
// =============================================================================
|
||||
// 2. COMPOSER AUTOLOADER (Essential for class resolution)
|
||||
// PHASE 3: PSR INTERFACES (Required for type resolution)
|
||||
// =============================================================================
|
||||
|
||||
preloadFiles([
|
||||
$basePath . '/vendor/autoload.php',
|
||||
$basePath . '/vendor/composer/autoload_real.php',
|
||||
$basePath . '/vendor/composer/ClassLoader.php',
|
||||
$basePath . '/vendor/composer/autoload_static.php',
|
||||
]);
|
||||
$psrDirs = [
|
||||
$basePath . '/vendor/psr/container/src',
|
||||
$basePath . '/vendor/psr/http-message/src',
|
||||
$basePath . '/vendor/psr/http-client/src',
|
||||
$basePath . '/vendor/psr/http-factory/src',
|
||||
$basePath . '/vendor/psr/log/src',
|
||||
$basePath . '/vendor/psr/cache/src',
|
||||
$basePath . '/vendor/psr/simple-cache/src',
|
||||
$basePath . '/vendor/psr/event-dispatcher/src',
|
||||
$basePath . '/vendor/psr/clock/src',
|
||||
];
|
||||
|
||||
foreach ($psrDirs as $dir) {
|
||||
preloadDirectory($dir, $excludePatterns);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 3. LARAVEL CORE FRAMEWORK
|
||||
// PHASE 4: SYMFONY COMPONENTS (Laravel's HTTP Foundation)
|
||||
// =============================================================================
|
||||
|
||||
$laravelCoreDirs = [
|
||||
// Foundation & Core
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Foundation',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Container',
|
||||
$symfonyComponents = [
|
||||
// HTTP Foundation (most critical)
|
||||
$basePath . '/vendor/symfony/http-foundation',
|
||||
|
||||
// HTTP Kernel
|
||||
$basePath . '/vendor/symfony/http-kernel',
|
||||
|
||||
// Routing
|
||||
$basePath . '/vendor/symfony/routing',
|
||||
|
||||
// Event Dispatcher
|
||||
$basePath . '/vendor/symfony/event-dispatcher',
|
||||
$basePath . '/vendor/symfony/event-dispatcher-contracts',
|
||||
|
||||
// Console (for Artisan commands)
|
||||
$basePath . '/vendor/symfony/console',
|
||||
|
||||
// Error Handler
|
||||
$basePath . '/vendor/symfony/error-handler',
|
||||
|
||||
// Finder
|
||||
$basePath . '/vendor/symfony/finder',
|
||||
|
||||
// Process
|
||||
$basePath . '/vendor/symfony/process',
|
||||
|
||||
// Service Contracts
|
||||
$basePath . '/vendor/symfony/service-contracts',
|
||||
|
||||
// Translation
|
||||
$basePath . '/vendor/symfony/translation',
|
||||
$basePath . '/vendor/symfony/translation-contracts',
|
||||
|
||||
// Var Dumper (for debugging)
|
||||
$basePath . '/vendor/symfony/var-dumper',
|
||||
|
||||
// Mime
|
||||
$basePath . '/vendor/symfony/mime',
|
||||
|
||||
// Mailer
|
||||
$basePath . '/vendor/symfony/mailer',
|
||||
|
||||
// String (Slugger, etc.)
|
||||
$basePath . '/vendor/symfony/string',
|
||||
|
||||
// UID
|
||||
$basePath . '/vendor/symfony/uid',
|
||||
|
||||
// Clock
|
||||
$basePath . '/vendor/symfony/clock',
|
||||
];
|
||||
|
||||
foreach ($symfonyComponents as $dir) {
|
||||
preloadDirectory($dir, $excludePatterns, 10);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// PHASE 5: LARAVEL FRAMEWORK CORE
|
||||
// =============================================================================
|
||||
|
||||
$laravelCore = [
|
||||
// Contracts (interfaces - load first)
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Contracts',
|
||||
|
||||
// Container (DI)
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Container',
|
||||
|
||||
// Foundation
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Foundation',
|
||||
|
||||
// Support (helpers, traits, collections)
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Support',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Collections',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Conditionable',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Macroable',
|
||||
|
||||
// HTTP Layer
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Http',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Routing',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Pipeline',
|
||||
|
||||
// Database & Eloquent
|
||||
// Database & Eloquent (critical for your app)
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Database',
|
||||
|
||||
// Support utilities
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Support',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Collections',
|
||||
|
||||
// Session & Auth
|
||||
// Auth
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Auth',
|
||||
|
||||
// Session & Cookie
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Session',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Cookie',
|
||||
|
||||
// Cache
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Cache',
|
||||
|
||||
// Events
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Events',
|
||||
|
||||
// Queue
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Queue',
|
||||
|
||||
// Validation
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Validation',
|
||||
|
||||
// Views & Blade
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/View',
|
||||
|
||||
// Events & Queue
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Events',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Queue',
|
||||
|
||||
// Validation & Cache
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Validation',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Cache',
|
||||
// Mail
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Mail',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Notifications',
|
||||
|
||||
// Encryption & Hashing
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Encryption',
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Hashing',
|
||||
|
||||
// Filesystem
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Filesystem',
|
||||
|
||||
// Console
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Console',
|
||||
|
||||
// Log
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Log',
|
||||
|
||||
// Config
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Config',
|
||||
|
||||
// Translation
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Translation',
|
||||
|
||||
// Pagination
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Pagination',
|
||||
|
||||
// Bus (Commands)
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Bus',
|
||||
|
||||
// Process
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Process',
|
||||
|
||||
// Concurrency
|
||||
$basePath . '/vendor/laravel/framework/src/Illuminate/Concurrency',
|
||||
];
|
||||
|
||||
// Exclude test files and stubs
|
||||
$excludePatterns = [
|
||||
'/[Tt]est[s]?\.php$/',
|
||||
'/[Ss]tub[s]?\.php$/',
|
||||
'/[Ff]ixture[s]?/',
|
||||
];
|
||||
|
||||
foreach ($laravelCoreDirs as $dir) {
|
||||
foreach ($laravelCore as $dir) {
|
||||
preloadDirectory($dir, $excludePatterns);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 4. LIVEWIRE (Critical for your app)
|
||||
// PHASE 6: LARAVEL OCTANE (High Performance Server)
|
||||
// =============================================================================
|
||||
|
||||
preloadDirectory($basePath . '/vendor/laravel/octane/src', $excludePatterns);
|
||||
|
||||
// =============================================================================
|
||||
// PHASE 7: LARAVEL PASSPORT (API Authentication)
|
||||
// =============================================================================
|
||||
|
||||
preloadDirectory($basePath . '/vendor/laravel/passport/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/league/oauth2-server/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/lcobucci/jwt/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/lcobucci/clock/src', $excludePatterns);
|
||||
|
||||
// =============================================================================
|
||||
// PHASE 8: LIVEWIRE 3
|
||||
// =============================================================================
|
||||
|
||||
preloadDirectory($basePath . '/vendor/livewire/livewire/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/livewire/volt/src', $excludePatterns);
|
||||
|
||||
// =============================================================================
|
||||
// 5. FILAMENT (Admin Panel - Critical for your app)
|
||||
// PHASE 9: FILAMENT 3 (Admin Panel)
|
||||
// =============================================================================
|
||||
|
||||
$filamentDirs = [
|
||||
$filamentPackages = [
|
||||
// Core
|
||||
$basePath . '/vendor/filament/filament/src',
|
||||
$basePath . '/vendor/filament/support/src',
|
||||
|
||||
// Components
|
||||
$basePath . '/vendor/filament/forms/src',
|
||||
$basePath . '/vendor/filament/tables/src',
|
||||
$basePath . '/vendor/filament/actions/src',
|
||||
$basePath . '/vendor/filament/infolists/src',
|
||||
$basePath . '/vendor/filament/notifications/src',
|
||||
$basePath . '/vendor/filament/widgets/src',
|
||||
|
||||
// Spatie integration
|
||||
$basePath . '/vendor/filament/spatie-laravel-media-library-plugin/src',
|
||||
$basePath . '/vendor/filament/spatie-laravel-settings-plugin/src',
|
||||
$basePath . '/vendor/filament/spatie-laravel-tags-plugin/src',
|
||||
$basePath . '/vendor/filament/spatie-laravel-translatable-plugin/src',
|
||||
];
|
||||
|
||||
foreach ($filamentDirs as $dir) {
|
||||
foreach ($filamentPackages as $dir) {
|
||||
preloadDirectory($dir, $excludePatterns);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 6. COMMON DEPENDENCIES
|
||||
// PHASE 10: BLADE ICONS (Multiple icon sets you're using)
|
||||
// =============================================================================
|
||||
|
||||
$commonDeps = [
|
||||
// Symfony HTTP Foundation
|
||||
$basePath . '/vendor/symfony/http-foundation/Request.php',
|
||||
$basePath . '/vendor/symfony/http-foundation/Response.php',
|
||||
$basePath . '/vendor/symfony/http-foundation/HeaderBag.php',
|
||||
$basePath . '/vendor/symfony/http-foundation/ParameterBag.php',
|
||||
$basePath . '/vendor/symfony/http-foundation/InputBag.php',
|
||||
$basePath . '/vendor/symfony/http-foundation/FileBag.php',
|
||||
$basePath . '/vendor/symfony/http-foundation/ServerBag.php',
|
||||
$basePath . '/vendor/symfony/http-foundation/Cookie.php',
|
||||
$basePath . '/vendor/symfony/http-foundation/Session/Session.php',
|
||||
|
||||
// Symfony HTTP Kernel
|
||||
$basePath . '/vendor/symfony/http-kernel/HttpKernel.php',
|
||||
|
||||
// PSR Interfaces
|
||||
$basePath . '/vendor/psr/container/src/ContainerInterface.php',
|
||||
$basePath . '/vendor/psr/http-message/src/MessageInterface.php',
|
||||
$basePath . '/vendor/psr/http-message/src/RequestInterface.php',
|
||||
$basePath . '/vendor/psr/http-message/src/ResponseInterface.php',
|
||||
$basePath . '/vendor/psr/log/src/LoggerInterface.php',
|
||||
|
||||
// Carbon (Date handling)
|
||||
$basePath . '/vendor/nesbot/carbon/src/Carbon/Carbon.php',
|
||||
$basePath . '/vendor/nesbot/carbon/src/Carbon/CarbonInterface.php',
|
||||
$basePath . '/vendor/nesbot/carbon/src/Carbon/CarbonImmutable.php',
|
||||
$bladeIconPackages = [
|
||||
$basePath . '/vendor/blade-ui-kit/blade-icons/src',
|
||||
$basePath . '/vendor/blade-ui-kit/blade-heroicons/src',
|
||||
$basePath . '/vendor/andreiio/blade-remix-icon/src',
|
||||
$basePath . '/vendor/codeat3/blade-coolicons/src',
|
||||
$basePath . '/vendor/codeat3/blade-devicons/src',
|
||||
$basePath . '/vendor/codeat3/blade-file-icons/src',
|
||||
$basePath . '/vendor/codeat3/blade-vaadin-icons/src',
|
||||
$basePath . '/vendor/faisal50x/blade-ionicons/src',
|
||||
$basePath . '/vendor/postare/blade-mdi/src',
|
||||
];
|
||||
|
||||
preloadFiles($commonDeps);
|
||||
foreach ($bladeIconPackages as $dir) {
|
||||
preloadDirectory($dir, $excludePatterns);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 7. APPLICATION CODE (Your code)
|
||||
// PHASE 11: SPATIE PACKAGES
|
||||
// =============================================================================
|
||||
|
||||
$appDirs = [
|
||||
// Models (Most frequently accessed)
|
||||
$basePath . '/app/Models',
|
||||
$spatiePackages = [
|
||||
$basePath . '/vendor/spatie/laravel-cookie-consent/src',
|
||||
$basePath . '/vendor/spatie/laravel-query-builder/src',
|
||||
$basePath . '/vendor/spatie/laravel-package-tools/src',
|
||||
];
|
||||
|
||||
foreach ($spatiePackages as $dir) {
|
||||
preloadDirectory($dir, $excludePatterns);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// PHASE 12: OTHER CRITICAL DEPENDENCIES
|
||||
// =============================================================================
|
||||
|
||||
// Carbon (DateTime handling)
|
||||
preloadDirectory($basePath . '/vendor/nesbot/carbon/src', $excludePatterns);
|
||||
|
||||
// Monolog (Logging)
|
||||
preloadDirectory($basePath . '/vendor/monolog/monolog/src', $excludePatterns);
|
||||
|
||||
// Flysystem (File storage)
|
||||
preloadDirectory($basePath . '/vendor/league/flysystem/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/league/flysystem-local/src', $excludePatterns);
|
||||
|
||||
// Guzzle HTTP (API calls)
|
||||
preloadDirectory($basePath . '/vendor/guzzlehttp/guzzle/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/guzzlehttp/psr7/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/guzzlehttp/promises/src', $excludePatterns);
|
||||
|
||||
// DomPDF (PDF generation)
|
||||
preloadDirectory($basePath . '/vendor/barryvdh/laravel-dompdf/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/dompdf/dompdf/src', $excludePatterns);
|
||||
|
||||
// QR Code
|
||||
preloadDirectory($basePath . '/vendor/endroid/qr-code/src', $excludePatterns);
|
||||
|
||||
// Two Factor Auth
|
||||
preloadFile($basePath . '/vendor/robthree/twofactorauth/lib/TwoFactorAuth.php');
|
||||
preloadDirectory($basePath . '/vendor/robthree/twofactorauth/lib', $excludePatterns);
|
||||
|
||||
// Laravel Socialite (Social auth)
|
||||
preloadDirectory($basePath . '/vendor/laravel/socialite/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/socialiteproviders/discord/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/socialiteproviders/manager/src', $excludePatterns);
|
||||
|
||||
// ApexCharts
|
||||
preloadDirectory($basePath . '/vendor/akaunting/laravel-apexcharts/src', $excludePatterns);
|
||||
|
||||
// Laravel Trend
|
||||
preloadDirectory($basePath . '/vendor/flowframe/laravel-trend/src', $excludePatterns);
|
||||
|
||||
// Laravel Themer
|
||||
preloadDirectory($basePath . '/vendor/qirolab/laravel-themer/src', $excludePatterns);
|
||||
|
||||
// JSON API
|
||||
preloadDirectory($basePath . '/vendor/timacdonald/json-api/src', $excludePatterns);
|
||||
|
||||
// Cookie Consent
|
||||
preloadDirectory($basePath . '/vendor/whitecube/laravel-cookie-consent/src', $excludePatterns);
|
||||
|
||||
// Ramsey UUID
|
||||
preloadDirectory($basePath . '/vendor/ramsey/uuid/src', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/ramsey/collection/src', $excludePatterns);
|
||||
|
||||
// Doctrine (DBAL for migrations, Inflector for pluralization)
|
||||
preloadDirectory($basePath . '/vendor/doctrine/inflector/lib', $excludePatterns);
|
||||
preloadDirectory($basePath . '/vendor/doctrine/lexer/src', $excludePatterns);
|
||||
|
||||
// Vite manifest helper
|
||||
preloadDirectory($basePath . '/vendor/laravel/framework/src/Illuminate/Foundation/Vite', $excludePatterns);
|
||||
|
||||
// =============================================================================
|
||||
// PHASE 13: APPLICATION CODE (Your Code - Highest Priority)
|
||||
// =============================================================================
|
||||
|
||||
// Models (most frequently accessed)
|
||||
$modelFiles = [
|
||||
$basePath . '/app/Models/User.php',
|
||||
$basePath . '/app/Models/Service.php',
|
||||
$basePath . '/app/Models/Product.php',
|
||||
$basePath . '/app/Models/Invoice.php',
|
||||
$basePath . '/app/Models/InvoiceItem.php',
|
||||
$basePath . '/app/Models/InvoiceTransaction.php',
|
||||
$basePath . '/app/Models/Order.php',
|
||||
$basePath . '/app/Models/Ticket.php',
|
||||
$basePath . '/app/Models/TicketMessage.php',
|
||||
$basePath . '/app/Models/Gateway.php',
|
||||
$basePath . '/app/Models/Server.php',
|
||||
$basePath . '/app/Models/Category.php',
|
||||
$basePath . '/app/Models/Price.php',
|
||||
$basePath . '/app/Models/Plan.php',
|
||||
$basePath . '/app/Models/ConfigOption.php',
|
||||
$basePath . '/app/Models/Coupon.php',
|
||||
$basePath . '/app/Models/Property.php',
|
||||
$basePath . '/app/Models/Extension.php',
|
||||
$basePath . '/app/Models/Currency.php',
|
||||
$basePath . '/app/Models/Setting.php',
|
||||
$basePath . '/app/Models/Session.php',
|
||||
$basePath . '/app/Models/Role.php',
|
||||
$basePath . '/app/Models/ServiceConfig.php',
|
||||
$basePath . '/app/Models/ServiceCancellation.php',
|
||||
$basePath . '/app/Models/ServiceUpgrade.php',
|
||||
$basePath . '/app/Models/TaxRate.php',
|
||||
$basePath . '/app/Models/EmailTemplate.php',
|
||||
$basePath . '/app/Models/Credit.php',
|
||||
$basePath . '/app/Models/ApiKey.php',
|
||||
$basePath . '/app/Models/AuditLog.php',
|
||||
];
|
||||
|
||||
preloadFiles($modelFiles);
|
||||
|
||||
// Preload remaining models
|
||||
preloadDirectory($basePath . '/app/Models', $excludePatterns);
|
||||
|
||||
// Core application directories
|
||||
$appDirectories = [
|
||||
// HTTP Layer
|
||||
$basePath . '/app/Http/Controllers',
|
||||
$basePath . '/app/Http/Middleware',
|
||||
$basePath . '/app/Http/Requests',
|
||||
|
||||
// Livewire Components
|
||||
// Livewire Components (critical for UI)
|
||||
$basePath . '/app/Livewire',
|
||||
|
||||
// Filament Admin
|
||||
// Filament Admin Panel
|
||||
$basePath . '/app/Admin/Resources',
|
||||
$basePath . '/app/Admin/Pages',
|
||||
$basePath . '/app/Admin/Widgets',
|
||||
$basePath . '/app/Admin/Components',
|
||||
$basePath . '/app/Admin/Actions',
|
||||
$basePath . '/app/Admin/Clusters',
|
||||
|
||||
// Service Providers
|
||||
$basePath . '/app/Providers',
|
||||
|
||||
// Jobs & Events
|
||||
// Background Jobs
|
||||
$basePath . '/app/Jobs',
|
||||
|
||||
// Events & Listeners
|
||||
$basePath . '/app/Events',
|
||||
$basePath . '/app/Listeners',
|
||||
|
||||
// Helpers & Classes
|
||||
// Observers
|
||||
$basePath . '/app/Observers',
|
||||
|
||||
// Policies
|
||||
$basePath . '/app/Policies',
|
||||
|
||||
// Classes & Helpers
|
||||
$basePath . '/app/Classes',
|
||||
$basePath . '/app/Helpers',
|
||||
$basePath . '/app/Support',
|
||||
$basePath . '/app/Traits',
|
||||
|
||||
// Policies & Rules
|
||||
$basePath . '/app/Policies',
|
||||
// Validation Rules
|
||||
$basePath . '/app/Rules',
|
||||
|
||||
// Mail
|
||||
$basePath . '/app/Mail',
|
||||
|
||||
// View Components
|
||||
$basePath . '/app/View',
|
||||
|
||||
// Attributes
|
||||
$basePath . '/app/Attributes',
|
||||
|
||||
// Exceptions
|
||||
$basePath . '/app/Exceptions',
|
||||
|
||||
// Console Commands
|
||||
$basePath . '/app/Console/Commands',
|
||||
];
|
||||
|
||||
foreach ($appDirs as $dir) {
|
||||
preloadDirectory($dir);
|
||||
foreach ($appDirectories as $dir) {
|
||||
preloadDirectory($dir, $excludePatterns);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 8. BLADE COMPILED VIEWS (if using view caching)
|
||||
// PHASE 14: EXTENSIONS (Payment Gateways, Servers, etc.)
|
||||
// =============================================================================
|
||||
|
||||
$extensionDirs = [
|
||||
$basePath . '/extensions/Gateways',
|
||||
$basePath . '/extensions/Servers',
|
||||
$basePath . '/extensions/Others',
|
||||
];
|
||||
|
||||
foreach ($extensionDirs as $dir) {
|
||||
preloadDirectory($dir, $excludePatterns);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// PHASE 15: THEMES
|
||||
// =============================================================================
|
||||
|
||||
preloadDirectory($basePath . '/themes/lucentui', $excludePatterns);
|
||||
|
||||
// =============================================================================
|
||||
// PHASE 16: COMPILED BLADE VIEWS (Most Recent)
|
||||
// =============================================================================
|
||||
|
||||
// Only preload if compiled views exist and are recent
|
||||
$compiledViewsPath = $basePath . '/storage/framework/views';
|
||||
if (is_dir($compiledViewsPath)) {
|
||||
// Limit to most recently modified compiled views (top 200)
|
||||
$viewFiles = glob($compiledViewsPath . '/*.php');
|
||||
if ($viewFiles) {
|
||||
// Sort by modification time, newest first
|
||||
usort($viewFiles, fn($a, $b) => filemtime($b) - filemtime($a));
|
||||
$viewFiles = array_slice($viewFiles, 0, 200);
|
||||
usort($viewFiles, static fn($a, $b) => filemtime($b) <=> filemtime($a));
|
||||
// Preload top 500 most recently used views
|
||||
$viewFiles = array_slice($viewFiles, 0, 500);
|
||||
preloadFiles($viewFiles);
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// SUMMARY (logged to error_log for debugging)
|
||||
// PHASE 17: CONFIG FILES
|
||||
// =============================================================================
|
||||
|
||||
if (php_sapi_name() === 'cli') {
|
||||
echo "OPcache Preload Complete: {$preloadedCount} files preloaded, {$skippedCount} skipped\n";
|
||||
echo "Memory usage: " . round(memory_get_usage(true) / 1024 / 1024, 2) . " MB\n";
|
||||
preloadDirectory($basePath . '/config', $excludePatterns);
|
||||
preloadFile($basePath . '/bootstrap/app.php');
|
||||
preloadFile($basePath . '/bootstrap/providers.php');
|
||||
|
||||
// =============================================================================
|
||||
// PRELOAD SUMMARY & LOGGING
|
||||
// =============================================================================
|
||||
|
||||
$stats['end_time'] = hrtime(true);
|
||||
$stats['end_memory'] = memory_get_usage(true);
|
||||
|
||||
$duration = round(($stats['end_time'] - $stats['start_time']) / 1e6, 2); // ms
|
||||
$memoryUsed = round(($stats['end_memory'] - $stats['start_memory']) / 1024 / 1024, 2); // MB
|
||||
$totalMemory = round($stats['end_memory'] / 1024 / 1024, 2); // MB
|
||||
|
||||
$summary = sprintf(
|
||||
'OPcache Preload: %d files preloaded, %d skipped in %.2fms (Memory: %.2fMB used, %.2fMB total)',
|
||||
$stats['preloaded'],
|
||||
$stats['skipped'],
|
||||
$duration,
|
||||
$memoryUsed,
|
||||
$totalMemory
|
||||
);
|
||||
|
||||
// Log summary
|
||||
if (PHP_SAPI === 'cli') {
|
||||
echo $summary . PHP_EOL;
|
||||
|
||||
if (!empty($stats['errors'])) {
|
||||
echo "Errors (" . count($stats['errors']) . "):\n";
|
||||
foreach (array_slice($stats['errors'], 0, 10) as $error) {
|
||||
echo " - {$error}\n";
|
||||
}
|
||||
if (count($stats['errors']) > 10) {
|
||||
echo " ... and " . (count($stats['errors']) - 10) . " more errors\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Show OPcache status
|
||||
if (function_exists('opcache_get_status')) {
|
||||
$status = opcache_get_status(false);
|
||||
if ($status) {
|
||||
echo sprintf(
|
||||
"OPcache Status: %d cached scripts, %.2fMB memory used, %.2f%% hit rate\n",
|
||||
$status['opcache_statistics']['num_cached_scripts'] ?? 0,
|
||||
($status['memory_usage']['used_memory'] ?? 0) / 1024 / 1024,
|
||||
$status['opcache_statistics']['opcache_hit_rate'] ?? 0
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error_log("OPcache Preload: {$preloadedCount} files preloaded, {$skippedCount} skipped");
|
||||
error_log($summary);
|
||||
}
|
||||
|
||||
// Force garbage collection to free memory
|
||||
gc_collect_cycles();
|
||||
|
||||
Reference in New Issue
Block a user