ProcessWire - Performance: Unterschied zwischen den Versionen

Aus Wikizone
Wechseln zu: Navigation, Suche
Zeile 5: Zeile 5:
 
  https://processwire.com/talk/topic/10548-my-way-of-using-wirecache-and-some-hints-to-make-life-easier-with-it/
 
  https://processwire.com/talk/topic/10548-my-way-of-using-wirecache-and-some-hints-to-make-life-easier-with-it/
  
Example als Hook für die ready.php (ungetestet)
+
Auf die WireCache Klasse kann mit der '''$cache''' variable zugegriffen werden. Die angelegten Caches werden in der PW Datenbank gespeichert. Es gibt diverse Methoden
 +
https://processwire.com/api/ref/wire-cache/
 +
Standard Cachezeit ist 24h
 +
 
 +
''' Beispiel - delayed output variable eines Templates cachen.
 
<syntaxhighlight lang="php">
 
<syntaxhighlight lang="php">
// the next ensures that the following code will only run on front end (otherwise back end would get cached, too which results in problems)
+
$cacheId = 'c_content_'.$page->id;
// make sure to place anything you need in the backend before this line or change it to your needs..
+
$content = $cache->get($cacheId);
if ((strpos($page->url, wire('config')->urls->admin) !== false) || ($page->id && $page->is('parent|has_parent=2'))) return;
+
if(!$content) {
 
+
include("./partials/layout-blocks.inc");
$cacheName = "prefix__$page->id-$page->template-{$user->language->name}";
+
$content = renderLayoutBlocks($page,$additionalHeaderData); // 2nd passed by reference
if ($urlSegment1) $cacheName .= "-$urlSegment1";
+
$cache->save($cacheId, $content);
if ($urlSegment2) $cacheName .= "-$urlSegment2";
 
if ($urlSegment3) $cacheName .= "-$urlSegment3";
 
if ($input->pageNum > 1) $cacheName .= "-page$input->pageNum";
 
 
 
// if already cached exit here printing cached content (only 1 db query)
 
$wire->addHookBefore('Page::render', function() use($cache, $cacheName) {
 
 
 
    $cached = $cache->get($cacheName);
 
    if ($cached) {
 
        exit($cached);
 
    }
 
 
 
});
 
 
 
// not cached so far, continue as usual but save generated content to cache
 
$wire->addHookAfter('Page::render', function($event) use($cache, $cacheName) {
 
 
 
    $cached = $cache->get($cacheName);
 
 
 
    if (!$cached) {
 
        $cache->save($cacheName, $event->return);
 
    }
 
 
 
    unset($cached);
 
 
 
});
 
/* of course not the same as a proper flat file cache like procache but at least saving many database queries
 
make sure to adjust the $cacheName as needed, you can even cache query strings, almost everything you'd like
 
and you could wrap everything in a condition to only run if no incoming post or query strings so form submits keep working
 
example
 
*/
 
 
 
if (!count($input->get) && !count($input->post) && !$config->ajax) {
 
    // cache logic from above
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>

Version vom 13. Februar 2020, 16:52 Uhr

Caching

wireCache

https://processwire.com/blog/posts/processwire-core-updates-2.5.28/#wirecache-upgrades
https://processwire.com/talk/topic/15286-delete-and-generate-new-markup-cache/
https://processwire.com/talk/topic/10548-my-way-of-using-wirecache-and-some-hints-to-make-life-easier-with-it/

Auf die WireCache Klasse kann mit der $cache variable zugegriffen werden. Die angelegten Caches werden in der PW Datenbank gespeichert. Es gibt diverse Methoden

https://processwire.com/api/ref/wire-cache/

Standard Cachezeit ist 24h

Beispiel - delayed output variable eines Templates cachen.

$cacheId = 'c_content_'.$page->id;
$content = $cache->get($cacheId);
if(!$content) {
	include("./partials/layout-blocks.inc");
	$content = renderLayoutBlocks($page,$additionalHeaderData); // 2nd passed by reference
	$cache->save($cacheId, $content);
}

Performante Datenbankabfragen

Mit Modul oder per Hand (pdo) möglich.

https://modules.processwire.com/modules/rock-finder/
https://processwire.com/talk/topic/16346-how-to-transform-page-selectors-into-sql-queries/

my module is a companion module for RockGrid. Those grids always need an array of objects as data source. Using $pages->find() and then foreach() to create such an array is terribly inefficient when dealing with several thousands of pages. That's why I built RockFinder -> it creates an efficient SQL statement for you and it is almost as easy as using regular PW selectors.

The benefit of using SQL is that it is incredibly efficient. The downside is that some pw-related tasks become a headache (like checking for published state, sort order, multilanguage field values, to name just a few). RockFinder takes care of all that.

It returns an array of objects that you can easily pass to a RockGrid or do whatever you want with it.

Performance Testen

Zeit und RAM

// 8000 pages with title and body fields
$pp = $pages('template=basic, parent=1384');
$out = '';
foreach($pp as $p) {
    $t = $p->title . microtime();
    $b = $p->body . mt_rand(0, 1e5);
    $out .= $t . $b;
}
echo strlen($out);
// 18384.08ms, 25.00 MB
 
// 8000 pages with title and body fields
$pp = $pages('template=basic, parent=1384');
$out = '';
foreach($pp as $p) {
    $out .= $p->title . microtime();
    $out .= $p->body . mt_rand(0, 1e5);
}
echo strlen($out);
// 17617.05ms, 25.00MB
 
$out = '';
foreach($pages('template=basic, parent=1384') as $p) {
    $out .= $p->title . microtime();
    $out .= $p->body . mt_rand(0, 1e5);
}
echo strlen($out);
// 17927.9ms, 25.00MB

Performance und Repeater Matrix

https://processwire.com/talk/topic/20156-are-there-hidden-scalabilityperformance-issues-when-making-heavy-use-of-repeater-matrix-or-pagetable-fields/

Backend

  • Repeater Items per AJAX laden
https://processwire.com/blog/posts/more-repeaters-repeater-matrix-and-new-field-rendering/#repeater-upgrades-continued-in-pw-3.0.5

Frontend

  • Können viele Datenbank (PDO) Queries auslösen, da alle Page Objekte geladen werden müssen.

Auswahl aus verschiedenen Repeatern über ein Select, statt einzelnes RepeaterMatrix Feld

Evtl. könnte man ein Auswahlfeld generieren, das dann wiederum einen Contentblock wählt, statt alles in ein RepeaterMatrix Feld zu packen.

  • Layoutblock -> Select Feld
  • Optionen werden geladen.

Alternativ PageTables

https://processwire.com/talk/topic/7459-module-pagetableextended/

Könnte Performancemäßig die bessere Alternative sein. Prüfen und auch mit PageTableExtended verbinden.