Performance Optimization di NexaUI Framework

Pengenalan

Performa aplikasi yang optimal sangat penting untuk memberikan pengalaman pengguna yang baik. NexaUI menyediakan berbagai fitur dan teknik untuk mengoptimalkan performa aplikasi Anda. Dokumen ini akan membahas praktik terbaik dan strategi untuk meningkatkan performa aplikasi NexaUI Anda.

Optimasi Aplikasi

Config Caching

Salah satu cara termudah untuk meningkatkan performa aplikasi NexaUI adalah dengan menggunakan config caching. Ini menggabungkan semua file konfigurasi menjadi satu file cache, mengurangi waktu yang diperlukan untuk memuat dan memproses file konfigurasi.

php nexa config:cache

Untuk menghapus cache konfigurasi (misalnya, selama pengembangan):

php nexa config:clear

Route Caching

Route caching dapat meningkatkan performa aplikasi secara signifikan, terutama jika Anda memiliki banyak route. Ini mengkompilasi semua route terdaftar menjadi satu file cache.

php nexa route:cache

Untuk menghapus cache route:

php nexa route:clear

Catatan: Route caching hanya berfungsi jika semua route Anda menggunakan penutupan atau controller. Route yang menggunakan fungsi callback tidak dapat di-cache.

View Caching

NexaUI secara otomatis mengkompilasi view menjadi PHP untuk meningkatkan performa. Anda dapat mem-precompile semua view untuk menghindari overhead kompilasi saat runtime:

php nexa view:cache

Untuk menghapus cache view:

php nexa view:clear

Autoloader Optimization

Composer menyediakan optimasi autoloader yang dapat meningkatkan performa aplikasi Anda. Gunakan flag --optimize saat menginstal atau memperbarui dependensi:

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

Ini menghasilkan classmap untuk autoloader Composer, yang lebih cepat daripada autoloading standar PSR-4.

Optimasi Database

Query Caching

NexaUI mendukung query caching untuk mengurangi beban database:

// Cache query selama 60 detik
$users = DB::table('users')->cache(60)->get();

// Cache query dengan key kustom
$users = DB::table('users')->cache(60, 'all-active-users')->where('active', 1)->get();

// Hapus cache
DB::flushQueryCache('all-active-users');

Eager Loading

Untuk menghindari masalah N+1 query, gunakan eager loading saat mengambil data dengan relasi:

// Tanpa eager loading (tidak efisien)
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name; // Ini akan melakukan query terpisah untuk setiap post
}

// Dengan eager loading (lebih efisien)
$posts = Post::with('author')->get();
foreach ($posts as $post) {
    echo $post->author->name; // Tidak ada query tambahan
}

Chunking Results

Saat bekerja dengan dataset besar, gunakan chunking untuk mengurangi penggunaan memori:

// Memproses ribuan baris tanpa kehabisan memori
DB::table('users')->chunk(100, function ($users) {
    foreach ($users as $user) {
        // Proses setiap user
    }
});

Query Optimization

Pastikan query Anda dioptimalkan:

  • Gunakan indeks pada kolom yang sering digunakan dalam klausa WHERE, ORDER BY, atau JOIN
  • Hindari penggunaan SELECT * dan pilih hanya kolom yang Anda butuhkan
  • Gunakan EXPLAIN untuk menganalisis dan mengoptimalkan query
  • Pertimbangkan untuk menggunakan subquery atau JOIN berdasarkan kasus penggunaan
// Menggunakan EXPLAIN untuk menganalisis query
DB::statement('EXPLAIN SELECT * FROM users WHERE email = ?', ['john@example.com']);

Connection Pooling

Untuk aplikasi dengan trafik tinggi, gunakan connection pooling untuk mengurangi overhead pembuatan koneksi database:

'mysql' => [
    // Other options...
    'pool' => [
        'min' => 5,
        'max' => 20,
        'timeout' => 30,
    ],
],

Optimasi Frontend

Asset Bundling

NexaUI mendukung bundling asset untuk mengurangi jumlah HTTP request dan ukuran file:

// Konfigurasi di config/assets.php
return [
    'bundles' => [
        'css' => [
            'output' => 'css/app.min.css',
            'files' => [
                'css/normalize.css',
                'css/main.css',
                'css/components.css',
            ],
        ],
        'js' => [
            'output' => 'js/app.min.js',
            'files' => [
                'js/vendor/jquery.js',
                'js/main.js',
                'js/components.js',
            ],
        ],
    ],
];

