Shop Optimieren

Hallo zusammen

[B]1. Google Page Speed[/B]

Gegenwärtig arbeite ich an der Optimierung (Geschwindigkeit) unseres Shops.
Dabei bin ich über die Google-Messung PageSpeed Insights gestoßen. Beim ersten Lauf waren es fürchterliche 45 Punkte von 100. Das konnte ich nicht auf mir sitzen lassen.

Nach diversen Forenbeiträgen bin ich zu der Seite http://www.tfonfara.de/javascript-und-css-mit-gzip-komprimieren.xhtml"gelangt. Der Code zur Komprimierung wurde eingearbeitet und die Größeren Dateien komprimiert.

Inzwischen bin ich bei 74 Punkten angekommen:
https://developers.google.com/speed/pagespeed/insights#url=http_3A_2F_2Fwww.sonnenblumen-werkstatt.de_2Fshop_2F&mobile=false

Ist noch immer nicht der Hammer, da einiges laut Google optimiert werden könnte. Zum Einen wäre es noch hilfreich, wenn für manche Dateien ein Ablaufdatum angegeben wird. Dazu hat mir das Forum nicht weiterhelfen können.

[B]
EDIT[/B]
Inzwischen habe ich das Whitepaper von Oxid gefunden (http://docu.oxid-esales.com/devdocuments/whitepaper-performance-optimierung.pdf) und hier noch den Browser-Cache optimiert (mod_expires und mod_headers). Jetzt komme ich auf 79 Google-Punkte. Als neuer kritischer Punkt tauscht jetzt hier “Cache-Validierer angeben” auf:
https://developers.google.com/speed/pagespeed/insights#url=http_3A_2F_2Fwww.sonnenblumen-werkstatt.de_2Fshop_2F&mobile=false&rule=SpecifyACacheValidator
[I]Wie gebe ich das an?[/I]

[I]Kann mir einer von Euch Entwicklern weiterhelfen?[/I]

[B]2. Ladezeiten[/B]

Mit Firebug kam ich bis vor kurzem immer auf Zeiten zwischen 5 und 6 Sekunden.

Habe jetzt den Laden der Varianten in der Artikelvorschau deaktiviert und komme beim Laden der Webseite jetzt immer auf Zeiten zwischen 2,5 und 3 Sekunden.

[I]Könnte mir hier jemand Tipps geben wie die Zeiten noch weiter reduziert werden?[/I]

[B]3. Sammelthread[/B]

Gibt es einen Sammelthread mit Tipps und Tricks um Oxid zu optimieren hinsichtlich Geschwindigkeit? Habe überhaupt nichts gescheites hier im Forum gefunden. (zumindestens für so einen Anfänger wie mich)

Grüße
Christoph

den kennst Du?
http://forum.oxid-esales.com/showthread.php?t=11776

Hallo Ray

Yep, den kenne ich auch.
Offen ist

  1. Cache Validierer
  2. Ladezeiten (hab den eAccelerator noch eingeschaltet)

Danke

Gruß
Christoph

Ach ja, nicht zu vergessen auch noch der Link zum Shop:
www.sonnenblumen-werkstatt.de

Vieles was ich hier zu xt:Commerce geschrieben habe kann man auch problemlos auf OXID anwenden:
http://50north.de/category/its-all-about-speed/

Cache Validierer ist eine Einstellungsoption deines Webservers, also entweder einen ETag oder last-modified Header senden.

Hallo Christoph,
OXID Demo Shop hat ohne Optimierung bei PageSpeed 87 Punkte.

Wie kommst Du auf 45 Punkten?

Grüße

Hallo zusammen,

@msslovi0

danke für deinen Tipp.
Google empfiehlt zwar den Cache Validierer, allerdings bringt mir der nichts.
Egal ob mit oder ohne ETag, ich komme immer auch 77 Punkte. Die Ladezeiten sind lauf Firebug auch etwas länger mit ETag als ohne. Also wieder rausgekommen.

@Markus

Keine Ahnung wie ich auf die 45 gekommen bin. War halt so. Jetzt bin ich immerhin bei 77 Punkte. Geschwindigkeit ist auch schneller geworden und mach auf mich den Eindruck eines doch schon flüssig ablaufenden Shops.

Aber sicherlich könnt Ihr Experten mir hier noch ein paar Tipps geben.
Wie schon gesagt, die Standardsachen vom Whitepaper sind schon eingearbeitet.

Grüße
Christoph

[B]Lösche superfish JS Dateien [/B](sind 3 Stück) aus dem base.tpl, Du hast doch unseren [B]CSS3 Menu[/B] im Einsatz die benötigst Du nämlich nicht mehr.

Lade alle css und js Dateien noch einmal als gzip hoch, beispiel: [B]oxid.css.gzip[/B] (Voraussetzung: PDF Anleitung abgearbeitet).

Denke an [B]CSS Sprites[/B] um abfragen zu Reduzieren, in unseren [B]ThemeStyler[/B]ist eine CSS Sprite Funktion eingebaut.

Optimiere deine Grafiken (Header 210 KB, Photoshop 85% anstatt 100%, gleicher Qualität).

Ohne große mühe und in ca.5 Minuten läuft OXID Azure Template mit 1000 Produkten bei Google PageSpeed über [B]96 Punkten[/B].

Wegen der Einstellungen auf dem Server (my.cnf, php.ini und apache2.conf) habe ich Dir PM geschrieben.

Grüße

Hallo Markus,

Superfish ist deaktiviert, danke!
Die Komprimierung ist schon länger eingeschaltet. Liegt alles über 5kB als gzip vor. Bringt es unter 5kB auch was?

Habe erst jetzt bemerkt, dass die Subdomain der Pictures nicht funktioniert hat, da im Whitepaper die http-Adresse in “” angegeben ist, allerdings ’ ’ richtig wäre. Jetzt geht es echt flott.

Allerdings haben meine ganzen Bilder jetzt wieder kein Ablaufdatum, da die jetzt von der Subdomain kommen. muss ich in den Ordner out/pictures noch eine .htaccess kopieren und den Ablauf der bilder festlegen?

Wäre super, wenn du mir hier noch einen tipp geben könntest.

PS: Ich bin schon froh wenn der PageSpeed über 80 kommen wird.

btw:
Ach ja, noch was: Piwik liegt bei mir im gleichen Webspace und braucht immer ewig zum laden. Im Durchschnitt wird Piwik mit einer Sekunde Verzögerung vor dem letzten Transfer des Shop geladen und braucht dann auch noch ewig…

Du brauchst noch einen .htaccess Datei in Subdomain für die Bilder. So etwa konnte das .htaccess Datei in Subdomain aussehen:


<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month 1 days"
ExpiresByType text/html "access plus 1 month 1 days"
ExpiresByType image/gif "access plus 1 month 1 days"
ExpiresByType image/jpeg "access plus 1 month 1 days"
ExpiresByType image/png "access plus 1 month 1 days"
ExpiresByType text/css "access plus 1 month 1 days"
ExpiresByType text/javascript "access plus 1 month 1 week"
ExpiresByType application/x-javascript "access plus 1 month 1 days"
ExpiresByType text/xml "access plus 1 seconds"
</IfModule>

<IfModule mod_headers.c>
<FilesMatch "\.(gif|png|jpg|jpeg|pdf|ico)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
</IfModule>


Ja, YSlow meckert bei ETags, weil die, wenn du deinen Webauftritt auf mehr als einem Server betreibst, nur richtig konfiguriert ihren Nutzen ausspielen können. Von daher am besten wieder deaktivieren. Mit dem Code von Markus solltest du eigentlich sowohl Leverage browser caching als auch den Cache Validator in den Griff bekommen (ersteres durch die Expires, wobei ich die sogar noch länger setzen würde, letzteres durch den Cache-Control-Header).

Komprimiert werden sollte grundsätzlich alles, es ist aber unnötig, die Dateien bereits gezippt hochzuladen, das lässt sich auch über den Apache erledigen (dann muss man da auch nichts :

<IfModule mod_deflate.c>

# Force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/
<IfModule mod_setenvif.c>
  <IfModule mod_headers.c>
    SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
    RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
  </IfModule>
</IfModule>

# HTML, TXT, CSS, JavaScript, JSON, XML, HTC:
<IfModule filter_module>
  FilterDeclare   COMPRESS
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/html
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/css
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/plain
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/xml
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/x-component
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/javascript
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/json
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/xml
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/xhtml+xml
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/rss+xml
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/atom+xml
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/vnd.ms-fontobject
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $image/svg+xml
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/x-font-ttf
  FilterProvider  COMPRESS  DEFLATE resp=Content-Type $font/opentype
  FilterChain     COMPRESS
  FilterProtocol  COMPRESS  DEFLATE change=yes;byteranges=no
</IfModule>

<IfModule !mod_filter.c>
  # Legacy versions of Apache
  AddOutputFilterByType DEFLATE text/html text/plain text/css application/json
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE text/xml application/xml text/x-component
  AddOutputFilterByType DEFLATE application/xhtml+xml application/rss+xml application/atom+xml
  AddOutputFilterByType DEFLATE image/svg+xml application/vnd.ms-fontobject application/x-font-ttf font/opentype
</IfModule>
</IfModule>

Was dann noch offen ist sind die vielen einzelnen CSS- und Javascript-Dateien, die müsste man alle zusammenfassen. Das ist leider so ne OXID-Krankheit.

Hoi,

[QUOTE=msslovi0;113488]Was dann noch offen ist sind die vielen einzelnen CSS- und Javascript-Dateien, die müsste man alle zusammenfassen. Das ist leider so ne OXID-Krankheit.[/QUOTE]

Wurde das nicht vor ein paar Versionen zusammengefasst? Ansonsten wäre es durchaus einen Bug-Eintrag wert.

Gruß

Ich nehme mal an, der Demo-Shop ist auf der aktuellen Release-Version. Und selbst da ist es nach wie vor nicht so.

[QUOTE=Marco Steinhaeuser;113495]
Wurde das nicht vor ein paar Versionen zusammengefasst? [/QUOTE]

irgendwann in der 4.5 wurde da mal was zusammengefasst, aber ich meine, kurz danach wieder getrennt

Hallo zusammen,

ich melde mich mal wieder weil ich nicht weiterkomme.

Zuerst mal kurz der aktuelle Stand:

Es wurde eine weitere subdomain angelegt, welche auch auf den Ordner “out/pictures” zeigt. Diese Subdomain wird nur verwendet, wenn Inhalte manuell in Oxid eingebunden werden (z.B. Hintergrund oder über CMS-Seiten). Dies funktioniert auch super.

Inzwischen war ich auch mal kurzzeitig bei 79 Punkten beim Google PageSpeed. Die 80 schaffe ich sicherlich noch. (CSS-Sprites ist der nächste Punkt auf meiner Liste).

Aber bevor ich die 80 Punkte angehe bitte ich euch um eine kurze Hilfestellung:
Nachdem ich einen alternativen Bilderpfad angegeben habe ($this->sAltImageDir = ‘http://pictures.sonnenblumen-werkstatt.de’;), wurde mir die Artikelbilder nicht mehr angezeigt. Genauer: Die Bilder wurden nicht mehr in ihren unterschiedlichen Größen generiert.

Dies habe ich auch in folgendem Thread nachgelesen:
http://forum.oxid-esales.com/showthread.php?t=12308&page=3

Habe den alternativen Pfad wieder entfernt (temporäre Problemlösung).

So wie ich das in dem letzten Beitrag gelesen habe, müsste ich ja nur in die .htaccess im Ordner out/pictures den folgenden Code einfügen:

RewriteCond %{REQUEST_URI} (\/out\/pictures\/)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (\.jpg|\.gif|\.png)$ core/utils/getimg.php

Problem ist, dass dies nicht funktioniert, da die subdomain (meines erachtens) gar keinen Zugriff auf den Ordner core bekommen könnte. Müsste außerdem ich noch eine RewriteBase oder RewriteEngine On angeben?

Versteh das nicht so ganz.

So, ich hab mir jetzt dazu noch ein paar Gedanken gemacht.

Erstmal die Stellen wo der alternative Bilderpfad vom Core verwendet wird:

views/oxviewconfig.php


  /**
     * Checks if alternative image server is configured.
     *
     * @return bool
     */
    public function isAltImageServerConfigured()
    {
        $oConfig = $this->getConfig();

        return $oConfig->getConfigParam('sAltImageUrl') || $oConfig->getConfigParam('sSSLAltImageUrl') ||
               $oConfig->getConfigParam('sAltImageDir') || $oConfig->getConfigParam('sSSLAltImageDir');
    }

core/oxutilspic.php

   /**
     * Removes picture file from disk.
     *
     * @param string $sPicName        name of picture
     * @param string $sAbsDynImageDir the absolute image diectory, where to delete the given image ($myConfig->getPictureDir(false))
     *
     * @return null
     */
    protected function _deletePicture( $sPicName, $sAbsDynImageDir )
    {
        $blDeleted = false;
        $myConfig  = $this->getConfig();

        if ( !$myConfig->isDemoShop() && ( strpos( $sPicName, 'nopic.jpg' ) === false ||
             strpos( $sPicName, 'nopic_ico.jpg' ) === false ) ) {

            $sFile = "$sAbsDynImageDir/$sPicName";

            if ( file_exists( $sFile ) && is_file( $sFile ) ) {
                $blDeleted = unlink( $sFile );
            }

            if ( !$myConfig->getConfigParam( 'sAltImageUrl' ) ) {
                // deleting various size generated images
                $sGenPath = str_replace( '/master/', '/generated/', $sAbsDynImageDir );
                foreach ( glob( "{$sGenPath}*/{$sPicName}" ) as $sFile ) {
                    $blDeleted = unlink( $sFile );
                }
            }
        }
        return $blDeleted;
    }

core/oxpicturehandler.php

   /**
     * Returns alternative image url
     *
     * @param string $sFilePath path to file
     * @param string $sFile     filename in pictures dir
     * @param bool   $blSSL     is ssl ?
     *
     * @return string
     */
    public function getAltImageUrl($sFilePath, $sFile, $blSSL = null)
    {
        $oConfig = $this->getConfig();

        $sAltUrl = $oConfig->getConfigParam('sAltImageUrl');
        if ( !$sAltUrl ) {
            $sAltUrl = $oConfig->getConfigParam('sAltImageDir');
        }

        if ( $sAltUrl ) {
            if ( (is_null($blSSL) && $oConfig->isSsl()) || $blSSL) {

                $sSslAltUrl = $oConfig->getConfigParam('sSSLAltImageUrl');
                if ( !$sSslAltUrl ) {
                    $sSslAltUrl = $oConfig->getConfigParam('sSSLAltImageDir');
                }

                if ( $sSslAltUrl ) {
                    $sAltUrl = $sSslAltUrl;
                }
            }

            if ( !is_null( $sFile ) ) {
                $sAltUrl .= '/'.$sFilePath.$sFile;
            }
        }

        return $sAltUrl;
    }

Der erste Code aus der oxviewconfig ist eigentlich nur dazu da im Backend dem Admin einen Hinweis zu geben, dass ein alternativer Bilderpfad angegeben wurde. Für die Ausgabe aber irrelevant.

Der zweite Code aus der oxviewconfig.php ist nur dann interessant, wenn eine alternative Bilder-URL ($sAltImageURL) angegeben wird. Ich möchte aber nur einen alternativen Ordner ($sAltImageDir) angeben.

Der dritte Code ist der eigentlich interessante, da dieser ja erst den Pfad zum Bild anzeigt. $sAltUrl wird erst belegt mit dem Pfad aus der config.ini.php und dann mit dem individuellen Bilderpfad.

Soooo, meine Idee ist jetzt:

  1. Bilder-Subdomain auf das Stammverzeichnis zeigen lassen
  2. oxpicturehandler.php so anpassen, dass unten steht:
            if ( !is_null( $sFile ) ) {
                $sAltUrl .= '/out/pictures'.$sFilePath.$sFile;
            }

Auf meinem Demoshop funktioniert es ausgezeichnet. Das Bildermanagement von Oxid wird beibehalten. Des Weiteren werden auch die Bilder generiert wenn diese beim ersten Mal geladen werden. Das Laden der Bilder ist auch beschleunigt.

Bevor ich es jetzt in dem Live-Shop einspiele wollte ich allerdings erst mal Eure Rückmeldung abwarten.

Was haltet Ihr davon?

Also die oben genannte Lösungsvariante habe ich jetzt eingebunden. Die oxpicturehandler.php wurde direkt geändert (war zu faul für ein Modul).

Nebst anderer kleiner Änderungen bin ich jetzt auf einen Score-Wert von 82 gekommen, was für mich ausreichend ist.

Die Ladezeiten sind doch schon akzeptabel, zwar nicht super schnell, aber auch nicht langsam.

Vielen Dank an alle Helfer, vor allem Markus.

Hi Leute, folgender Code funktioniert bei mir irgendwie nicht. Ich nutze OXID 4.7.7, ich habe all diese Dinge in die .htaccess im Hauptordner reingeschrieben:

[QUOTE=markus26;113483]Du brauchst noch einen .htaccess Datei in Subdomain für die Bilder. So etwa konnte das .htaccess Datei in Subdomain aussehen:


<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month 1 days"
ExpiresByType text/html "access plus 1 month 1 days"
ExpiresByType image/gif "access plus 1 month 1 days"
ExpiresByType image/jpeg "access plus 1 month 1 days"
ExpiresByType image/png "access plus 1 month 1 days"
ExpiresByType text/css "access plus 1 month 1 days"
ExpiresByType text/javascript "access plus 1 month 1 week"
ExpiresByType application/x-javascript "access plus 1 month 1 days"
ExpiresByType text/xml "access plus 1 seconds"
</IfModule>

<IfModule mod_headers.c>
<FilesMatch "\.(gif|png|jpg|jpeg|pdf|ico)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
</IfModule>


[/QUOTE]

Egal ob ich es vor


Options -Indexes
DirectoryIndex index.php index.html

oder danach schreibe, ich erhalte nach wie vor von PageSpeed die Meldung: “Cache-Validierer angeben”. Die meisten Dateien befinden sich unter
http://url.de/out/azure/img/
http://url.de/out/azure/src/bg/

Mit folgendem Code (stammt von Oxid und z.B. am Ende der .htaccess angehängt) gibt es keine Probleme in Oxid Version 4.7.4:


# Following customized:
 
<IfModule mod_expires.c> 
ExpiresActive On 
ExpiresDefault "access plus 1 seconds" 
ExpiresByType image/x-icon "access plus 604800 seconds" 
ExpiresByType image/jpeg "access plus 604800 seconds" 
ExpiresByType image/png "access plus 604800 seconds" 
ExpiresByType image/gif "access plus 604800 seconds"
ExpiresByType image/ico "access plus 604800 seconds" 
ExpiresByType application/x-shockwave-flash "access plus 432000 seconds" 
ExpiresByType text/css "access plus 432000 seconds" 
ExpiresByType text/javascript "access plus 432000 seconds" 
ExpiresByType application/x-javascript "access plus 432000 seconds" 
ExpiresByType text/html "access plus 600 seconds" 
ExpiresByType application/xhtml+xml "access plus 600 seconds" 
</IfModule>
 
# File compression during transfer to browser with module deflate.c
<IfModule mod_deflate.c>
<FilesMatch "\.(css|js|x?html?|php)$">
SetOutputFilter DEFLATE
</FilesMatch>
AddOutputFilterByType DEFLATE application/javascript application/x-javascript
</IfModule>
 
# Apache Modul mod_headers.c
<IfModule mod_headers.c>
<FilesMatch "[\\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$](file://\\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$)">
 Header set Cache-Control "max-age=2592000, public" 
</FilesMatch>
<FilesMatch "[\\.(css)$](file://\\.(css)$)">
 Header set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "[\\.(js)$](file://\\.(js)$)">
 Header set Cache-Control "max-age=216000, private"
</filesMatch> 
<FilesMatch "[\\.(xml|txt)$](file://\\.(xml|txt)$)">
 Header set Cache-Control "max-age=216000, public, must-revalidate" 
</FilesMatch>
<FilesMatch "[\\.(html|htm|php)$](file://\\.(html|htm|php)$)">
 Header set Cache-Control "max-age=1, private, must-revalidate" 
</FilesMatch> Header unset ETag Header unset Last-Modified 
</IfModule> 
FileETag None

PS: Ob das tatsächlich bessere Performance bringt, kann ich auf meinem aktuellen High-End Root-Server nicht bestätigen und einige Experten ebenso. Probiers einfach mal aus und gib Bescheid.

Hast du geprüft, ob die Module überhaupt installiert sind?

httpd2 -M

ist dein Freund.

Warum sollte es nicht? Es sorgt dafür, dass weniger Files bei subsequenten Aufrufen vom Server geholt werden müssen. Das hat mit der Serverleistung erstmal nichts zu tun, entlastet den aber natürlich trotzdem. Und spätestens bei der nächsten Besucherspitze macht es sich positiv bemerkbar.