ShahiAssist

Performance Optimization

Optimizing ShahiAssist for high performance ensures fast loading times, efficient database queries, and scalable operations. This guide covers various optimization techniques and best practices.

Database Optimization

Query Optimization

Efficient Ticket Queries

`php
// Instead of multiple queries
$tickets = get_posts([
‘post_type’ => ‘ticket’,
‘postsperpage’ => -1,
‘meta_query’ => [
[
‘key’ => ‘ticketstatus’,
‘value’ => ‘open’,
]
]
]);

// Use single optimized query
global $wpdb;
$tickets = $wpdb->get_results($wpdb->prepare(“
SELECT p.ID, p.posttitle, p.postdate, pm.meta_value as status
FROM {$wpdb->posts} p
INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_type = ‘ticket’
AND p.post_status = ‘publish’
AND pm.metakey = ‘ticket_status’
AND pm.meta_value = ‘open’
ORDER BY p.post_date DESC
LIMIT %d
“, 50));
`

Meta Query Optimization

`php
// Use single meta query instead of multiple
$args = [
‘post_type’ => ‘ticket’,
‘meta_query’ => [
‘relation’ => ‘AND’,
[
‘key’ => ‘ticketstatus’,
‘value’ => ‘open’,
],
[
‘key’ => ‘ticketpriority’,
‘value’ => ‘high’,
‘compare’ => ‘>=’,
]
]
];
`

Indexing Strategy

Custom Database Indexes

`php
// Add to activation hook
global $wpdb;
$tablename = $wpdb->prefix . ‘shahiassistticketmeta’;

$wpdb->query(“
CREATE TABLE IF NOT EXISTS $table_name (
metaid bigint(20) unsigned NOT NULL AUTOINCREMENT,
ticket_id bigint(20) unsigned NOT NULL,
meta_key varchar(255) DEFAULT NULL,
meta_value longtext,
PRIMARY KEY (meta_id),
KEY ticketid (ticketid),
KEY metakey (metakey(191)),
KEY statuspriority (metakey(50), meta_value(50))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4unicodeci;
“);

// Add composite index for common queries
$wpdb->query(“
ALTER TABLE $table_name
ADD INDEX idxstatusdate (metakey, metavalue, ticket_id)
“);
`

Optimize Existing Tables

`php
// Run during maintenance
global $wpdb;

// Add indexes to existing tables
$wpdb->query(“ALTER TABLE {$wpdb->posts} ADD INDEX idxposttypestatus (posttype, post_status)”);
$wpdb->query(“ALTER TABLE {$wpdb->postmeta} ADD INDEX idxmetakeyvalue (metakey(50), meta_value(100))”);

// Analyze and optimize tables
$wpdb->query(“ANALYZE TABLE {$wpdb->posts}, {$wpdb->postmeta}”);
$wpdb->query(“OPTIMIZE TABLE {$wpdb->posts}, {$wpdb->postmeta}”);
`

Caching Strategies

Object Caching

Transient API for Expensive Operations

`php
function getticketstats() {
$cachekey = ‘shahiassistticketstats’;
$stats = gettransient($cachekey);

if ($stats === false) {
$stats = [
‘open’ => wpcountposts(‘ticket’)->publish,
‘closed’ => get_posts([
‘post_type’ => ‘ticket’,
‘metakey’ => ‘ticket_status’,
‘meta_value’ => ‘closed’,
‘fields’ => ‘ids’,
]),
‘total’ => wpcountposts(‘ticket’)->publish + wpcountposts(‘ticket’)->draft,
];

settransient($cachekey, $stats, HOURINSECONDS);
}

return $stats;
}

// Clear cache when tickets are updated
addaction(‘savepost_ticket’, function() {
deletetransient(‘shahiassistticketstats’);
});
`

WP Object Cache

`php
function getpopularkb_articles() {
$cachekey = ‘popularkb_articles’;
$articles = wpcacheget($cachekey, ‘shahiassist’);

if ($articles === false) {
$articles = get_posts([
‘posttype’ => ‘kbarticle’,
‘metakey’ => ‘view_count’,
‘orderby’ => ‘metavaluenum’,
‘order’ => ‘DESC’,
‘postsperpage’ => 10,
]);

wpcacheset($cachekey, $articles, ‘shahiassist’, 6 * HOURINSECONDS);
}

return $articles;
}
`

