これを軽減するために、私が見るいくつかのオプションがあります。
retina.js の HTTP 呼び出し結果のキャッシュを強化して保持する
「1x」バージョンをスワップアウトするように設定されている任意の「2x」イメージについて、retina.js は最初にXMLHttpRequest
リクエストを介してイメージの可用性を確認します。応答が成功したパスは配列にキャッシュされ、イメージがダウンロードされます。
次の変更により、効率が向上する場合があります。
失敗しXMLHttpRequest
た検証試行はキャッシュできます: 現在、「2x」パス検証試行は、以前に成功した場合にのみスキップされます。したがって、失敗した試行が繰り返される可能性があります。実際には、ページが最初にロードされるときに検証プロセスが行われるため、これはあまり問題になりません。ただし、結果が保持されている場合は、失敗を追跡することで 404 エラーの再発を防ぐことができます。
Persist '2x' path validation results in localStorage
: 初期化中に、retina.js はlocalStorage
結果キャッシュをチェックできます。見つかった場合は、既に検出された「2x」イメージの検証プロセスをバイパスして、「2x」イメージをダウンロードまたはスキップできます。新たに検出された「2x」画像パスを検証して、結果をキャッシュに追加できます。が利用可能である間、理論的にlocalStorage
は、404 はブラウザごとに画像に対して 1 回だけ発生します。これは、ドメイン上の任意のページのページ全体に適用されます。
これが簡単なワークアップです。おそらく有効期限機能を追加する必要があります。
https://gist.github.com/4343101/revisions
HTTP リダイレクト ヘッダーを採用する
「サーバー側」の問題についての私の把握は、せいぜいむらがあることに注意する必要があります。このFWIWを受け取ってください
@2x
もう 1 つのオプションは、文字が含まれていて存在しない画像要求に対して、サーバーがリダイレクト コードで応答することです。この関連する回答を参照してください。
特に:
画像をリダイレクトし、それらがキャッシュ可能である場合は、HTTP Expires ヘッダー (および適切な Cache-Control ヘッダー) を遠い将来の日付に設定するのが理想的です。これにより、少なくともそのページへのその後のアクセスでは、ユーザーは持っていません。リダイレクトを再度実行します。
リダイレクト応答を使用すると、404 が取り除かれ、ブラウザは存在しない「2x」画像パスにアクセスする後続の試行をスキップします。
retina.js をより選択的にすることができます
retinajs を変更して、一部の画像を考慮から除外することができます。
これに関連するプルリクエスト: https://github.com/imulus/retinajs/commit/e7930be
プル リクエストに<img>
よると、タグ名で要素を検索する代わりに、CSS セレクターを使用できます。これは、retina.js の構成可能なオプションの 1 つです。ユーザーがアップロードした画像 (および「2x」バリアントが存在しないと予想されるその他の画像) を除外する CSS セレクターを作成できます。
もう 1 つの可能性は、構成可能なオプションにフィルター機能を追加することです。この関数は、一致した<img>
要素ごとに呼び出すことができます。areturn true
は '2x' バリアントをダウンロードさせ、それ以外のものは<img>
スキップさせます。
基本的なデフォルト構成は、現在のバージョンから次のように変更されます。
var config = {
check_mime_type: true,
retinaImgTagSelector: 'img',
retinaImgFilterFunc: undefined
};
Retina.init()
関数は現在のバージョンから次のように変更されます。
Retina.init = function(context) {
if (context == null) context = root;
var existing_onload = context.onload || new Function;
context.onload = function() {
// uses new query selector
var images = document.querySelectorAll(config.retinaImgTagSelector),
retinaImages = [], i, image, filter;
// if there is a filter, check each image
if (typeof config.retinaImgFilterFunc === 'function') {
filter = config.retinaImgFilterFunc;
for (i = 0; i < images.length; i++) {
image = images[i];
if (filter(image)) {
retinaImages.push(new RetinaImage(image));
}
}
} else {
for (i = 0; i < images.length; i++) {
image = images[i];
retinaImages.push(new RetinaImage(image));
}
}
existing_onload();
}
};
それを実践するには、window.onload
火災の前に次のように呼び出します。
window.Retina.configure({
// use a class 'no-retina' to prevent retinajs
// from checking for a retina version
retinaImgTagSelector : 'img:not(.no-retina)',
// or, assuming there is a data-owner attribute
// which indicates the user that uploaded the image:
// retinaImgTagSelector : 'img:not([data-owner])',
// or set a filter function that will exclude images that have
// the current user's id in their path, (assuming there is a
// variable userId in the global scope)
retinaImgFilterFunc: function(img) {
return img.src.indexOf(window.userId) < 0;
}
});
更新: クリーンアップおよび再編成。localStorage
強化を追加しました。