Zwischengespeicherte, von PHP generierte Thumbnails werden langsam geladen


179

Frage Teil A ▉ (100 Kopfgelder, vergeben) Die
Hauptfrage war, wie diese Site schneller geladen werden kann. Zuerst mussten wir diese Wasserfälle lesen. Vielen Dank für Ihre Vorschläge zur Analyse der Wasserfallanzeige. Aus den verschiedenen hier gezeigten Wasserfalldiagrammen geht der Hauptengpass hervor: die von PHP generierten Miniaturansichten. Das von David empfohlene protokolllose Laden von Abfragen von CDN hat mein Kopfgeld erhalten, obwohl meine Website insgesamt nur 3% schneller ist und der Hauptengpass der Website nicht beantwortet wird. Zeit für die Klärung meiner Frage und eine weitere Prämie:

Frage Teil B ▉ (100 Kopfgelder, vergeben)
Der neue Fokus lag nun auf der Lösung des Problems, das die 6-JPG-Bilder hatten und die den größten Teil der Ladeverzögerung verursachen. Diese 6 Bilder sind PHP-Thumbnails, winzig klein und nur 3 ~ 5 kb, aber das Laden relativ sehr langsam. Beachten Sie die " Zeit bis zum ersten Byte " in den verschiedenen Diagrammen. Das Problem blieb ungelöst, aber ein Kopfgeld ging an James, der den von RedBot unterstrichenen Header-Fehler behebte : "Eine bedingte If-Modified-Since-Anforderung gab den vollständigen Inhalt unverändert zurück." .

Frage Teil C ▉ (mein letztes Kopfgeld: 250 Punkte)
Leider blieb die durch die PHP-generierten Bilder verursachte Verzögerung unberührt, nachdem selbst der Header-Fehler von REdbot.org behoben wurde. Was um alles in der Welt denken diese winzigen, mickrigen 3 ~ 5 KB Miniaturansichten? All diese Header-Informationen können eine Rakete zum Mond und zurück schicken. Vorschläge zu diesem Engpass werden sehr geschätzt und als mögliche Antwort behandelt, da ich bereits seit sieben Monaten an diesem Engpassproblem festhalte. Mein Dank im Voraus.

[Einige Hintergrundinformationen auf meiner Website: CSS ist oben. JS unten (Jquery, JQuery UI, gekauftes Menü awm / menu.js Engines, Tabs js Engine, Video swfobject.js) Die schwarzen Linien im zweiten Bild zeigen, was das Laden initiiert. Der wütende Roboter ist mein Haustier "ZAM". Er ist harmlos und oft glücklicher.]


Wasserfall laden: Chronologisch | http://webpagetest.org Geben Sie hier die Bildbeschreibung ein


Parallele Domänen gruppiert | http://webpagetest.org Geben Sie hier die Bildbeschreibung ein


Site-Perf Wasserfall | http://site-perf.com Geben Sie hier die Bildbeschreibung ein


Pingdom Tools Wasserfall | http://tools.pingdom.com

Geben Sie hier die Bildbeschreibung ein


GTmetrix Wasserfall | http://gtmetrix.com

Geben Sie hier die Bildbeschreibung ein



11
Ich denke, die meisten Browser stellen nur 20 Verbindungen gleichzeitig her, so dass nach 20 die erste vor dem nächsten Start beendet werden muss, daher die Verlangsamung nach 20

1
Ich denke, Sie haben vergessen, die erste Instanz Ihrer Domain zu redigieren. Zumindest hast du den Rest von ihnen: D
dreißig Punkte

2
Können Sie einige dieser Bilder nicht zu Sprites kombinieren?
Marcel Korpel

1
@Dagon, beachten Sie, dass HTTP 1.1 RFC ( SHOULD) HTTP 1.1-Clients auffordert, höchstens 2 Verbindungen zu HTTP 1.1-Servern zu verwenden. HTTP 1.0 ist natürlich viel offener.
Sarnold

1
@ Dragon-Browser stellen außerdem nur zwei gleichzeitige Verbindungen zu einer bestimmten Domain her.
Endophage

Antworten:


61

Erstens erfordert die Verwendung dieser mehreren Domänen mehrere DNS-Suchvorgänge. Sie sollten viele dieser Bilder besser zu einem Sprite kombinieren , als die Anforderungen zu verbreiten.

Zweitens sehe ich beim Laden Ihrer Seite den größten Teil der Blockierung (~ 1,25 s) auf all.js. Ich sehe, das beginnt mit (einer alten Version von) jQuery. Sie sollten dies aus dem Google CDN heraus referenzieren, um nicht nur die Ladezeit zu verkürzen , sondern möglicherweise eine HTTP-Anforderung vollständig zu vermeiden .

Unter diesen URLs kann auf die aktuellsten jQuery- und jQuery-UI-Bibliotheken verwiesen werden (siehe diesen Beitrag, wenn Sie interessiert sind, warum ich das weggelassen habe http:):

//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js

//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js

Wenn Sie eines der Standardthemen der jQuery-Benutzeroberfläche verwenden, können Sie auch dessen CSS und Bilder vom Google CDN abrufen .

Mit dem jQuery optimiert Hosting, sollten Sie auch kombinieren awmlib2.jsund tooltiplib.jseine einzige Datei in.

Wenn Sie diese Dinge ansprechen, sollten Sie eine signifikante Verbesserung sehen.