Fragment Caching

Cache Template Parts

`php
function getcachedticketlist($userid, $status = ‘all’) {
$cachekey = “ticketlist{$userid}_{$status}”;
$output = wpcacheget($cachekey, ‘shahiassist’);

if ($output === false) {
ob_start();
// Generate ticket list HTML
include gettemplatedirectory() . ‘/shahi-assist/ticket-list.php’;
$output = obgetclean();

wpcacheset($cachekey, $output, ‘shahiassist’, 15 * MINUTEINSECONDS);
}

return $output;
}
`

Opcode Caching

Ensure OPcache is configured:
`ini
; php.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.maxacceleratedfiles=7963
opcache.revalidate_freq=0
opcache.fast_shutdown=1
`

Asset Optimization

CSS and JavaScript Minification

`php
// Use during development, minify for production
function enqueueoptimizedassets() {
$isproduction = !defined(‘WPDEBUG’) || !WP_DEBUG;

if ($is_production) {
wpenqueuestyle(‘shahi-assist’, plugindirurl(FILE) . ‘assets/css/shahi-assist.min.css’, [], ‘1.0.0’);
wpenqueuescript(‘shahi-assist’, plugindirurl(FILE) . ‘assets/js/shahi-assist.min.js’, [‘jquery’], ‘1.0.0’, true);
} else {
wpenqueuestyle(‘shahi-assist’, plugindirurl(FILE) . ‘assets/css/shahi-assist.css’, [], ‘1.0.0’);
wpenqueuescript(‘shahi-assist’, plugindirurl(FILE) . ‘assets/js/shahi-assist.js’, [‘jquery’], ‘1.0.0’, true);
}
}
addaction(‘wpenqueuescripts’, ‘enqueueoptimized_assets’);
`

Lazy Loading Assets

`php
function conditionallyenqueueassets() {
// Only load on pages that need ShahiAssist
if (!issingular(‘ticket’) && !isposttypearchive(‘kbarticle’) && !hasshortcode(getpost()->postcontent ?? ”, ‘shahi_assist’)) {
return;
}

wpenqueuestyle(‘shahi-assist’);
wpenqueuescript(‘shahi-assist’);
}
addaction(‘wpenqueuescripts’, ‘conditionallyenqueue_assets’);
`

Asset Versioning

`php
function getassetversion($file) {
$filepath = plugindir_path(FILE) . $file;
return fileexists($filepath) ? filemtime($file_path) : ‘1.0.0’;
}

wpenqueuestyle(‘shahi-assist’, pluginsurl(‘assets/css/style.css’, FILE), [], getasset_version(‘assets/css/style.css’));
`

Frontend Performance

AJAX Optimization

`php
// Debounce rapid requests
let ticketSearchTimeout;
function searchTickets(query) {
clearTimeout(ticketSearchTimeout);
ticketSearchTimeout = setTimeout(() => {
fetch(‘/wp-admin/admin-ajax.php’, {
method: ‘POST’,
body: new URLSearchParams({
action: ‘search_tickets’,
query: query,
nonce: shahiAssistAjax.nonce
})
})
.then(response => response.json())
.then(data => updateResults(data));
}, 300);
}
`

Pagination Optimization

`php
// Use cursor-based pagination for large datasets
function getticketspaginated($cursor = null, $limit = 20) {
global $wpdb;

$where_clause = $cursor ? $wpdb->prepare(“AND p.ID < %d", $cursor) : ""; $tickets = $wpdb->get_results($wpdb->prepare(“
SELECT p.ID, p.posttitle, p.postdate
FROM {$wpdb->posts} p
WHERE p.post_type = ‘ticket’
AND p.post_status = ‘publish’
{$where_clause}
ORDER BY p.ID DESC
LIMIT %d
“, $limit));

$next_cursor = end($tickets)->ID ?? null;

return [
‘tickets’ => $tickets,
‘nextcursor’ => $nextcursor
];
}
`

