4

Web サイトに表示する画像 URL を返す外部 Web サービスを使用しています。たとえば、次のようになります。

$url = get_from_web_service();
echo '<img url="'.$url.'" />';

表示する画像が100個ある場合を除いて、すべて正常に機能しており、Webサービスの呼び出しに時間とリソースがかかります。

//the problem
foreach($items as $item) {
   $url = get_from_web_service($item);
   echo '<img url="'.$url.'" />';
}

だから今、私は2つのオプションを検討しています:

//Option1: Using php get_file_contents():
foreach($items as $item)
{
   echo '<img url="url_to_my_website/get_image.php?id='.$item->id.'" />'
}

get_image.php :

$url = get_from_web_service($id);
header("Content-Type: image/png");
echo file_get_contents($url);


//Option2: Using ajax:

echo '<img scr="dummy_image_or_website_logo" data-id="123" />';

//ajax call to the web service to get the id=123 and get the url then add the src attribute to that image.

考え

  1. 最初のオプションはより単純に思えますが、サーバーが過負荷になり、すべての画像リクエストに関与する可能性があります。
  2. 2番目のオプションは、すべてブラウザとWebサービスによって行われるため、サーバーはまったく関与しません。しかし、画像ごとに、画像のURLを取得するための1つのajax呼び出しと、画像を取得するための別の2つの呼び出しを行っています。そのため、読み込み時間が異なり、多数の呼び出しで ajax 呼び出しが失敗する可能性があります。

情報

  1. そのページには約50枚の画像が表示されます。
  2. このサービスは、一時に約 100 人のユーザーによって利用されます。
  3. Web サービスを制御できないため、その機能を変更することはできず、呼び出しごとに複数のイメージ ID を受け入れません。

私の質問

  1. 検討すべきより良いオプションはありますか?
  2. そうでない場合、どのオプションに従う必要がありますか? そして最も重要なのは、なぜ私はそれに従う必要があるのですか?

ありがとう

4

9 に答える 9

2

Web サービスからフェッチしている画像が本質的に動的ではない場合、つまり頻繁に変更/変更されない場合は、サーバーでスケジュールされたプロセス/cron ジョブをセットアップして、Web サービスから画像を取得し、ローカルに保存することをお勧めします (サーバー自体)、そのため、サーバーからのみ Web ページに画像を表示でき、Web ページがエンド ユーザーに提供されるたびにサード パーティ サーバーのラウンド トリップを回避できます。

于 2013-09-09T16:30:35.760 に答える
1

2 つのオプションはどちらも問題を解決できず、さらに悪化させる可能性があります。

オプション 1 の場合:

最も時間がかかるプロセスは " get_from_web_service($item)" であり、コードは別のスクリプトによって実行されるだけです (ファイル " get_image.php" が同じサーバーで実行される場合)。

オプション 2 の場合:

「get-image-resource-request」がブラウザによってトリガーされるだけですが、サーバーも「get_from_web_service($item)」を処理する必要があります。

1 つ明確にしなければならないことは、問題は get_from_web_service のパフォーマンスに関するものであることです。最も率直な提案は、パフォーマンスを向上させることです。一方、同時接続数を減らすこともできます。私はこれを熟考していません.2つの提案しかありません:

  1. Asynchronous : ユーザーはページ全体を閲覧せず、上部のページにのみ気づきます。上記の画像がすべて上部に表示されない場合は、jquery.lazyload 拡張機能を使用できます。これにより、非表示領域の画像リソースが表示されるまでサーバーに要求しないようにすることができます。

  2. CSS スプライト: イメージ スプライトは、1 つのイメージにまとめられたイメージのコレクションです。ページ上の画像の頻度が変わらない場合は、それらを毎日マージするコードを記述できます。

  3. 画像のキャッシュ: サーバーまたは別のサーバー (より良い) で画像をキャッシュできます。そして、いくつかのキー -> 値の作業を行います。キーは $item に関するもので、値はリソース ディレクトリ (url) です。

私は英語のネイティブ スピーカーではありません。

于 2013-09-05T09:54:14.133 に答える
0

2 つのオプションのいずれも、サーバー リソースの使用の問題を解決しません。ただし、2 つのうち、オプション 1 をお勧めします。2 つ目は、ページの読み込みが遅くなり、Web サイトの速度が遅くなり、SEO 評価が低下します。

あなたにとって最良の選択肢は次のようなものです:

foreach($items as $item) {
    echo '<img url="url_to_my_website/get_image.php?id='.$item->id.'" />'
}

そして魔法が起こるのはget_image.phpです:

if(file_exists('/path_to_local_storage/image_'.$id.'.png')) {
    $url = '/path_to_images_webfolder/image_'.$id.'.png';
    $img = file_get_contents($url);
} else {
    $url = get_from_web_service($id);
    $img = file_get_contents($url);
    $imgname = end(explode('/', $url));
    file_put_contents($imgname, $img);
}

header("Content-Type: image/png");
echo $img;

これは、Web サービスへの要求をイメージごとに 1 回だけ実行し、それをローカル スペースに保存するというものでした。次回画像がリクエストされたとき - Web サービスへのリクエストをスキップして、ローカル スペースから画像を提供します。

もちろん、イメージ ID が一意で永続的であることを考慮してください。

おそらく最善の解決策ではありませんが、あなたにとってはうまくいくはずです。

于 2013-09-10T13:53:47.097 に答える
0

オプション 3: Web サービスへの要求をキャッシュする

于 2013-09-06T21:13:17.980 に答える
0

上記のように、<img>tagsrc属性に画像を提供する Web サービスへの URL を含めているので、これらの URL は秘密でも機密でもないと考えて間違いありません。

上記のことを知っていれば、 からの次のスニペットは、get_image.php可能な限り最小限のオーバーヘッドで動作します。

$url = get_from_web_service($id);
header("Location: $url");

特定のクライアントから同じリクエストを大量にid受け取る場合、ブラウザの内部キャッシュを活用することで、リクエストの数をいくらか減らすことができます。

header("Cache-Control: private, max-age=$seconds");
header("Expires: ".gmdate('r', time()+$seconds));

それ以外の場合は、次のような Memcached、データベース、またはプレーン ファイルによるサーバー側のキャッシュに頼ります。

is_dir('cache') or mkdir('cache');
$cachedDataFile = "cache/$id";
$cacheExpiryDelay = 3600; // an hour

if (is_file($cachedDataFile) && filesize($cachedDataFile) 
     && filemtime($cachedDataFile) + $cacheExpiryDelay > time()) {
    $url = file_get_contents($cachedDataFile);
} else {
    $url = get_from_web_service($id);
    file_put_contents($cachedDataFile, $url,  LOCK_EX);
}

header("Cache-Control: private, max-age=$cacheExpiryDelay");
header("Expires: ".gmdate('r', time() + $cacheExpiryDelay));
header("Location: $url");
于 2013-09-12T00:56:01.130 に答える