캐시되고 PHP로 생성 된 썸네일이 느리게로드됩니다
질문 파트 A ▉ (100 bountys, award)
주요 질문은이 사이트를 어떻게 만들고 더 빠르게로드 하는가였습니다. 먼저 우리는이 폭포를 읽을 필요가있었습니다. 폭포 판독 분석에 대한 제안에 감사드립니다. 여기에 표시된 다양한 폭포 그래프에서 분명한 주요 병목은 PHP로 생성 된 썸네일입니다. David가 조언 한 CDN에서 프로토콜이없는 jquery 로딩은 전체 사이트를 3 % 더 빠르게 만들지 만 사이트의 주요 병목 현상은 해결하지 못했지만 현상금을 받았습니다. 내 질문을 명확히 할 시간과 또 다른 현상금 :
Question Part B ▉ (100 bountys, award)
새로운 촛점은 6 개의 jpg 이미지가 가지고있는 문제를 해결하는 것이 었습니다. 이 6 개 이미지는 PHP 생성 된 작은 썸네일, 만 3 ~ 5킬로바이트하지만 로딩 상대적이다 매우 느리게. 다양한 그래프 에서 " time to first byte "를 확인하십시오. 문제는 해결되지 않았지만 현상금은 James에게 갔으며, James는 RedBot에 밑줄을 긋 은 헤더 오류를 수정했습니다 . "If-Modified-Since 조건부 요청은 전체 내용을 변경하지 않고 반환했습니다." .
질문 파트 C ▉ (마지막 현상금 : 250 포인트)
불행히도 REdbot.org 헤더 오류가 수정 된 후에도 PHP로 생성 된 이미지로 인한 지연은 그대로 유지되었습니다. 이 작은 겁쟁이 3 ~ 5Kb 썸네일은 지구상에서 무엇을 생각하고 있습니까? 모든 헤더 정보는 로켓을 달과 뒤로 보낼 수 있습니다. 이 병목 현상에 대한 모든 제안은 이미 7 개월 동안이 병목 현상 문제에 갇혀 있기 때문에 가능한 답변으로 처리되어 매우 높이 평가됩니다. 미리 감사드립니다.
[내 사이트의 일부 배경 정보 : CSS가 맨 위에 있습니다. 맨 아래 JS (Jquery, JQuery UI, 메뉴 awm / menu.js 엔진, 탭 js 엔진, 비디오 swfobject.js 구매) 두 번째 이미지의 검은 색 선은로드 할 내용을 보여줍니다. 화난 로봇은 내 애완 동물 "ZAM"입니다. 그는 무해하고 더 행복합니다.]
폭포 폭포 : 연대기 | http://webpagetest.org
병렬 도메인 그룹화 | http://webpagetest.org
현장 성능 폭포 | http://site-perf.com
Pingdom Tools 폭포 | http://tools.pingdom.com
GTmetrix 폭포 | http://gtmetrix.com
먼저 이러한 여러 도메인을 사용하려면 몇 가지 DNS 조회가 필요합니다. 요청을 분산시키는 대신 많은 이미지를 스프라이트로 결합하는 것이 좋습니다 .
둘째, 페이지를로드하면 all.js에서 대부분의 차단 (~ 1.25 초)을 볼 수 있습니다. jQuery (이전 버전)로 시작하는 것을 알았습니다. 로드 시간 을 줄이면서 HTTP 요청을 완전히 피 하려면 Google CDN에서이를 참조해야합니다 .
특히 최신 jQuery 및 jQuery UI 라이브러리는 다음 URL에서 참조 할 수 있습니다 ( 이를 생략 한 이유에 관심이있는 경우이 게시물 참조 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
기본 jQuery UI 테마 중 하나를 사용하는 경우 CSS 및 이미지를 Google CDN에서 가져올 수 있습니다 .
JQuery와 최적화 호스팅, 당신은 또한 결합해야 awmlib2.js
하고 tooltiplib.js
하나의 파일로.
이러한 문제를 해결하면 크게 개선 될 것입니다.
며칠 전에 비슷한 문제가 있었고 head.js를 찾았 습니다 . 모든 JS 파일을 병렬로로드 할 수있는 Javascript 플러그인입니다. 희망이 도움이됩니다.
나는 전문가와는 거리가 멀지 만 ...
이와 관련하여 : "If-Modified-Since 조건부 요청은 전체 내용을 변경하지 않고 반환했습니다." 그리고 내 의견.
썸네일을 생성하는 데 사용 된 코드는 다음을 확인해야합니다.
- 캐시 된 버전의 썸네일이 있습니까?
- 캐시 된 버전이 원본 이미지보다 최신 버전입니다.
이들 중 하나가 거짓이면 썸네일이 생성되어 무엇이든 반환되어야합니다. 둘 다 참이면 다음을 확인해야합니다.
- HTTP_IF_MODIFIED_SINCE 헤더가 있습니까
- 캐시 된 버전의 마지막 수정 시간이 HTTP_IF_MODIFIED_SINCE와 동일합니까?
이들 중 하나가 거짓이면 캐시 된 썸네일이 반환되어야합니다.
둘 다 참이면 304 http 상태가 리턴되어야합니다. 필요한지 확실하지 않지만 개인적으로 Cache-Control, Expires 및 Last-Modified 헤더를 304와 함께 반환합니다.
GZipping과 관련하여 GZip 이미지가 필요하지 않으므로 내 의견의 해당 부분을 무시하십시오.
편집 : 귀하의 게시물에 추가 한 내용을 보지 못했습니다.
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");
또한 코드에서 HTTP_IF_MODIFIED_SINCE 헤더를 확인하고 이에 대응해야합니다. 이 헤더와 .htaccess 파일을 설정하면 필요한 결과를 얻을 수 없습니다.
나는 당신이 이와 같은 것을 필요로한다고 생각합니다 :
$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
와우, 그 이미지를 사용하여 설명하는 것은 어렵습니다. 그러나 여기, 일부 시도는 :
- files 33-36 load that late, because they are dynamically loaded within the swf, and the swf (25) is loaded first completely before it loads any additional content
- files 20 & 21 are maybe (I don't know, because I don't know your code) libraries that are loaded by all.js (11), but for 11 to execute, it waits for the whole page (and assets) to load (you should change that to domready)
- files 22-32 are loaded by those two libraries, again after those are completely loaded
Just a simple guess because this kind of analysis requires a lot of A/B testing: your .ch domain seems to be hard to reach (long, green bands before the first byte arrives).
This would mean that either the .ch website is poorly hosted or that you ISP does not have a good route to them.
Given the diagrams, this could explain a big performance hit.
참고로, 리소스 로딩 순서에 따라 항목을 정렬하는 데 도움 이되는이 멋진 도구 cuzillion 이 있습니다.
사이트 / 페이지에서 Y! Slow 및 Page Speed 테스트를 실행하고 가능한 성능 병목을 정렬하기위한 지침을 따르십시오. Y! Slow 또는 Page Speed에서 더 높은 점수를 얻으면 성능이 크게 향상됩니다.
이 테스트는 무엇이 잘못되었고 무엇을 변경해야하는지 알려줍니다.
따라서 PHP 스크립트는 모든 페이지로드에서 축소판을 생성합니까? 우선, 썸네일 이미지가 자주 변경되지 않는 경우 페이지를로드 할 때마다 파싱하지 않아도되도록 캐시를 설정할 수 있습니까? 둘째, PHP 스크립트 imagecopyresampled()
가 썸네일을 만드는 것과 같은 것을 사용하고 있습니까? 그것은 사소한 다운 샘플이며 PHP 스크립트는 축소가 끝날 때까지 아무것도 반환하지 않습니다. imagecopymerged()
대신 사용 하면 이미지 품질이 떨어지지 만 프로세스 속도는 빨라집니다. 그리고 얼마나 줄어드는가? 이 썸네일이 원본 이미지의 5 % 또는 50 %입니까? 원본 이미지의 크기가 크면 PHP 스크립트가 원본 이미지를 메모리에 가져 와서 축소하고 작은 축소판을 출력해야하기 때문에 속도가 느려질 수 있습니다.
I've found the URL of your website and checked an individual jpg file from the homepage. While the loading time is reasonable now (161ms), it's waiting for 126ms, which is far too much.
Your last-modified headers are all set to Sat, 01 Jan 2011 12:00:00 GMT, which looks too "round" to be the real date of generation ;-)
Since Cache-control is "public, max-age=14515200", arbitrary last-modified headers will could cause problem after 168 days.
Anyway, this is not the real reason for delays.
You have to check what your thumbnail generator do when the thumbnail already exists and what could consume so much time checking and delivering the picture.
You could install xdebug to profile the script and see where the bottlenecks are.
Maybe the whole thing uses a framework or connects to some database for nothing. I've seen very slow mysql_connect() on some servers, mostly because they were connecting using TCP and not socket, sometimes with some DNS issues.
I understand you can't post your paid generator here but I'm afraid there are too many possible issues...
If there isn't a really good reason (usually there isn't) your images shouldn't invoke the PHP interpreter.
Create a rewrite rule for your web server that servers the image directly if it is found on the file system. If it's not, redirect to your PHP script to generate the image. When you edit the image, change the images filename to force users that have a cached version to fetch the newly edited image.
If it doesn't work at least you will now it doesn't have anything to do with the way the images are created and checked.
Investigate PHP's usage of session data. Maybe (just maybe), the image-generating PHP script is waiting to get a lock on the session data, which is locked by the still-rendering main page or other image-rendering scripts. This would make all the JavaScript/browser optimizations almost irrelevant, since the browser's waiting for the server.
PHP locks the session data for every script running, from the moment the session handling starts, to the moment the script finishes, or when session_write_close() is called. This effectively serializes things. Check out the PHP page on sessions, especially the comments, like this one.
This is just a wild guess since I haven't looked at your code but I suspect sessions may be playing a role here, the following is from the PHP Manual entry on session_write_close()
:
Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.
Like I said, I don't know what your code is doing but those graphs seem oddly suspicious. I had a similar issue when I coded a multipart file serving function and I had the same problem. When serving a large file I couldn't get the multipart functionality to work nor could I open another page until the download was completed. Calling session_write_close()
fixed both my problems.
Have you tried replacing the php generated thumnails by regular images to see if there is any difference ? The problem could be around - a bug in your php code leading to a regeneration of the thumbnail upon each server invocation - a delay in your code ( sleep()?) associated with a clock problem - a hardrive issue causing a very bad race condition since all the thumbnails get loaded/generated at the same time.
I think instead of using that thumbnail-generator script you must give TinySRC a try for rapid fast and cloud-hosted thumbnail generation. It has a very simple and easy to use API, you can use like:-
http://i.tinysrc.mobi/ [height] / [width] /http://domain.tld/path_to_img.jpg
[width] (optional):- This is a width in pixels (which overrides the adaptive- or family-sizing). If prefixed with ‘-’ or ‘x’, it will subtract from, or shrink to a percentage of, the determined size.
[height] (optional):- This is a height in pixels, if width is also present. It also overrides adaptive- or family-sizing and can be prefixed with ‘-’ or ‘x’.
You can check the API summary here
FAQ
What does tinySrc cost me?
Nothing.
When can I start using tinySrc?
Now.
How reliable is the service?
We make no guarantees about the tinySrc service. However, it runs on a major, distributed cloud infrastructure, so it provides high availability worldwide. It should be sufficient for all your needs.
How fast is it?
tinySrc caches resized images in memory and in our datastore for up to 24 hours, and it will not fetch your original image each time. This makes the services blazingly fast from the user’s perspective. (And reduces your server load as a nice side-effect.)
Good Luck. Just a suggestion, since u ain't showing us the code :p
As some browsers only download 2 parallels downloads per domain, could you not add additional domains to shard the requests over two to three different hostnames. e.g. 1.imagecdn.com 2.imagecdn.com
First of all, you need to handle If-Modified-Since
requests and such appropriately, as James said. That error states that: "When I ask your server if that image is modified since the last time, it sends the whole image instead of a simple yes/no".
The time between the connection and the first byte is generally the time your PHP script takes to run. It is apparent that something is happening when that script starts to run.
- Have you considered profiling it? It may have some issues.
- Combined with the above issue, your script may be running many more times than needed. Ideally, it should generate thumbs only if the original image is modified and send cached thumbs for every other request. Have you checked that the script is generating the images unnecessarily (e.g. for each request)?
Generating proper headers through the application is a bit tricky, plus they may get overwritten by the server. And you are exposed to abuse as anyone sending some no-cache request headers will cause your thumbnail generator to run continuously (and raise loads). So, if possible, try to save those generated thumbs, call the saved images directly from your pages and manage headers from .htaccess
. In this case, you wouldn't even need anything in your .htaccess
if your server is configured properly.
Other than these, you can apply some of the bright optimization ideas from the performance parts of this overall nice SO question on how to do websites the right way, like splitting your resources into cookieless subdomains, etc. But at any rate, a 3k image shouldn't take a second to load, this is apparent when compared to other items in the graphs. You should try to spot the problem before optimizing.
Have you tried to set up several subdomains under NGINX webserver specially for serving static data like images and stylesheets? Something helpful could be already found in this topic.
Regarding the delayed thumbnails, try putting a call to flush() immediately after the last call to header() in your thumbnail generation script. Once done, regenerate your waterfall graph and see if the delay is now on the body instead of the headers. If so you need to take a long look at the logic that generates and/or outputs the image data.
The script that handles the thumbnails should hopefully use some sort of caching so that whatever actions it takes on the images you're serving will only happen when absolutely necessary. It looks like some expensive operation is taking place every time you serve the thumbnails which is delaying any output (including the headers) from the script.
The majority of the slow issue is your TTFB (Time to first byte) being too high. This is a hard one to tackle without getting intimate with your server config files, code and underlying hardware, but I can see it's rampant on every request. You got too much green bars (bad) and very little blue bars (good). You might want to stop optimizing the frontend for a bit, as I believe you've done much in that area. Despite the adage that "80%-90% of the end-user response time is spent on the frontend", I believe yours is occuring in the backend.
TTFB is backend stuff, server stuff, pre-processing prior to output and handshaking.
Time your code execution to find slow stuff like slow database queries, time entering and exiting functions/methods to find slow functions. If you use php, try Firephp. Sometimes it is one or two slow queries being run during startup or initializtion like pulling session info or checking authentication and what not. Optimizing queries can lead to some good perf gains. Sometimes code is run using php prepend or spl autoload so they run on everything. Other times it can be mal configured apache conf and tweaking that saves the day.
Look for inefficient loops. Look for slow fetching calls of caches or slow i/o operations caused by faulty disk drives or high disk space usage. Look for memory usages and what's being used and where. Run a webpagetest repeated test of 10 runs on a single image or file using only first view from different locations around the world and not the same location. And read your access and error logs, too many developers ignore them and rely only on outputted onscreen errors. If your web host has support, ask them for help, if they don't maybe politely ask them for help anyway, it won't hurt.
You can try DNS Prefetching to combat the many domains and resources, http://html5boilerplate.com/docs/DNS-Prefetching/
Is the server your own a good/decent server? Sometimes a better server can solve a lot of problems. I am a fan of the 'hardware is cheap, programmers are expensive' mentality, if you have the chance and the money upgrade a server. And/Or use a CDN like maxcdn or cloudflare or similar.
Good Luck!
(p.s. i don't work for any of these companies. Also the cloudflare link above will argue that TTFB is not that important, I threw that in there so you can get another take.)
Sorry to say, you provide to few data. And you already had some good suggestions.
How are you serving those images ? If you're streaming those via PHP you're doing a very bad thing, even if they are already generated.
NEVER STREAM IMAGES WITH PHP. It will slow down your server, no matter the way you use it.
Put them in a accessible folder, with a meaningful URI. Then call them directly with their real URI. If you need on the fly generation you should put an .htaccess in the images directory which redirects to a generator php-script only if the request image is missing. (this is called cache-on-request strategy).
Doing that will fix php session, browser-proxy, caching, ETAGS, whatever all at once.
WP-Supercache uses this strategy, if properly configured.
나는 이것을 얼마 전에 썼다 ( http://code.google.com/p/cache-on-request/source/detail?r=8 ), 마지막 개정이 깨졌지만 8 이하가 작동해야한다고 생각합니다. .htaccess를 예제로 사용하여 테스트 해보십시오 (예전보다 .htaccess를 구성하는 더 좋은 방법이 있지만).
이 블로그 게시물 ( http://www.stefanoforenza.com/need-for-cache/ ) 에서 전략을 설명했습니다 . 아마도 잘못 쓰여졌을 수도 있지만 명확하게 설명하는 데 도움이 될 수 있습니다.
추가 자료 : http://meta.wikimedia.org/wiki/404_handler_caching
참고 URL : https://stackoverflow.com/questions/4810806/cached-php-generated-thumbnails-load-slowly
'Programing' 카테고리의 다른 글
phpmyadmin 사용자 세션이 너무 빨리 시간 초과되지 않도록 설정하는 방법은 무엇입니까? (0) | 2020.05.20 |
---|---|
Swift에서 버튼 텍스트를 다시 설정하는 방법 (0) | 2020.05.19 |
사람들은 Go에서 인증을 어떻게 관리하고 있습니까? (0) | 2020.05.19 |
String.Empty가 상수가 아닌 이유는 무엇입니까? (0) | 2020.05.19 |
PHP로 PDF를 작성하는 가장 좋은 방법 (0) | 2020.05.19 |