Image Optimization

`php
// Generate responsive images for attachments
addfilter(‘wpgenerateattachmentmetadata’, function($metadata, $attachment_id) {
if (getpostmimetype($attachmentid) === ‘image/jpeg’) {
// Generate additional sizes
$metadata[‘sizes’][‘shahi-assist-thumb’] = [
‘file’ => ‘thumb.jpg’,
‘width’ => 150,
‘height’ => 150,
‘mime-type’ => ‘image/jpeg’
];
}
return $metadata;
}, 10, 2);
`

Background Processing

WP-Cron for Heavy Tasks

`php
// Schedule email digest
addaction(‘shahiassistdailydigest’, ‘senddailydigest’);

function scheduledailydigest() {
if (!wpnextscheduled(‘shahiassistdaily_digest’)) {
wpscheduleevent(strtotime(‘tomorrow 9am’), ‘daily’, ‘shahiassistdaily_digest’);
}
}
registeractivationhook(FILE, ‘scheduledailydigest’);

function senddailydigest() {
// Generate and send digest email
$stats = getticketstats();
$content = generatedigestcontent($stats);
wpmail(getoption(‘admin_email’), ‘Daily Support Digest’, $content);
}
`

Action Scheduler for Complex Tasks

`php
// Use Action Scheduler plugin for reliable background processing
add_action(‘init’, function() {
if (class_exists(‘ActionScheduler’)) {
// Schedule complex task
asschedulerecurring_action(
time(),
HOURINSECONDS,
‘shahiassisthourly_maintenance’,
[],
‘shahi-assist’
);
}
});

addaction(‘shahiassisthourlymaintenance’, function() {
// Perform maintenance tasks
cleanoldlogs();
updatesearchindexes();
sendpendingnotifications();
});
`

Search Optimization

Full-Text Search Indexes

`php
// Create search index table
function createsearchindex_table() {
global $wpdb;

$tablename = $wpdb->prefix . ‘shahiassistsearchindex’;

$wpdb->query(“
CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
object_id bigint(20) unsigned NOT NULL,
object_type varchar(50) NOT NULL,
search_content longtext NOT NULL,
FULLTEXT KEY searchcontent (searchcontent),
PRIMARY KEY (id),
KEY objectid (objectid),
KEY objecttype (objecttype)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
“);
}

// Index content when posts are saved
addaction(‘savepost’, function($post_id) {
if (!inarray(getposttype($postid), [‘ticket’, ‘kb_article’])) {
return;
}

global $wpdb;
$tablename = $wpdb->prefix . ‘shahiassistsearchindex’;

$content = getpostfield(‘postcontent’, $postid) . ‘ ‘ .
getpostfield(‘posttitle’, $postid);

$wpdb->replace($table_name, [
‘objectid’ => $postid,
‘objecttype’ => getposttype($postid),
‘search_content’ => $content
]);
});

// Perform optimized search
function optimized_search($query, $type = ‘all’) {
global $wpdb;
$tablename = $wpdb->prefix . ‘shahiassistsearchindex’;

$typeclause = $type !== ‘all’ ? $wpdb->prepare(“AND objecttype = %s”, $type) : “”;

return $wpdb->get_results($wpdb->prepare(“
SELECT objectid, objecttype,
MATCH(search_content) AGAINST(%s IN NATURAL LANGUAGE MODE) as relevance
FROM $table_name
WHERE MATCH(search_content) AGAINST(%s IN NATURAL LANGUAGE MODE)
{$type_clause}
ORDER BY relevance DESC
LIMIT 50
“, $query, $query));
}
`

Monitoring and Profiling

Performance Monitoring

`php
// Log slow queries
add_filter(‘query’, function($query) {
$start_time = microtime(true);

// Execute query here or let WordPress handle it

$end_time = microtime(true);
$executiontime = $endtime – $start_time;

if ($execution_time > 0.1) { // Log queries taking more than 100ms
errorlog(“Slow query ({$executiontime}s): {$query}”);
}

return $query;
});
`