1
Hervorragender Kommentar Dave! Die alte 1.3 JQuery war viel kleiner, also dachte ich, während sie funktioniert, könnte sie schneller sein. Aber ich mag Ihre Empfehlungen: Welche der Google CDN-Links schlagen Sie mir als Jqyuery vor? Kann ich JQ UI Javascript auf die gleiche Weise verwenden? +1 vielen Dank
Sam

2
Ich empfehle auf jeden Fall die Verwendung der neuesten Version von jQuery (derzeit 1.4.4). Beim Minimieren und Komprimieren gibt es nur wenige Byte Unterschied zwischen ihnen. Ich habe die Antwort mit einigen Links zu den neuesten jQuery- und jQuery-UI-Versionen auf dem Google CDN aktualisiert, die ich empfehlen würde.
Dave Ward

1
Guter Tipp mit dem Sprite, der die Anzahl der offenen Verbindungen zum Server reduzieren sollte
JamesHalsall

Derzeit wird an der Reduzierung der offenen Verbindungen gearbeitet (von 40 auf 30 oder so ... der letzte Push ist am schwierigsten, da einige der Bilder den Hintergrund wiederholen und nicht in ein Sprite (oder ???) gehen können
Sam

Aktualisieren der Seitengeschwindigkeit: (96%) YSlow-Note: (90%) ... und dennoch sind die Miniaturansichten so langsam wie nie zuvor!
Sam

17

Ich hatte vor ein paar Tagen ein ähnliches Problem und fand es head.js . Es ist ein Javascript-Plugin, mit dem Sie alle JS-Dateien parallel laden können. Hoffentlich hilft das.


Unglaublich! Wie kann ich das übersehen haben? +1 Ich werde jetzt diesen testen. Riecht nach einer fruchtbaren Nacht. Danke Schattenbaum!
Sam

1
Darf ich fragen, ob Sie der Schattenbaum von schattenbaum.net sind?
Pekka

12

Ich bin weit entfernt von einem Experten, aber ...

In Bezug auf dieses: "Eine bedingte If-Modified-Since-Anforderung hat den vollständigen Inhalt unverändert zurückgegeben." und meine Kommentare.

Der zum Generieren der Miniaturansichten verwendete Code sollte Folgendes überprüfen:

  1. Gibt es eine zwischengespeicherte Version des Miniaturbilds?
  2. Ist die zwischengespeicherte Version neuer als das Originalbild?

Wenn eine dieser Angaben falsch ist, sollte die Miniaturansicht generiert und zurückgegeben werden, egal was passiert. Wenn beide wahr sind, sollte die folgende Prüfung durchgeführt werden:

  1. Gibt es einen HTTP_IF_MODIFIED_SINCE-Header?
  2. Entspricht die zuletzt geänderte Zeit der zwischengespeicherten Version der HTTP_IF_MODIFIED_SINCE?

Wenn eine dieser Angaben falsch ist, sollte die zwischengespeicherte Miniaturansicht zurückgegeben werden.

Wenn beide zutreffen, sollte ein 304-http-Status zurückgegeben werden. Ich bin nicht sicher, ob es erforderlich ist, aber ich gebe auch persönlich die Header Cache-Control, Expires und Last-Modified zusammen mit dem 304 zurück.

In Bezug auf GZipping wurde mir mitgeteilt, dass keine GZip-Bilder erforderlich sind. Ignorieren Sie daher diesen Teil meines Kommentars.

Bearbeiten: Ich habe Ihre Hinzufügung zu Ihrem Beitrag nicht bemerkt.

session_cache_limiter('public');
header("Content-type: " . $this->_mime);
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 2419200) . " GMT");
// I'm sure Last-Modified should be a static value. not dynamic as you have it here.
header("Last-Modified: " . gmdate("D, d M Y H:i:s",time() - 404800000) . " GMT");

Ich bin mir auch sicher, dass Ihr Code nach dem HTTP_IF_MODIFIED_SINCE-Header suchen und darauf reagieren muss. Nur das Setzen dieser Header und Ihrer .htaccess-Datei liefert nicht das erforderliche Ergebnis.

Ich denke du brauchst so etwas:

$date = 'D, d M Y H:i:s T'; // DATE_RFC850
$modified = filemtime($filename);
$expires = strtotime('1 year'); // 1 Year

header(sprintf('Cache-Control: %s, max-age=%s', 'public', $expires - time()));
header(sprintf('Expires: %s', date($date, $expires)));
header(sprintf('Last-Modified: %s', date($date, $modified)));
header(sprintf('Content-Type: %s', $mime));

if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
    if(strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) === $modified) {
        header('HTTP/1.1 304 Not Modified', true, 304);
        // Should have been an exit not a return. After sending the not modified http
        // code, the script should end and return no content.
        exit();
    }
}
// Render image data

James, du hast die Essenz des Problems nach deiner Bearbeitung in deiner Antwort festgenagelt! Das If Modified SinceProblem scheint jetzt zu funktionieren! Die langen Überschriften / Wartezeiten für die winzigen Daumen sind jedoch noch nicht gelöst ...
Sam

@ James PS REdbot.org sagt, dass Ihr Expires-Header ein falscher Wert ist. Ich denke, es muss GMT sein und nicht MEZ?
Sam

@Sam Entschuldigung, mein Server befindet sich in Großbritannien und generiert automatisch GMT-Daten. Verwenden Sie stattdessen einfach die PHP-Funktion gmdate if date. Dies sollte ein GMT-Datum relativ zu Ihrer Serverzeit ergeben.
James

