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
tov3
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
.