Optimisation - mymagic/open_hub GitHub Wiki

Enable Caching

Make sure CACHE=true && DB_SCHEMA_CACHE_DURATION is set to an integer number like 60 in proctected/.env.

Use this as guideline to implement cache in you code:

Please take not the cacheId is universal. Hence follow a strict naming convention to prevent collision is essential

Increase the version number v2 to v3 for example when you change sql or logic to generate the result

$useCache = Yii::app()->params['cache'];
$cacheId = sprintf('%s::%s-%s', 'ClassName', 'functionName', sha1(json_encode(array('v2', 'param1', 'param2'))));
$result = Yii::app()->cache->get($cacheId);
if ($result === false || $useCache === false) {
    $result = Yii::app()->db->createCommand("sql...")->queryScalar();

    // cache for 5min
    Yii::app()->cache->set($cacheId, $result, 300);
}

Profiling

Enable profiling will make all none html page output fail, including json. Use $this->outputJsonRaw(array('key'=>'value')) to output your json safely, or include $this->layout = false; at the top in your action function.

SET ENABLE_PROFILE_LOG=true in proctected/.env to display profile.

To measure your code using profiling:

// starting
if (Yii::app()->params['enableProfileLog']) {
	Yii::beginProfile('anyIdHere');
}

// your code to measure execution speed

// ending
if (Yii::app()->params['enableProfileLog']) {
	Yii::endProfile('anyIdHere');
}

Pre generate Thumbnail

Thumbnail can either be pre-generated or live-generated. Use pre-generated by setting THUMB_MODE="pre" in proctected/.env where all thumbnails will automatically generated and store the moment images are uploaded.

Why Slow

Meta Structure and Item

Although convenience for developers, meta data itself is a join table relationships and will greatly decrease the system performance as the number of meta structure to a core model increased. More complex JOIN query and individual query to each of the meta_item table too.

Caching solve this problem. All meta are cache for a day, and these caches are remove when there's changes to the value by override model afterSave().

Model Relation

Model like organization loads all related necessary objects in afterFind as below:

protected function afterFind()
{
    if (empty($this->image_logo)) {
        $this->image_logo = $this->getDefaultImageLogo();
    }
    foreach ($this->impacts as $impact) {
        $this->inputImpacts[] = $impact->id;
    }
    foreach ($this->sdgs as $sdg) {
        $this->inputSdgs[] = $sdg->id;
    }
    foreach ($this->personas as $persona) {
        $this->inputPersonas[] = $persona->id;
    }
    foreach ($this->industries as $industry) {
        $this->inputIndustries[] = $industry->id;
    }
    foreach ($this->classifications as $classification) {
        $this->inputClassifications[] = $classification->id;
    }

    parent::afterFind();
}

In situation where list of organizations loaded, say 30 when viewing Manage Organization page in backend, each has x5 relations (impacts, sgds, personas, industries, classifications) and that would be equal to 150 queries. Multiply these by each of organization's META data (say 4 each), the SQL statements can easily go up to 600 queries.

Modules

Having too many custom modules also contributed to the pro-long load time of the entire system. In this case, you may move some of the modules out from the file system and only keep those needed one.

Troubleshoot

You may disable all custom modules to troubleshoot why slow. Make sure MODULE_DISABLE_NONE_CORE=true in proctected/.env.