Pytanie Część A ▉ (100 nagród, przyznane)
Głównym pytaniem było, jak sprawić, by ta strona ładowała się szybciej. Najpierw musieliśmy przeczytać te wodospady. Dziękujemy wszystkim za sugestie dotyczące analizy odczytu wodospadu. Widoczne na różnych pokazanych tutaj wykresach wodospadu jest główne wąskie gardło: miniatury generowane przez PHP. Załadowanie nagród z CDN bez protokołu, zalecane przez Davida, przyniosło mi nagrodę, chociaż ogólnie moja strona była tylko o 3% szybsza i nie odpowiadała na główne wąskie gardło strony. Czas na wyjaśnienie mojego pytania i kolejna nagroda:
Pytanie Część B ▉ (100 nagród, przyznane)
Teraz skupiono się na rozwiązaniu problemu, jaki miał 6 obrazów jpg, które powodują największe opóźnienie ładowania. Te obrazy są PHP 6 generowane miniatury, malutkie i tylko 3 ~ 5 kb, ale ładowanie stosunkowo bardzo powoli. Zwróć uwagę na „ czas do pierwszego bajtu ” na różnych wykresach. Problem pozostał nierozwiązany, ale nagrodę otrzymał James, który naprawił błąd nagłówka, który podkreślił RedBot : „Warunkowe żądanie If-Modified-Since zwróciło pełną treść bez zmian”. .
Pytanie Część C my (moja ostatnia nagroda: 250 punktów)
Niestety, nawet po naprawieniu błędu nagłówka REdbot.org opóźnienie spowodowane przez obrazy generowane przez PHP pozostało nietknięte. Co, u licha, myślą te małe, wątłe miniatury 3 ~ 5Kb? Wszystkie te informacje w nagłówku mogą wysłać rakietę na Księżyc iz powrotem. Wszelkie sugestie dotyczące tego wąskiego gardła są bardzo mile widziane i traktowane jako możliwa odpowiedź, ponieważ utknąłem w tym wąskim gardle już od siedmiu miesięcy. Z góry dziękuję.
[Kilka podstawowych informacji na mojej stronie: CSS jest na górze. JS na dole (Jquery, JQuery UI, kupione menu awm / menu.js silniki, tabs js silnik, wideo swfobject.js) Czarne linie na drugim obrazie pokazują, co inicjuje, co załadować. Wściekły robot to moje zwierzę domowe „ZAM”. Jest nieszkodliwy i często szczęśliwszy.]
Załaduj Wodospad: Chronologiczny | http://webpagetest.org
Domeny równoległe zgrupowane | http://webpagetest.org
Site-Perf Waterfall | http://site-perf.com
Pingdom Tools Wodospad | http://tools.pingdom.com
GTmetrix Waterfall | http://gtmetrix.com
SHOULD
), aby klienci HTTP 1.1 korzystali z maksymalnie 2 połączeń z serwerami HTTP 1.1; HTTP 1.0 jest oczywiście znacznie bardziej otwarty.Odpowiedzi:
Po pierwsze, korzystanie z tych wielu domen wymaga kilku wyszukiwań DNS. Lepiej byłoby połączyć wiele z tych obrazów w duszka zamiast rozprowadzać prośby.
Po drugie, kiedy ładuję twoją stronę, widzę większość blokowania (~ 1,25s) na all.js. Widzę, że zaczyna się od (starej wersji) jQuery. Powinieneś odwołać się do tego z Google CDN, aby nie tylko skrócić czas ładowania , ale potencjalnie całkowicie uniknąć żądania HTTP .
W szczególności najbardziej aktualne biblioteki interfejsu użytkownika jQuery i jQuery można znaleźć pod tymi adresami URL (zobacz ten post, jeśli jesteś zainteresowany, dlaczego pominąłem
http:
):Jeśli używasz jednego z domyślnych motywów interfejsu użytkownika jQuery, możesz również pobrać jego CSS i obrazy z CDN Google .
Z jQuery hosting zoptymalizowane, należy również łączyć
awmlib2.js
itooltiplib.js
do jednego pliku.Jeśli zajmiesz się tymi sprawami, powinieneś zauważyć znaczną poprawę.
źródło
Miałem podobny problem kilka dni temu i znalazłem head.js . Jest to wtyczka Javascript, która pozwala załadować wszystkie pliki JS równolegle. Mam nadzieję, że to pomaga.
źródło
Jestem daleki od eksperta, ale ...
W związku z tym: „Warunkowe żądanie If-Modified-Since zwróciło pełną treść bez zmian”. i moje komentarze.
Kod użyty do wygenerowania miniaturek powinien sprawdzać, czy:
Jeśli którykolwiek z nich jest fałszywy, miniatura powinna zostać wygenerowana i zwrócona bez względu na wszystko. Jeśli oba są prawdziwe, należy wykonać następujące sprawdzenie:
Jeśli którakolwiek z tych wartości jest fałszywa, należy zwrócić miniaturę z pamięci podręcznej.
Jeśli oba są prawdziwe, należy zwrócić status 304 http. Nie jestem pewien, czy jest to wymagane, ale osobiście zwracam również nagłówki Cache-Control, Expires i Last-Modified wraz z 304.
W odniesieniu do GZipping zostałem poinformowany, że nie ma potrzeby używania obrazów GZip, więc zignoruj tę część mojego komentarza.
Edycja: Nie zauważyłem twojego dodania do twojego postu.
Jestem również pewien, że Twój kod musi sprawdzić nagłówek HTTP_IF_MODIFIED_SINCE i zareagować na to. Samo ustawienie tych nagłówków i pliku .htaccess nie zapewni wymaganego rezultatu.
Myślę, że potrzebujesz czegoś takiego:
źródło
If Modified Since
problem wydaje się działać teraz! Jednak długie nagłówki / czas oczekiwania na maleńkie kciuki nie zostały jeszcze rozwiązane ...Wow, trudno jest wyjaśnić rzeczy za pomocą tego obrazu. Ale tutaj niektóre próby:
źródło
Po prostu zgadnij, ponieważ tego rodzaju analiza wymaga wielu testów A / B: domena .ch wydaje się trudna do osiągnięcia (długie, zielone pasma przed nadejściem pierwszego bajtu).
Oznaczałoby to, że witryna .ch jest źle hostowana lub że twój dostawca usług internetowych nie ma dobrej drogi do nich.
Biorąc pod uwagę diagramy, może to wyjaśniać duży hit wydajności.
Na marginesie, nie jest to fajne narzędzie cuzillion które mogłyby pomóc uporządkować rzeczy w zależności od uporządkowania ressource załadunku.
źródło
Spróbuj uruchomić testy Y! Slow i Page Speed na swojej stronie / stronie i postępuj zgodnie ze wskazówkami, aby rozwiązać ewentualne wąskie gardła w wydajności. Powinieneś uzyskać ogromny wzrost wydajności, gdy uzyskasz wyższy wynik w Y! Slow lub Page Speed.
Te testy pokażą ci, co jest nie tak i co zmienić.
źródło
Więc skrypt PHP generuje miniatury przy każdym ładowaniu strony? Po pierwsze, jeśli miniaturki obrazów nie zmieniają się tak często, czy możesz ustawić pamięć podręczną tak, aby nie musiała być analizowana przy każdym ładowaniu strony? Po drugie, czy twój skrypt PHP używa czegoś takiego jak
imagecopyresampled()
tworzenie miniatur? To nie jest trywialne próbkowanie i skrypt PHP nic nie zwróci, dopóki nie zakończy zmniejszania. Za pomocąimagecopymerged()
zamiast tego obniży jakość obrazu, ale przyspieszy proces. A ile robisz redukcji? Czy te miniatury są o 5% większe od oryginalnego obrazu, czy o 50%? Większy rozmiar oryginalnego obrazu prawdopodobnie prowadzi do spowolnienia, ponieważ skrypt PHP musi pobrać oryginalny obraz do pamięci, zanim będzie mógł go zmniejszyć i wygenerować mniejszą miniaturę.źródło
readfile()
a niefile_get_contents()
echa, które czeka na wyjście, aż cały plik zostanie przeniesiony do pamięci skryptu PHP.Znalazłem adres URL twojej witryny i sprawdziłem pojedynczy plik jpg ze strony głównej. Chociaż czas ładowania jest teraz rozsądny (161 ms), czeka on na 126 ms, co jest zdecydowanie za dużo.
Twoje ostatnio zmodyfikowane nagłówki są ustawione na Sat, 01 stycznia 2011 12:00:00 GMT, co wydaje się zbyt „okrągłe”, aby być prawdziwą datą generacji ;-)
Ponieważ kontrola pamięci podręcznej ma wartość „public, max-age = 14515200”, dowolne nagłówki ostatniej modyfikacji mogą powodować problemy po 168 dniach.
W każdym razie nie jest to prawdziwy powód opóźnień.
Musisz sprawdzić, co robi generator miniatur, gdy miniatura już istnieje i co może zająć tyle czasu na sprawdzenie i dostarczenie obrazu.
Możesz zainstalować xdebug, aby profilować skrypt i sprawdzać, gdzie są wąskie gardła.
Być może cała ta rzecz korzysta z frameworka lub łączy się z jakąś bazą danych za darmo. Widziałem bardzo powolną mysql_connect () na niektórych serwerach, głównie dlatego, że łączyły się one za pomocą TCP, a nie gniazda, czasem z pewnymi problemami z DNS.
Rozumiem, że nie możesz opublikować tutaj swojego płatnego generatora, ale obawiam się, że istnieje zbyt wiele możliwych problemów ...
źródło
Jeśli nie ma naprawdę dobrego powodu (zwykle nie ma), twoje obrazy nie powinny wywoływać interpretera PHP.
Utwórz regułę przepisywania dla swojego serwera WWW, który bezpośrednio obsługuje obraz, jeśli zostanie on znaleziony w systemie plików. Jeśli nie, przekieruj do skryptu PHP, aby wygenerować obraz. Podczas edycji obrazu zmień nazwę pliku obrazów, aby zmusić użytkowników posiadających wersję z pamięci podręcznej do pobrania nowo edytowanego obrazu.
Jeśli to nie zadziała przynajmniej teraz, to nie ma to nic wspólnego ze sposobem tworzenia i sprawdzania obrazów.
źródło
Zbadaj wykorzystanie danych sesji przez PHP. Być może (tylko być może) skrypt PHP generujący obraz czeka na zablokowanie danych sesji, które są blokowane przez wciąż wyświetlaną stronę główną lub inne skrypty renderowania obrazu. To spowodowałoby, że wszystkie optymalizacje JavaScript / przeglądarki byłyby prawie nieistotne, ponieważ przeglądarka czeka na serwer.
PHP blokuje dane sesji dla każdego uruchomionego skryptu, od momentu rozpoczęcia obsługi sesji, do momentu zakończenia skryptu lub wywołania session_write_close (). To skutecznie serializuje rzeczy. Sprawdź stronę PHP na temat sesji, zwłaszcza komentarzy, takich jak ta .
źródło
To tylko dzikie przypuszczenie, ponieważ nie spojrzałem na twój kod, ale podejrzewam, że sesje mogą tutaj odgrywać pewną rolę, poniższe informacje pochodzą z wpisu w PHP Manual na
session_write_close()
:Tak jak powiedziałem, nie wiem, co robi twój kod, ale te wykresy wydają się dziwnie podejrzane. Miałem podobny problem, gdy kodowałem funkcję wyświetlania plików wieloczęściowych i miałem ten sam problem. Podczas serwowania dużego pliku nie mogłem uruchomić funkcji wieloczęściowej ani nie mogłem otworzyć innej strony, dopóki pobieranie nie zostanie zakończone. Dzwonienie
session_write_close()
naprawiło oba moje problemy.źródło
exit();
funkcja ma podobne linie jaksession_write_close();
? obecnie oryginalny autor kodu bada ten problem, ale wydaje się, że jest on również trochę w ciemności, ponieważ jego hojna aktualizacja kodu z lepszą obsługą If-Modified-Since wydaje się mieć takie same opóźnienia (nowy wodospad wykresy tworzyły te same wykresy, chociaż rzeczywiste wyniki worl wyglądały / odczuwały szybsze ładowanie! To bardzo dziwny problem ...Czy próbowałeś zastąpić thumnails generowane przez php zwykłymi obrazami, aby zobaczyć, czy jest jakaś różnica? Problem może być związany z - błąd w kodzie php prowadzący do regeneracji miniatury przy każdym wywołaniu serwera - opóźnienie w kodzie (uśpienie ()?) Związane z problemem z zegarem - problem z dyskiem twardym powodujący bardzo zły stan wyścigu ponieważ wszystkie miniatury są ładowane / generowane jednocześnie.
źródło
Myślę, że zamiast używać tego skryptu generującego miniatury , musisz dać TinySRC szansę na szybkie, szybkie generowanie miniaturek w chmurze. Ma bardzo prosty i łatwy w użyciu interfejs API, z którego można korzystać w następujący sposób: -
http://i.tinysrc.mobi/ [wysokość] / [szerokość] /http://domain.tld/path_to_img.jpg
[szerokość] (opcjonalnie): - Jest to szerokość w pikselach (która przesłania wielkość adaptacyjną lub rodzinną). Jeśli poprzedza je „-” lub „x”, odejmie lub zmniejszy się do procentu określonego rozmiaru.
[wysokość] (opcjonalnie): - Jest to wysokość w pikselach, jeśli występuje również szerokość. Zastępuje także dostosowywanie lub rozmiar rodziny i może być poprzedzone znakiem „-” lub „x”.
Można sprawdzić podsumowanie API tutaj
FAQ
Ile kosztuje maleSrc?
Nic.
Kiedy mogę zacząć korzystać z tinySrc?
Teraz.
Jak niezawodna jest usługa?
Nie udzielamy żadnych gwarancji dotyczących usługi tinySrc. Działa jednak na dużej rozproszonej infrastrukturze chmurowej , dzięki czemu zapewnia wysoką dostępność na całym świecie. To powinno wystarczyć na wszystkie Twoje potrzeby.
Jak szybko to jest
tinySrc buforuje obrazy o zmienionym rozmiarze w pamięci i naszym magazynie danych przez maksymalnie 24 godziny i za każdym razem nie pobierze oryginalnego obrazu. To sprawia, że usługi są niezwykle szybkie z perspektywy użytkownika. (I zmniejsza obciążenie serwera jako miły efekt uboczny.)
Powodzenia. Tylko sugestia, ponieważ nie wyświetlasz nam kodu: p
źródło
Ponieważ niektóre przeglądarki pobierają tylko 2 równoległe pliki do pobrania na domenę, nie możesz dodać dodatkowych domen, aby oddzielić żądania od dwóch do trzech różnych nazw hostów. np. 1.imagecdn.com 2.imagecdn.com
źródło
Po pierwsze, musisz obsługiwać
If-Modified-Since
wnioski i tak odpowiednio, jak powiedział James. Ten błąd stwierdza, że: „Kiedy pytam twój serwer, czy ten obraz został zmodyfikowany od ostatniego razu, wysyła cały obraz zamiast zwykłego tak / nie”.Czas między połączeniem a pierwszym bajtem to na ogół czas potrzebny na uruchomienie skryptu PHP. Oczywiste jest, że coś się dzieje, gdy skrypt zaczyna działać.
Generowanie odpowiednich nagłówków za pomocą aplikacji jest nieco trudne, a ponadto mogą zostać zastąpione przez serwer. I jesteś narażony na nadużycia, ponieważ każdy, kto wysyła nagłówki żądań bez pamięci podręcznej, spowoduje, że generator miniatur będzie działał nieprzerwanie (i zwiększy obciążenia). Jeśli to możliwe, spróbuj zapisać wygenerowane kciuki, wywołać zapisane obrazy bezpośrednio ze swoich stron i zarządzać nagłówkami
.htaccess
. W takim przypadku nie potrzebujesz niczego w.htaccess
swoim serwerze, jeśli Twój serwer jest odpowiednio skonfigurowany.Inne niż te, możesz zastosować niektóre z pomysłów na optymalizację z części wydajnościowych tego ogólnego miłego SO pytania o to, jak robić strony internetowe we właściwy sposób , np. Dzielenie zasobów na bezdechowe subdomeny itp. Ale w każdym razie obraz 3k ładowanie nie powinno zająć sekundy, jest to widoczne w porównaniu z innymi elementami na wykresach. Powinieneś spróbować znaleźć problem przed optymalizacją.
źródło
Czy próbowałeś skonfigurować kilka subdomen pod serwerem NGINX specjalnie do obsługi danych statycznych, takich jak obrazy i arkusze stylów? W tym temacie można już znaleźć coś pomocnego .
źródło
straight from hdd
. masz na myśli zamiast tegostraight from DDR3 RAM
/straight from Solid State Disk
wiem, że dyski twarde, w przeciwieństwie do pamięci RAM DDR3 lub dysków SSD, mają bardzo wolny czas dostępu. Ale wydaje mi się, że to nie jest wąskie gardło ...Jeśli chodzi o opóźnione miniatury, spróbuj wywołać funkcję flush () natychmiast po ostatnim wywołaniu funkcji header () w skrypcie generowania miniatur. Po zakończeniu zregeneruj wykres wodospadu i sprawdź, czy opóźnienie występuje teraz na ciele zamiast na nagłówkach. Jeśli tak, musisz rzucić okiem na logikę, która generuje i / lub wyprowadza dane obrazu.
Skrypt, który obsługuje miniatury powinien, mam nadzieję, użyć pewnego rodzaju buforowania, aby wszelkie działania podejmowane na obrazach, które wyświetlasz, miały miejsce tylko wtedy, gdy jest to absolutnie konieczne. Wygląda na to, że za każdym razem, gdy wyświetlasz miniatury, odbywa się kosztowna operacja, która opóźnia jakiekolwiek wyjście (w tym nagłówki) ze skryptu.
źródło
flush();
tuż po nagłówkach wydaje się, że nic się nie zmienia! Co to może znaczyć?<img src="thumbprocessor.php?src=/folder/image.jpg&w=100&h=200" id="thumbnail"/>
Większość powolnych problemów to zbyt wysoki czas TTFB (czas do pierwszego bajtu). Jest to trudna do rozwiązania bez intymności z plikami konfiguracyjnymi serwera, kodem i sprzętem bazowym, ale widzę, że rozprzestrzenia się przy każdym żądaniu. Masz za dużo zielonych pasków (źle) i bardzo mało niebieskich pasków (dobrze). Możesz na chwilę przestać optymalizować frontend, ponieważ uważam, że wiele zrobiłeś w tej dziedzinie. Pomimo powiedzenia, że „ 80% -90% czasu reakcji użytkownika końcowego jest spędzane na interfejsie użytkownika ”, uważam, że twój występuje w interfejsie użytkownika .
TTFB to backend, serwer, przetwarzanie wstępne przed wyjściem i uzgadnianie.
Czas na wykonanie kodu, aby znaleźć wolne rzeczy, takie jak powolne zapytania do bazy danych, czas wchodzenia i wychodzenia z funkcji / metod, aby znaleźć wolne funkcje. Jeśli używasz php, spróbuj Firephp . Czasami podczas uruchamiania lub inicjowania uruchamiane jest jedno lub dwa wolne zapytania, takie jak pobieranie informacji o sesji lub sprawdzanie autentyczności, a co nie. Optymalizacja zapytań może prowadzić do dobrych zysków. Czasami kod jest uruchamiany przy użyciu php prepend lub spl autoload, aby działały na wszystkim. Innym razem może to być źle skonfigurowana konfiguracja i modyfikacja apache, która oszczędza dzień.
Poszukaj nieefektywnych pętli. Szukaj powolnego pobierania wywołań pamięci podręcznej lub powolnych operacji we / wy spowodowanych przez wadliwe napędy dysków lub duże wykorzystanie miejsca na dysku. Poszukaj zastosowań pamięci, co jest używane i gdzie. Uruchom powtarzany test 10 stron na jednym obrazie lub pliku, używając tylko pierwszego widoku z różnych lokalizacji na całym świecie, a nie z tej samej lokalizacji. I czytaj swoje dzienniki dostępu i błędów, zbyt wielu programistów je ignoruje i polega wyłącznie na wynikowych błędach ekranowych. Jeśli Twój hosting ma wsparcie, poproś go o pomoc, jeśli i tak może grzecznie nie poprosi o pomoc, to nie zaszkodzi.
Możesz spróbować pobrać wstępnie DNS, aby zwalczyć wiele domen i zasobów, http://html5boilerplate.com/docs/DNS-Prefetching/
Czy serwer jest twoim własnym / dobrym serwerem? Czasami lepszy serwer może rozwiązać wiele problemów. Jestem fanem mentalności „ sprzęt jest tani, programiści są kosztowni ”, jeśli masz szansę i pieniądze na ulepszenie serwera. I / lub użyj CDN, takiego jak maxcdn lub cloudflare lub podobny.
Powodzenia!
(ps, nie pracuję dla żadnej z tych firm. Również powyższy link cloudflare będzie argumentował, że TTFB nie jest aż tak ważny, wrzuciłem to tam, abyś mógł wziąć jeszcze jedno.)
źródło
Przykro mi to mówić, podajesz niewiele danych. I masz już kilka dobrych sugestii.
Jak serwujesz te obrazy? Jeśli przesyłasz strumieniowo te przez PHP, robisz bardzo złe rzeczy, nawet jeśli są już wygenerowane.
NIGDY NIE PRZESYŁAJ OBRAZÓW Z PHP. Spowolni twój serwer, bez względu na sposób korzystania z niego.
Umieść je w dostępnym folderze z sensownym identyfikatorem URI. Następnie zadzwoń do nich bezpośrednio z ich prawdziwym identyfikatorem URI. Jeśli potrzebujesz w locie, powinieneś umieścić .htaccess w katalogu images, który przekierowuje do skryptu php generatora tylko wtedy, gdy brakuje obrazu żądania. (nazywa się to strategią buforowania na żądanie).
Spowoduje to naprawienie sesji php, proxy przeglądarki, buforowania, ETAGS, cokolwiek naraz.
WP-Supercache korzysta z tej strategii, jeśli jest poprawnie skonfigurowana.
Napisałem to jakiś czas temu ( http://code.google.com/p/cache-on-request/source/detail?r=8 ), ostatnie poprawki są zepsute, ale wydaje mi się, że 8 lub mniej powinno działać i możesz skorzystaj z .htaccess jako przykładu, aby przetestować różne rzeczy (chociaż istnieją lepsze sposoby konfiguracji .htaccess niż to, co kiedyś).
Opisałem tę strategię w tym poście na blogu ( http://www.stefanoforenza.com/need-for-cache/ ). Prawdopodobnie jest źle napisany, ale może pomóc w wyjaśnieniu.
Dalsza lektura: http://meta.wikimedia.org/wiki/404_handler_caching
źródło