Untuk menghasilkan bundle:

php nexa asset:bundle

Asset Minification

Minifikasi CSS dan JavaScript untuk mengurangi ukuran file:

php nexa asset:minify

Browser Caching

Konfigurasikan browser caching untuk asset statis dengan menambahkan header cache-control di server web Anda atau di middleware NexaUI:

<?php
// app/Middleware/CacheControl.php

namespace App\Middleware;

use Closure;

class CacheControl
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        
        // Cek jika request adalah untuk asset statis
        if ($this->isStaticAsset($request->path())) {
            $response->header('Cache-Control', 'public, max-age=31536000');
        }
        
        return $response;
    }
    
    protected function isStaticAsset($path)
    {
        $extensions = ['css', 'js', 'jpg', 'jpeg', 'png', 'gif', 'ico', 'svg', 'woff', 'woff2', 'ttf', 'eot'];
        $pathInfo = pathinfo($path);
        
        return isset($pathInfo['extension']) && in_array($pathInfo['extension'], $extensions);
    }
}

Lazy Loading

Implementasikan lazy loading untuk gambar dan konten berat lainnya:

<img src="placeholder.jpg" data-src="actual-image.jpg" class="lazy" alt="Lazy loaded image">

Dengan JavaScript:

document.addEventListener('DOMContentLoaded', function() {
    var lazyImages = [].slice.call(document.querySelectorAll('img.lazy'));
    
    if ('IntersectionObserver' in window) {
        let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
            entries.forEach(function(entry) {
                if (entry.isIntersecting) {
                    let lazyImage = entry.target;
                    lazyImage.src = lazyImage.dataset.src;
                    lazyImage.classList.remove('lazy');
                    lazyImageObserver.unobserve(lazyImage);
                }
            });
        });
        
        lazyImages.forEach(function(lazyImage) {
            lazyImageObserver.observe(lazyImage);
        });
    }
});

Optimasi Cache

Data Caching

Gunakan sistem cache untuk menyimpan data yang sering diakses atau mahal untuk dihasilkan:

// Menyimpan data di cache selama 60 menit
Cache::put('key', $value, 60);

// Mengambil data dari cache
$value = Cache::get('key');

// Mengambil data dari cache atau menghitung jika tidak ada
$value = Cache::remember('key', 60, function () {
    return expensiveOperation();
});

Cache Drivers

NexaUI mendukung berbagai driver cache:

  • File - Menyimpan cache di filesystem
  • Database - Menyimpan cache di database
  • Memcached - Menggunakan Memcached untuk caching
  • Redis - Menggunakan Redis untuk caching
  • Array - Menyimpan cache di memori (hanya untuk request saat ini)

Konfigurasi driver cache di config/cache.php:

'default' => env('CACHE_DRIVER', 'file'),

Full Page Caching

Untuk halaman yang jarang berubah, gunakan full page caching:

<?php
// routes/web.php

Route::get('/blog', function () {
    return Cache::remember('blog-page', 60, function () {
        return view('blog.index', [
            'posts' => Post::latest()->get()
        ]);
    });
});

Cache Tags

Gunakan cache tags untuk mengelompokkan item cache terkait:

// Menyimpan item cache dengan tag
Cache::tags(['users', 'profile'])->put('user:1', $user, 60);

// Mengambil item cache dengan tag
$user = Cache::tags(['users', 'profile'])->get('user:1');

// Menghapus semua item cache dengan tag tertentu
Cache::tags('users')->flush();

Catatan: Tidak semua driver cache mendukung tags. File dan database driver tidak mendukung tags.

Optimasi Server

PHP OPcache

Aktifkan PHP OPcache untuk meningkatkan performa PHP dengan menyimpan skrip yang telah dikompilasi di memori:

; Di php.ini
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1

Web Server Caching

Konfigurasikan web server Anda (Apache, Nginx) untuk caching dan kompresi:

Untuk Nginx:

# Di konfigurasi Nginx
# Aktifkan Gzip compression
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
  application/atom+xml
  application/javascript
  application/json
  application/ld+json
  application/manifest+json
  application/rss+xml
  application/vnd.geo+json
  application/vnd.ms-fontobject
  application/x-font-ttf
  application/x-web-app-manifest+json
  application/xhtml+xml
  application/xml
  font/opentype
  image/bmp
  image/svg+xml
  image/x-icon
  text/cache-manifest
  text/css
  text/plain
  text/vcard
  text/vnd.rim.location.xloc
  text/vtt
  text/x-component
  text/x-cross-domain-policy;