1
@ Sam, Ihre Wartezeit ist die Ausführungszeit des Skripts. Es dauert entweder lange, bis Sie Ihren Code bis zu dem Punkt durchlaufen haben, an dem Sie Ihre Header gesendet haben, oder Sie beenden ihn nicht, nachdem Sie Ihre Header gesendet haben.
James

@ James, ich verstehe ... Aber abgesehen von diesem PHP-Thumbnail-Generator gibt es eine ganze Reihe anderer gleich langer Skripte, die verschiedene andere Dinge (Übersetzungen, Laden von Menüs usw.) in einem Bruchteil einer Zeit erledigen ... SIE scheint überhaupt kein Engpass zu sein ... lenkt das das Problem dann NUR auf den Thumbnail Generator PHP?
Sam

6

Wow, es ist schwer, Dinge mit diesem Bild zu erklären. Aber hier einige Versuche:

  • Die Dateien 33-36 werden so spät geladen, weil sie dynamisch in den SWF geladen werden und der SWF (25) zuerst vollständig geladen wird, bevor zusätzlicher Inhalt geladen wird
  • Die Dateien 20 und 21 sind möglicherweise (ich weiß nicht, weil ich Ihren Code nicht kenne) Bibliotheken, die von all.js (11) geladen werden, aber bis 11 ausgeführt wird, wartet sie auf die gesamte Seite (und die Assets). zu laden (Sie sollten das in domready ändern)
  • Die Dateien 22-32 werden von diesen beiden Bibliotheken wieder geladen, nachdem diese vollständig geladen wurden

Interessanter Punkt. Ich vermute, es gibt nichts um die swf ... Wie kann ich ändern, was zu domready? Ich habe eine Ahnung, was du meinst. Es geht darum, wann das Javascript fertig ist und auf dem Dokument dies oder jenes sagt? Sollte dieses Dokument bereits durch dom.ready ersetzt werden?
Sam

@Sam Wenn Sie clientseitiges Caching verwenden (und das sollten Sie auch sein), können Sie die vom SWF verwendeten Ressourcen in js oder versteckte Divs auf Ihrer Seite laden, sodass sie sich bereits auf dem Client befinden, wenn der SWF sie anfordert.
Endophage

4

Nur eine einfache Vermutung, da diese Art der Analyse viele A / B-Tests erfordert: Ihre .ch-Domain scheint schwer zu erreichen zu sein (lange, grüne Bänder, bevor das erste Byte eintrifft).

Dies würde bedeuten, dass entweder die .ch-Website schlecht gehostet wird oder dass Ihr ISP keinen guten Weg zu ihnen hat.

Angesichts der Diagramme könnte dies einen großen Leistungseinbruch erklären.

Nebenbei bemerkt, es gibt dieses coole Tool Cuzillion , mit dem Sie die Dinge in Abhängigkeit von Ihrer Reihenfolge beim Laden der Ressourcen sortieren können.


4

Führen Sie Y! Slow- und Page Speed-Tests auf Ihrer Site / Seite durch und befolgen Sie die Richtlinien, um mögliche Leistungsengpässe zu beheben. Sie sollten enorme Leistungssteigerungen erzielen, wenn Sie in Y! Slow oder Page Speed ​​eine höhere Punktzahl erzielen.

Diese Tests zeigen Ihnen, was falsch ist und was Sie ändern müssen.


Vielen Dank! Die Ergebnisse sind: 92 bei Seitengeschwindigkeit und 93 bei Ylow. Was fehlt, sind: KEEP ALIVE = off und kein CDN verwenden.
Sam

UPDATE: 96 bzw. 90 derzeit
Sam

4

Ihr PHP-Skript generiert also die Miniaturansichten bei jedem Laden der Seite? Wenn sich die Bilder, die als Miniaturbilder angezeigt werden, nicht so oft ändern, können Sie dann zunächst einen Cache einrichten, damit sie nicht jedes Mal analysiert werden müssen, wenn die Seite geladen wird. Zweitens verwendet Ihr PHP-Skript so etwas wie imagecopyresampled()das Erstellen der Miniaturansichten? Das ist ein nicht triviales Downsample und das PHP-Skript gibt nichts zurück, bis es fertig ist. Wenn Sie imagecopymerged()stattdessen verwenden, wird die Bildqualität verringert, der Vorgang wird jedoch beschleunigt. Und wie viel reduzieren Sie? Sind diese Miniaturansichten 5% so groß wie das Originalbild oder 50%? Eine größere Größe des Originalbilds führt wahrscheinlich zu einer Verlangsamung, da das PHP-Skript das Originalbild im Speicher ablegen muss, bevor es verkleinert und eine kleinere Miniaturansicht ausgegeben werden kann.


Danke MidnightLightning! Es gibt einen Cache-Ordner, aus dem Miniatur-JPGs erstellt und wiederverwendet werden, obwohl ich das Gefühl habe, dass hier das Problem des Skripts liegt, das ich gekauft habe (und für andere gut zu funktionieren scheint)
Sam

2
Wenn die Miniaturansichten zwischengespeichert werden, stellen Sie sicher, dass das Skript, das sie aus dem Cache abruft, verwendet wird readfile()und nicht file_get_contents()von einem Echo gefolgt wird, das auf die Ausgabe wartet, bis die gesamte Datei in den Speicher des PHP-Skripts verschoben wurde.
MidnightLightning

Besser noch - wenn die Dateien zwischengespeichert sind, generieren Sie den HTML-Code so, dass das zwischengespeicherte Image direkt von der Festplatte abgerufen wird, ohne PHP zu durchlaufen. Das mache ich in meinen Skripten für videodb.net
andig