Memory Usage Tracking

`php
function logmemoryusage($label = ”) {
$memory = memorygetpeak_usage(true) / 1024 / 1024;
error_log(“Memory usage {$label}: {$memory}MB”);
}

// Use throughout code
logmemoryusage(‘before heavy operation’);
// … heavy operation
logmemoryusage(‘after heavy operation’);
`

Query Monitor Integration

`php
add_action(‘qm/collectors’, function($collectors) {
require_once ‘class-shahi-assist-collector.php’;
$collectors[‘shahi-assist’] = new ShahiAssistQueryMonitorCollector();
return $collectors;
});

add_action(‘qm/outputter/html’, function($output) {
require_once ‘class-shahi-assist-outputter.php’;
$output[‘shahi-assist’] = new ShahiAssistQueryMonitorOutputter($output[‘shahi-assist’]);
return $output;
});
`

CDN and External Resources

Static Asset CDN

`php
// Serve assets from CDN
define(‘SHAHIASSISTCDN_URL’, ‘https://cdn.example.com/wp-content/plugins/shahi-assist/’);

function getasseturl($relative_path) {
if (defined(‘SHAHIASSISTCDN_URL’)) {
return SHAHIASSISTCDNURL . $relativepath;
}
return plugindirurl(FILE) . $relative_path;
}

wpenqueuestyle(‘shahi-assist’, getasseturl(‘assets/css/style.css’));
`

Database Read Replicas

`php
// Use read replica for SELECT queries
add_filter(‘query’, function($query) {
global $wpdb;

if (stripos($query, ‘SELECT’) === 0 && defined(‘DBREADHOST’)) {
$wpdb->add_database([
‘host’ => DBREADHOST,
‘user’ => DB_USER,
‘password’ => DB_PASSWORD,
‘name’ => DB_NAME,
‘read’ => 1,
]);
}

return $query;
});
`

Scaling Considerations

Horizontal Scaling

    1. Use load balancers for multiple web servers
    2. Implement session sharing (Redis, database)
    3. Use shared storage for file uploads
    4. Database Sharding

      `php
      // Route queries based on ticket ID
      function getshardforticket($ticketid) {
      $shard_count = 4;
      return $ticketid % $shardcount;
      }

      function executeonshard($shard_id, $query) {
      global $wpdb;

      // Switch to appropriate database connection
      // Implementation depends on your sharding setup
      }
      `

      Caching Layers

    5. Browser caching with proper headers
    6. CDN caching for static assets
    7. Application-level caching (Redis, Memcached)
    8. Database query caching
    9. Maintenance Tasks

      Automated Cleanup

      `php
      // Daily cleanup cron job
      addaction(‘shahiassistdailycleanup’, function() {
      // Clean old transients
      global $wpdb;
      $wpdb->query(“DELETE FROM {$wpdb->options} WHERE optionname LIKE ‘transientshahiassist%’ AND optionvalue < NOW() - INTERVAL 1 DAY"); // Clean old logs $logfiles = glob(WPCONTENT_DIR . ‘/uploads/shahi-assist/logs/*.log’);
      foreach ($log_files as $file) {
      if (filemtime($file) < strtotime('-30 days')) { unlink($file); } } // Optimize tables $wpdb->query(“OPTIMIZE TABLE {$wpdb->posts}, {$wpdb->postmeta}”);
      });
      `

      Performance Audits

      `php
      function runperformanceaudit() {
      $audit = [
      ‘querycount’ => getnum_queries(),
      ‘memoryusage’ => memorygetpeakusage(true) / 1024 / 1024,
      ‘loadtime’ => timerstop(0, 3),
      ‘cachehitratio’ => getcachehit_ratio(),
      ];

      // Log or display audit results
      errorlog(‘Performance Audit: ‘ . jsonencode($audit));

      return $audit;
      }
      `

      Resources

    10. WordPress Performance
    11. Database Optimization
    12. Caching Best Practices
    13. Share this article

Was this article helpful?

Help us improve our documentation

Still need help?

Our support team is ready to assist you with personalized guidance for your workspace.

Submit a support ticket