javascript - 最初にサーバーで画像を生成する必要がある場合、画像をブラウザーのキャッシュに非同期でプリロードします。

原文 javascript jquery ajax asynchronous preloading

スタックオーバーフローを数年読んでいますが、投稿されていません。今日まで-私は自分で解決できず、解決策を見つけることができない問題に遭遇しました。

シナリオ:基本的にWebサイトのスクリーンショットを表示する動的Webページがあります。これらのスクリーンショットは、すべての新しいユーザーとそのURLが変更されるたびにオンザフライで生成されます。これらの画像をブラウザーのキャッシュにプリロードして、ユーザーがリンクをクリックすると0ミリ秒後に使用できるようにします。ページの主観的な読み込み時間を増やしたくないので、バックグラウンドで目に見えないように読み込む必要があります。

私のアプローチ:
インフラストラクチャとしてjelasticを使用して後で拡張できるようにし、nginx、PHP、およびPhantomJSを使用してcentOSをインストールしました。 PHPを使用してphantomJSをクエリし、スクリーンショットを作成します。


exec( "phantomjs engine.js"。$ source。 ""。$ filez。 "> / dev / null&");


dev / nullは、ユーザーへのロード時間を増加させないために使用されます。
リンクをブラウザに出力します。これまでのところ機能します。次に、これらの画像をプリロードします。

for (var i = 0; i < document.links.length; i++) {   
    imgArray[i] = new Image(1,1);
    imgArray[i].visibility = 'hidden';
    imgArray[i].src = (document.links[i].href.substr(7) + ".png");              
    document.links[i].href = 'javascript: showtouser("' + imgArray[i].src.substr(7) + '");';
}


ここで私が間違いを犯した2つのこと:


サーバーで画像が生成される前に、画像のプリロードを開始します。 phantomJSによって画像が生成された後にのみ、キャッシュを開始する方法が見つかりませんでした。 Onloadイベントは明らかにここでは機能しません。
私のアプローチは実際には非同期ではなく、ユーザーが感じる主観的な読み込み時間が増えると思います


何が悪いのですか?私はISPの人です、私はjavascriptを吸う:/
答え
あなたはアプローチが非同期でした。必要なのは、読み込まれなかった画像を特定して再試行するメカニズムです。

このスクリプトは画像をプリロードし、失敗した場合は再試行し、再試行後も存在しない画像のリンクを非表示にします(demo)。

var links = Array.prototype.slice.call(document.links, 0); // Converting links to a normal array

links.forEach(prepareImageLink);

function prepareImageLink(link) {
    var retries = 3; // current image number of retries
    var image = new Image();

    /** option: hide all links then reveal those with preloaded image
    link.style.visibility = 'hidden'; 

    image.onload = function() {
        link.style.visibility = '';
    };
    **/

    image.onerror = function() {
        if(retries === 0) {
            link.style.visibility = 'hidden'; // hide the link if image doesn't exist
           //link.remove(); // option - remove the link if image doesn't exist
            return;
        }

        retries--;

        setTimeout(function() {
            image.src = image.src + '?' + Date.now(); // for image to reload by adding the current dateTime to url
        }, 1000); // the amount of time to wait before retry, change it to fit you're system

    };

    image.src = (link.href + ".png"); // add .substr(7) in your case

    /** This is instead of 'javascript: showtouser("' + imgArray[i].src.substr(7) + '");'; which won't work on some browsers **/

    link.addEventListener('mouseover', function() {
        document.getElementById('image').src = image.src; // change to your showtouser func
    });
}
関連記事

javascript - ページネーションの「前へ」および「次へ」エラー

javascript - WebGL v.sでパレットベースのグラフィックスをエミュレートします。キャンバス2D

javascript - パブリックJSファイルでExpress res.renderを介して送信されたJSONを使用する方法

javascript - Railsとリモートデータ読み込みを使用したSelectize.js –配列の代わりにカンマ区切りの文字列を返す

javascript - JavaScriptのJavaScriptパーサー[終了]

javascript - スティッキーヘッダーが存在するときにドロップダウン「キャレット」を非表示にする

javascript - jqueryでdivを複製し、コードとして表示する

javascript - 1つの列のみに画像を表示する角度組積造ディレクティブ

javascript - 'require(…)'は一般的なJavaScriptパターンまたはライブラリ関数ですか?

javascript - カスタムJSFコンポーネントがAJAXによる更新を受け取った後にカスタムJavaScriptコードを呼び出す