"Es gibt einen Cache-Ordner, in dem ..." und wie schnell werden sie dereferenziert? Verweist Ihre URL direkt auf eine zwischengespeicherte Datei oder ein PHP-Skript? Leiten Sie readfile () um oder verwenden Sie es? Enthält dasselbe PHP-Skript den Code zur Generierung von Miniaturansichten - oder verschieben Sie das Laden des Großteils des Codes mit include / erquire?
Symcbean

4

Ich habe die URL Ihrer Website gefunden und eine einzelne JPG-Datei von der Homepage überprüft. Während die Ladezeit jetzt angemessen ist (161 ms), wartet sie auf 126 ms, was viel zu viel ist.

Deine zuletzt geänderten Header sind alle auf Sa, 01. Januar 2011, 12:00:00 GMT eingestellt, was zu "rund" aussieht, um das eigentliche Generierungsdatum zu sein ;-)

Da die Cache-Steuerung "public, max-age = 14515200" ist, können beliebige zuletzt geänderte Header nach 168 Tagen Probleme verursachen.

Dies ist jedoch nicht der wahre Grund für Verzögerungen.

Sie müssen überprüfen, was Ihr Miniaturbildgenerator tut, wenn das Miniaturbild bereits vorhanden ist, und was so viel Zeit in Anspruch nehmen kann, um das Bild zu überprüfen und zu liefern.

Sie könnten xdebug installieren um das Skript zu profilieren und , wo die Engpässe liegen.

Vielleicht verwendet das Ganze ein Framework oder stellt für nichts eine Verbindung zu einer Datenbank her. Ich habe auf einigen Servern sehr langsames mysql_connect () gesehen, hauptsächlich, weil sie eine Verbindung über TCP und nicht über Socket herstellten, manchmal mit einigen DNS-Problemen.

Ich verstehe, dass Sie Ihren bezahlten Generator hier nicht posten können, aber ich fürchte, es gibt zu viele mögliche Probleme ...


Vielen Dank für Ihren Detektiv und die richtigen Hinweise Capsule! Das Wichtigste zuerst: Es gibt keine Datenbank. Ihre Ergebnisse sind die gleichen wie meine: Warten Sie 90% der Zeit auf? Verrückte kleine Daumen. Interessante Gedanken zu den zuletzt geänderten Headern, denn laut James Post hier musste ich diese zuletzt geänderten Header auf eine STATISCHE (feste) Zeit setzen, nicht auf eine dynamische / sich ständig ändernde Zeit, die von PHP-GMdate-Generatoren festgelegt wurde. Oder meinst du hier etwas anderes? (Nominiert für Kopfgeld)
Sam

1
Um perfekt zu sein, sollte es das tatsächliche Generierungsdatum widerspiegeln, indem beispielsweise die Dateizeit () der zwischengespeicherten Miniaturansicht abgerufen wird. Es wäre interessant zu testen, auf eine leere PHP-Datei oder eine PHP-Datei zuzugreifen, die nur "test" wiedergibt, und zu sehen, wie viel Wartezeit Sie auf diese haben. Möglicherweise ist der gesamte Server nur langsam und wirkt sich auf jedes einzelne PHP-Skript aus, unabhängig davon, was es tut.
Kapsel

1
Ich sehe auch eine relativ lange Verzögerung bei reinen statischen Dateien (zum Beispiel den mit den Daumen verknüpften Bildern), wie 36 ms. Auf einem der Server, die ich verwalte (was kein Biest ist ... Dual Core mit 2 GB RAL), bekomme ich fast die Hälfte davon, wie 20 ms bei statischen Dateien.
Kapsel

Interessant ... 1. Mit welcher Software / welchem ​​Online-Tool messen Sie? 2. Sind Ihre schnelleren 20-ms-Messungen konsistent (wie viele ± xx%)? Finden Sie, dass Ihre Ergebnisse variieren? In meinem Fall variiert es sehr stark, je nachdem, welches Testwerkzeug ich verwende. Einige sind sehr konsistent ( gtmetrix.com ), andere variieren wirklich ( pingdom.com ) und es ist schwierig, Zeiten in XX ms anzugeben, da sie sich jedes Mal ändern ...
Sam

Ich verwende die Registerkarte NET von Firebug. 20ms ist das schnellste Timing, das ich bekomme. Es variiert zwischen 20 und 28. Natürlich waren die 36 ms, die ich auf Ihrem Server gemessen habe, auch die schnellsten.
Kapsel

4

Wenn es keinen wirklich guten Grund gibt (normalerweise nicht), sollten Ihre Bilder den PHP-Interpreter nicht aufrufen.

Erstellen Sie eine Umschreiberegel für Ihren Webserver, die das Image direkt verwaltet, wenn es im Dateisystem gefunden wird. Wenn dies nicht der Fall ist, leiten Sie zu Ihrem PHP-Skript um, um das Bild zu generieren. Wenn Sie das Bild bearbeiten, ändern Sie den Dateinamen des Bilds, um Benutzer mit einer zwischengespeicherten Version zu zwingen, das neu bearbeitete Bild abzurufen.

Wenn es zumindest nicht funktioniert, hat es jetzt nichts mit der Art und Weise zu tun, wie die Bilder erstellt und überprüft werden.