# Cache statis
location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|ttf|woff|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, no-transform";
}

Untuk Apache:

# Di .htaccess atau konfigurasi Apache
<IfModule mod_deflate.c>
  # Aktifkan kompresi untuk tipe konten berikut
  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/xml
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>

<IfModule mod_expires.c>
  ExpiresActive On
  
  # Gambar
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType image/x-icon "access plus 1 year"
  
  # Video
  ExpiresByType video/mp4 "access plus 1 year"
  ExpiresByType video/mpeg "access plus 1 year"
  
  # CSS, JavaScript
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType text/javascript "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
  
  # Font
  ExpiresByType font/ttf "access plus 1 year"
  ExpiresByType font/otf "access plus 1 year"
  ExpiresByType font/woff "access plus 1 year"
  ExpiresByType font/woff2 "access plus 1 year"
  ExpiresByType application/font-woff "access plus 1 year"
  
  # Default
  ExpiresDefault "access plus 2 days"
</IfModule>

Content Delivery Network (CDN)

Gunakan CDN untuk menyajikan asset statis dari server yang lebih dekat dengan pengguna:

// Di config/app.php
'asset_url' => env('ASSET_URL', 'https://cdn.example.com'),

Kemudian gunakan helper asset() untuk menghasilkan URL:

<link rel="stylesheet" href="{{ asset('css/app.css') }}">

Monitoring dan Profiling

Debug Bar

NexaUI menyediakan Debug Bar yang dapat membantu Anda mengidentifikasi bottleneck performa:

// Aktifkan Debug Bar di config/app.php
'debug_bar' => env('APP_DEBUG', false),

Debug Bar menampilkan informasi tentang:

  • Query database dan waktu eksekusi
  • Request dan response
  • Penggunaan memori
  • Waktu eksekusi
  • Cache hits dan misses
  • Route dan controller yang digunakan

Query Logging

Aktifkan query logging untuk mengidentifikasi query yang lambat:

// Aktifkan query logging
DB::enableQueryLog();

// Jalankan beberapa query
// ...

// Ambil log query
$queries = DB::getQueryLog();

Application Profiling

Gunakan profiler untuk mengukur waktu eksekusi bagian kode tertentu:

// Mulai profiling
$profiler = app('profiler')->start('operation-name');

// Kode yang ingin diprofile
// ...

// Akhiri profiling
$profiler->stop();

// Lihat hasil profiling
$results = app('profiler')->results();

Optimasi Deployment

Autoloader Optimization

Seperti disebutkan sebelumnya, optimalkan autoloader saat deployment:

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

Cache Configuration

Cache konfigurasi, route, dan view saat deployment:

php nexa config:cache
php nexa route:cache
php nexa view:cache

Disable Debug Mode

Pastikan mode debug dinonaktifkan di lingkungan production:

// Di .env
APP_ENV=production
APP_DEBUG=false

Praktik Terbaik

  • Identifikasi Bottleneck - Gunakan profiling dan monitoring untuk mengidentifikasi bagian aplikasi yang lambat.
  • Optimasi Database - Database sering menjadi bottleneck performa. Pastikan query dioptimalkan dan indeks digunakan dengan benar.
  • Gunakan Caching - Cache data yang sering diakses atau mahal untuk dihasilkan.
  • Minimalkan HTTP Request - Gabungkan dan minifikasi asset untuk mengurangi jumlah HTTP request.
  • Optimalkan Gambar - Kompres dan resize gambar untuk mengurangi ukuran file.
  • Gunakan Lazy Loading - Muat konten hanya ketika diperlukan.
  • Implementasikan Browser Caching - Konfigurasikan browser caching untuk asset statis.
  • Pertimbangkan CDN - Gunakan CDN untuk menyajikan asset statis.
  • Optimalkan Server - Konfigurasikan server web dan PHP untuk performa optimal.
  • Gunakan Queue untuk Tugas Berat - Pindahkan tugas berat ke queue background untuk menghindari blocking request.

Kesimpulan

Optimasi performa adalah proses berkelanjutan yang melibatkan identifikasi bottleneck, implementasi perbaikan, dan pengukuran hasil. NexaUI menyediakan berbagai alat dan teknik untuk membantu Anda mengoptimalkan aplikasi Anda. Dengan mengikuti praktik terbaik dan menggunakan fitur yang disediakan oleh NexaUI, Anda dapat membangun aplikasi yang cepat, efisien, dan responsif.