Vielen Dank, Goran, dies ist jedoch nicht die elegante Lösung, die ich mir wünsche: Ich denke, in meinem Fall ist etwas faul, und normalerweise dauert es nicht so lange, bis ein PHP-Skript weiß, ob es einen 304-Header übergibt oder den backt Bild usw. Trotzdem danke für Ihren Vorschlag, da er das Problem aus einer völlig neuen Perspektive lenkt! Was für sich genommen wertvoll ist +1
Sam

3

Untersuchen Sie die Verwendung von Sitzungsdaten durch PHP. Vielleicht (nur vielleicht) wartet das bildgenerierende PHP-Skript darauf, eine Sperre für die Sitzungsdaten zu erhalten, die durch die noch gerenderte Hauptseite oder andere bildgebende Skripte gesperrt wird. Dies würde alle JavaScript / Browser-Optimierungen fast irrelevant machen, da der Browser auf den Server wartet.

PHP sperrt die Sitzungsdaten für jedes Skript, das ausgeführt wird, vom Beginn der Sitzungsbehandlung bis zum Ende des Skripts oder beim Aufruf von session_write_close (). Dies serialisiert effektiv Dinge. Schauen Sie sich die PHP-Seite zu Sitzungen an, insbesondere die Kommentare wie diese .


Danke für den Vorschlag Ricardo! Es scheint, dass Alix dasselbe vorschlägt wie Sie (richtig?). Was schlagen Sie mir in der Praxis vor, um den Code einzufügen / zu entfernen, dann die Grafiken erneut zu testen und dann zurückzumelden? Sehr geschätzt.
Sam

1
Ja, ich denke schon. Ich schlage vor, dass Sie die Bilderzeugungsskripte so ändern, dass sie nicht von $ _SESSION-Daten oder ähnlichem abhängen (möglicherweise bereits nicht). Verwenden Sie dann session_write_close () so bald wie möglich oder, noch besser, vermeiden Sie die Verwendung von Sessions in diesen Skripten. Überprüfen Sie heraus php.net/manual/en/function.session-write-close.php
Ricardo Pardini

3

Dies ist nur eine wilde Vermutung, da ich Ihren Code nicht angesehen habe, aber ich vermute, dass Sitzungen hier eine Rolle spielen könnten. Folgendes stammt aus dem Eintrag im PHP-Handbuch session_write_close():

Sitzungsdaten werden normalerweise nach dem Beenden Ihres Skripts gespeichert, ohne dass session_write_close () aufgerufen werden muss. Da jedoch Sitzungsdaten gesperrt sind, um gleichzeitige Schreibvorgänge zu verhindern, kann immer nur ein Skript eine Sitzung bearbeiten. Wenn Sie Framesets zusammen mit Sitzungen verwenden, werden die Frames aufgrund dieser Sperre einzeln geladen. Sie können die zum Laden aller Frames erforderliche Zeit verkürzen, indem Sie die Sitzung beenden, sobald alle Änderungen an den Sitzungsvariablen vorgenommen wurden.

Wie gesagt, ich weiß nicht, was Ihr Code tut, aber diese Grafiken scheinen seltsamerweise verdächtig. Ich hatte ein ähnliches Problem, als ich eine mehrteilige Datei-Serving-Funktion codierte, und ich hatte das gleiche Problem. Beim Bereitstellen einer großen Datei konnte ich weder die mehrteilige Funktionalität zum Laufen bringen noch eine andere Seite öffnen, bis der Download abgeschlossen war. Das Anrufen hatsession_write_close() meine beiden Probleme behoben .


Danke Alix für deinen Vorschlag. Eine Frage: Ist die exit();Funktion in ähnlichen Zeilen wie die session_write_close();? Derzeit untersucht der ursprüngliche Verfasser des Codes das Problem, aber es scheint, dass er auch ein bisschen im Dunkeln liegt, da die großzügige Aktualisierung des Codes mit besserer If-Modified-Since-Behandlung die gleichen Verzögerungen zu haben scheint (neuer Wasserfall) Diagramme erzeugten dieselben Diagramme, obwohl echte Worls-Ergebnisse schneller geladen / gefühlt wurden! Es ist ein sehr seltsames Problem ...
Sam

1
@Sam: Ich kann Ihnen derzeit keine Quellen nennen, aber ich glaube, exit () ruft zuerst alle Destruktoren und / oder Funktionen auf, die zum Herunterfahren registriert sind, und erst dann wird die Sitzung geschlossen. Wie auch immer, ich wette, Ihr Problem liegt wahrscheinlich vor Ihrem Aufruf von exit (). Siehe auch: stackoverflow.com/questions/1674314/…
Alix Axel

2

Haben Sie versucht, die von PHP generierten Thumnails durch reguläre Bilder zu ersetzen, um festzustellen, ob es einen Unterschied gibt? Das Problem könnte auftreten - ein Fehler in Ihrem PHP-Code, der bei jedem Serveraufruf zu einer Neuerstellung des Miniaturbilds führt - eine Verzögerung in Ihrem Code (sleep ()?), Die mit einem Uhrproblem verbunden ist - ein Festplattenproblem, das einen sehr schlechten Rennzustand verursacht da alle Thumbnails gleichzeitig geladen / generiert werden.


Etwas, von dem ich irgendwann dachte, ich würde versuchen +1, um meine Gedanken zu lesen und die erste Lösung zu enthüllen, die ich bereits getan habe. Was ich hoffte, war festzustellen, dass normale Bilder auch langsam geladen werden, so dass es sich um die Download-Bandbreitengeschwindigkeit oder etwas physikalisch Begrenzendes handeln könnte, aber ich fand stattdessen, dass normale statische Dump-Bilder (ich habe die generierten Daumen gespeichert und als statisch hochgeladen) diese geladen haben Extrem schnell. Also muss es mit dem tun, was der Thumbnail Generator PHP!
Sam

2

Ich denke, anstatt dieses Thumbnail-Generator-Skript zu verwenden , müssen Sie TinySRC geben für eine schnelle, schnelle und in der Cloud gehostete Thumbnail-Generierung ausprobieren. Es hat eine sehr einfache und benutzerfreundliche API, die Sie wie folgt verwenden können: -

http://i.tinysrc.mobi/ [Höhe] / [Breite] /http://domain.tld/path_to_img.jpg

[width] (optional): - Dies ist eine Breite in Pixel (die die adaptive oder Familiengröße überschreibt). Wenn '-' oder 'x' vorangestellt wird, wird die ermittelte Größe von der festgelegten Größe abgezogen oder auf einen bestimmten Prozentsatz verkleinert.

[Höhe] (optional): - Dies ist eine Höhe in Pixel, wenn auch Breite vorhanden ist. Es überschreibt auch die adaptive Größe oder die Familiengröße und kann mit '-' oder 'x' versehen werden.

Sie können die API-Zusammenfassung hier überprüfen


FAQ

Was kostet mich tinySrc?

Nichts.

Wann kann ich mit tinySrc beginnen?

Jetzt.

Wie zuverlässig ist der Service?

Wir übernehmen keine Garantie für den tinySrc-Service. Es läuft jedoch auf einer großen, verteilten Cloud-Infrastruktur und bietet daher weltweit eine hohe Verfügbarkeit. Es sollte für alle Ihre Bedürfnisse ausreichen.

Wie schnell ist es

tinySrc speichert die Größe von Bildern bis zu 24 Stunden im Speicher und in unserem Datenspeicher zwischen , und es wird nicht jedes Mal Ihr Originalbild abgerufen . Dies macht die Dienste aus Anwendersicht blitzschnell . (Und reduziert Ihre Serverlast als netten Nebeneffekt.)


Viel Glück. Nur ein Vorschlag, da Sie uns den Code nicht zeigen: p


2

Da einige Browser nur 2 Parallel-Downloads pro Domain herunterladen, können Sie keine zusätzlichen Domains hinzufügen, um die Anforderungen über zwei bis drei verschiedene Hostnamen zu verteilen. zB 1.imagecdn.com 2.imagecdn.com


+1 für Ihren Vorschlag: Danke, aber wenn Sie sich meine (zugegebenermaßen: sehr chaotischen Zeichnungen) genauer ansehen, werden Sie sehen, dass einige Gegenstände von ....... es kommen einige von ........ com .......... de ABER, vielleicht reicht das nicht so gut wie Ihr Vorschlag? (Ich sehe, Sie schlagen Subdomains vor, anstatt nur verschiedene Domains.)
Sam

1

Zuallererst müssen Sie If-Modified-SinceAnfragen und dergleichen angemessen behandeln, wie James sagte. Dieser Fehler besagt: "Wenn ich Ihren Server frage, ob dieses Image seit dem letzten Mal geändert wurde, sendet es das gesamte Image anstelle eines einfachen Ja / Nein."

Die Zeit zwischen der Verbindung und dem ersten Byte ist im Allgemeinen die Zeit, die Ihr PHP-Skript zum Ausführen benötigt. Es ist offensichtlich, dass etwas passiert, wenn dieses Skript ausgeführt wird.

  1. Haben Sie darüber nachgedacht, ein Profil zu erstellen? Es kann einige Probleme haben.
  2. In Kombination mit dem oben genannten Problem wird Ihr Skript möglicherweise viel öfter als erforderlich ausgeführt. Im Idealfall sollten nur dann Daumen generiert werden, wenn das Originalbild geändert wurde, und zwischengespeicherte Daumen für jede andere Anforderung gesendet werden. Haben Sie überprüft, ob das Skript die Bilder unnötig generiert (z. B. für jede Anforderung)?

Das Generieren geeigneter Header über die Anwendung ist etwas schwierig und kann vom Server überschrieben werden. Und Sie sind Missbrauch ausgesetzt, da jeder, der Header ohne Cache-Anforderungen sendet, dazu führt, dass Ihr Miniaturbildgenerator kontinuierlich ausgeführt wird (und die Lasten erhöht). Versuchen Sie also nach Möglichkeit, diese generierten Daumen zu speichern, rufen Sie die gespeicherten Bilder direkt von Ihren Seiten auf und verwalten Sie die Überschriften von .htaccess. In diesem Fall benötigen Sie nicht einmal etwas in .htaccessIhrem Server, wenn Ihr Server ordnungsgemäß konfiguriert ist.

Abgesehen von diesen können Sie einige der brillanten Optimierungsideen aus den Leistungsteilen dieser insgesamt netten SO-Frage anwenden, wie Sie Websites richtig machen , z. B. Ihre Ressourcen in kochfreie Subdomains aufteilen usw. Aber auf jeden Fall ein 3k-Bild Das Laden sollte keine Sekunde dauern. Dies ist im Vergleich zu anderen Elementen in den Diagrammen offensichtlich. Sie sollten versuchen, das Problem zu erkennen, bevor Sie es optimieren.


-1: Wenn Sie auf eine bedingte Anfrage mit "Nicht geändert" und ohne überarbeitete Ablaufzeit antworten, wird Ihre Website in 99,9% der Fälle langsamer (BTW, AFAIK, es gibt keine Möglichkeit, Apache dazu zu bringen, überarbeitete Caching-Informationen mit einer 304-Antwort auszugeben).
Symcbean

Und was hat das mit meiner Antwort zu tun?
Halil Özgür

1

Haben Sie versucht, unter NGINX-Webserver mehrere Subdomains speziell für die Bereitstellung statischer Daten wie Bilder und Stylesheets einzurichten ? In diesem Thema war bereits etwas Hilfreiches zu finden .


Vielen Dank! Nach einigen Recherchen scheint es jedoch so zu sein, dass das Einrichten von Subdomains für statische Server-Cookies eine Site nur dann schneller macht, wenn viele Bilder vorhanden sind, was einen zusätzlichen Aufwand bedeutet. In meinem Fall werden die 6 Bilder nicht schneller geladen als der Overhead der Sub- / Extra-Domain. Richtig?
Sam

1
NGinx unterstützt sendfile syscall, mit dem Dateien direkt von der Festplatte gesendet werden können. Weitere Informationen finden Sie im folgenden Dokument wiki.nginx.org/HttpCoreModule zu den Anweisungen 'sendfile', 'aio'. Dieser Webserver liefert statische Dateien wie Bilder viel schneller als Apache.
Nefo_x

interessant ... Ich wusste nicht, dass es etwas Besseres als Apache geben kann. By the way, was meinst du straight from hdd. Meinst du stattdessen straight from DDR3 RAM/ straight from Solid State DiskIch weiß, dass Festplatten im Gegensatz zu DDR3-RAM oder Solid State Discs eine sehr langsame Zugriffszeit haben. Aber ich denke, das ist nicht der Engpass hier ...
Sam

1
Der Punkt ist, dass Nginx die statische Datenausgabe nicht wie Apache puffert.
nefo_x

1

Versuchen Sie in Bezug auf die verzögerten Miniaturansichten, einen Aufruf von flush () unmittelbar nach dem letzten Aufruf von header () in Ihrem Skript zur Erstellung von Miniaturansichten zu tätigen. Wenn Sie fertig sind, regenerieren Sie Ihr Wasserfalldiagramm und prüfen Sie, ob die Verzögerung jetzt auf dem Körper statt auf den Kopfzeilen liegt. In diesem Fall müssen Sie sich die Logik ansehen, mit der die Bilddaten generiert und / oder ausgegeben werden.

Das Skript, das die Miniaturansichten verarbeitet, sollte hoffentlich eine Art Caching verwenden, damit alle Aktionen, die für die von Ihnen bereitgestellten Bilder ausgeführt werden, nur ausgeführt werden, wenn dies unbedingt erforderlich ist. Es sieht so aus, als ob jedes Mal, wenn Sie die Miniaturansichten bereitstellen, eine teure Operation stattfindet, die die Ausgabe (einschließlich der Header) des Skripts verzögert .


+1 Spannende Vermutung, ich werde es jetzt ausprobieren! Ich werde berichten, wenn ich den neuen Wasserfall zum Fließen gebracht habe ...
Sam

Leider flush();scheint sich nach dem Hinzufügen direkt nach den Überschriften überhaupt nichts zu ändern! Was könnte das bedeuten?
Sam

Nicht sicher. Können Sie uns auf irgendeine Weise mit dem betreffenden PHP-Skript verknüpfen? Ich weiß, dass Sie dafür bezahlt haben, aber es ist unglaublich schwierig zu sagen, was das Verhalten verursachen könnte, ohne sehen zu können, was es tut.
AR Younce

Werden die Miniaturansichten in CSS oder in <img> -Tags referenziert?
AR Younce

Was meinst du mit in CSS referenziert? Sie sind in der Seite des Körpers HTML und wie folgt: <img src="thumbprocessor.php?src=/folder/image.jpg&w=100&h=200" id="thumbnail"/>
Sam

1

Der größte Teil des langsamen Problems ist, dass Ihr TTFB (Time to First Byte) zu hoch ist. Dies ist schwer zu lösen, ohne mit Ihren Serverkonfigurationsdateien, dem Code und der zugrunde liegenden Hardware vertraut zu werden, aber ich kann sehen, dass es bei jeder Anfrage weit verbreitet ist. Sie haben zu viele grüne Balken (schlecht) und sehr kleine blaue Balken (gut). Vielleicht möchten Sie das Frontend für eine Weile nicht mehr optimieren, da ich glaube, dass Sie in diesem Bereich viel getan haben. Trotz des Sprichworts, dass " 80% -90% der Antwortzeit des Endbenutzers für das Frontend aufgewendet wird ", glaube ich, dass Ihre Antwort im Backend stattfindet.

TTFB ist Backend-Zeug, Server-Zeug, Vorverarbeitung vor der Ausgabe und Handshake.

Planen Sie die Ausführung Ihres Codes, um langsame Dinge wie langsame Datenbankabfragen zu finden, und geben Sie Funktionen / Methoden ein, um langsame Funktionen zu finden. Wenn Sie PHP verwenden, versuchen Sie es mit Firephp . Manchmal werden während des Starts oder der Initialisierung ein oder zwei langsame Abfragen ausgeführt, z. B. das Abrufen von Sitzungsinformationen oder das Überprüfen der Authentifizierung und was nicht. Das Optimieren von Abfragen kann zu guten Leistungsgewinnen führen. Manchmal wird Code mit PHP Prepend oder Spl Autoload ausgeführt, damit sie auf allem ausgeführt werden. In anderen Fällen kann es zu einer Fehlkonfiguration von Apache Conf und Optimierungen kommen, die den Tag retten.

Suchen Sie nach ineffizienten Schleifen. Suchen Sie nach langsamen Abrufaufrufen von Caches oder langsamen E / A-Vorgängen, die durch fehlerhafte Laufwerke oder hohe Speicherplatznutzung verursacht werden. Suchen Sie nach Speichernutzung und was verwendet wird und wo. Führen Sie einen wiederholten Webpagetest-Test mit 10 Läufen für ein einzelnes Bild oder eine einzelne Datei durch, wobei Sie nur die erste Ansicht von verschiedenen Orten auf der ganzen Welt und nicht vom gleichen Ort aus verwenden. Lesen Sie Ihre Zugriffs- und Fehlerprotokolle, zu viele Entwickler ignorieren sie und verlassen sich nur auf ausgegebene Bildschirmfehler. Wenn Ihr Webhost Unterstützung hat, bitten Sie ihn um Hilfe. Wenn er ihn ohnehin nicht höflich um Hilfe bittet, tut dies nicht weh.

Sie können DNS Prefetching ausprobieren, um die vielen Domänen und Ressourcen zu bekämpfen. Http://html5boilerplate.com/docs/DNS-Prefetching/

Ist der Server Ihr eigener ein guter / anständiger Server? Manchmal kann ein besserer Server viele Probleme lösen. Ich bin ein Fan der Mentalität " Hardware ist billig, Programmierer sind teuer ", wenn Sie die Chance und das Geld haben, einen Server zu aktualisieren. Und / oder verwenden Sie ein CDN wie maxcdn oder cloudflare oder ähnliches.

Viel Glück!

(ps ich arbeite nicht für eines dieser Unternehmen. Auch der Cloudflare-Link oben wird argumentieren, dass TTFB nicht so wichtig ist, ich habe das da reingeworfen, damit Sie eine andere Einstellung bekommen können.)


Lieber Anthony, vielen Dank für dieses aufschlussreiche "Hintergrundwissen". Ich bin damit einverstanden, dass manchmal die Hardware der Engpass ist und dass dies weniger offensichtlich ist, insbesondere wenn das Hosting-Unternehmen den Serverteil in einer gemeinsam genutzten Hosting-Umgebung hostet. Ich denke, Cloudflare ist eine gute Option, um es in Kombination mit der Optimierung der Apache-Konfiguration auszuprobieren. Schöne Grüße!
Sam

-1

Leider geben Sie nur wenige Daten an. Und Sie hatten bereits einige gute Vorschläge.

Wie bedienen Sie diese Bilder? Wenn Sie diese über PHP streamen, machen Sie eine sehr schlechte Sache, selbst wenn sie bereits generiert wurden.

STREAMEN SIE BILDER NIEMALS MIT PHP. Es wird Ihren Server verlangsamen, egal wie Sie ihn verwenden.

Legen Sie sie in einem zugänglichen Ordner mit einer aussagekräftigen URI ab. Rufen Sie sie dann direkt mit ihrer realen URI an. Wenn Sie eine sofortige Generierung benötigen, sollten Sie eine .htaccess-Datei in das Images-Verzeichnis stellen, die nur dann zu einem Generator-PHP-Skript umleitet, wenn das Anforderungs-Image fehlt. (Dies wird als Cache-on-Request-Strategie bezeichnet.)

Dadurch werden PHP-Sitzung, Browser-Proxy, Caching und ETAGS auf einmal repariert.

WP-Supercache verwendet diese Strategie, wenn sie richtig konfiguriert ist.

Ich habe dies vor einiger Zeit geschrieben ( http://code.google.com/p/cache-on-request/source/detail?r=8 ), die letzten Revisionen sind defekt, aber ich denke, 8 oder weniger sollten funktionieren und Sie können Nehmen Sie das .htaccess als Beispiel, um die Dinge zu testen (obwohl es bessere Möglichkeiten gibt, das .htaccess zu konfigurieren als früher).

Ich habe diese Strategie in diesem Blogbeitrag beschrieben ( http://www.stefanoforenza.com/need-for-cache/ ). Es ist wahrscheinlich schlecht geschrieben, aber es kann helfen, die Dinge zu klären.

Weiterführende Literatur: http://meta.wikimedia.org/wiki/404_handler_caching


Beachten Sie, dass ErrorDocument nicht das Beste ist, was Sie tun können, da es Einträge im Fehlerprotokoll von Apache generiert hat. Eine -f-Umleitung wäre besser.
Tacone

Vielen Dank für Ihre Eingabe Tacone. Wollen Sie damit sagen, dass das PHP-Skript, egal wie gut es sein wird, den Server verlangsamt oder wie Sie in Ihrem Beitrag sagten: "Es wird Ihren Server töten, egal was passiert."
Sam

Es wird den Server verlangsamen, egal wie gut das Skript ist. Für jedes Bild muss der Server PHP laden und das Bild Byte für Byte streamen lassen. Lassen Sie Apache die Arbeit erledigen, ohne den PHP-Interpreter zu passieren. Als Nebeneffekt werden viele andere mögliche Fehler automatisch vermieden, wie z. B. Sitzungen, Inhaltslänge, Caching, MIME / Typ usw. Wenn die Leistung kritisch ist, sollten Sie nicht einmal PHP laden (sondern zur Generierungszeit).
Tacone

Stimmen Sie ab, können Sie erklären, warum?
Tacone
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.