序文
ImagePoolは、画像の読み込みを管理するためのJSツールです。 ImagePoolは、同時の画像負荷の数を制御できます。
画像の読み込みの場合、最も原始的な方法は、次のようなIMGタグを直接記述することです。
継続的な最適化の後、画像遅延ロードスキームが表示されました。今回は、画像のURLはSRC属性に直接記述されるのではなく、次のような特定の属性に書かれています。このようにして、ブラウザは画像を自動的にロードしません。適切な時間が必要な場合は、JSを使用してURLをData-SRC属性にIMGタグのSRC属性に配置するか、URLを読み取り、JSを使用して画像をロードし、ロード後にSRC属性を設定し、画像を表示します。
これは十分に制御されているようですが、まだ問題があります。
写真の一部しかロードできませんが、写真のこの部分はまだ比較的大きな大きさである可能性があります。
これはPC側にとっては大したことではありませんが、モバイル面では、あまりにも多くの同時画像がロードされているため、アプリケーションがクラッシュする可能性が非常に高くなります。
したがって、画像の負荷の並行性を制御するための画像バッファリングメカニズムが緊急に必要です。バックエンドデータベース接続プールと同様に、あまりにも多くの接続を作成することはなく、各接続を完全に再利用できます。
この時点で、ImagePoolが生まれました。
悪い概略図
使用する手順
まず、接続プールを初期化します。
var imagepool = initimagepool(5);
initimagepoolは、どこでも直接使用できるグローバルな方法です。関数は接続プールを作成することであり、接続プールへの接続の最大数を指定できます。オプションでは、デフォルトは5です。
同じページでは、InityMagePoolへの複数の呼び出しが同じコアインスタンスを返します。これは常に最初のインスタンスであり、シングルトンの気持ちが少しあります。例えば:
コードコピーは次のとおりです。
var imagepool1 = initimagepool(3);
var imagepool2 = initimagepool(7);
現時点では、ImagePool1とImagePool2の間の接続の最大数は3で、同じコアインスタンスが内部で使用されています。 ImagePool1 === ImagePool2ではなく、内部コアは同じであることに注意してください。
初期化後、自信を持って画像をロードできます。
コールする最も簡単な方法は次のとおりです。
コードコピーは次のとおりです。
var imagepool = initimagepool(10);
ImagePool.Load( "Image URL"、{
成功:function(src){
console.log( "成功::::::"+src);
}、
エラー:function(src){
console.log( "error ::::"+src);
}
});
インスタンスのロードメソッドを呼び出すだけです。
負荷方法には2つのパラメーターがあります。最初のパラメーターは、ロードする必要がある画像URLであり、2番目のパラメーターは、成功したコールバックや失敗したコールバックを含むさまざまなオプションです。画像URLは、コールバック中に渡されます。
これにより、1つの写真のみを渡すことができるため、次の形式で書くこともできます。
コードコピーは次のとおりです。
var imagepool = initimagepool(10);
ImagePool.Load(["Image 1Url"、 "Image 2url"]、{
成功:function(src){
console.log( "成功::::::"+src);
}、
エラー:function(src){
console.log( "error ::::"+src);
}
});
画像URL配列を渡すことにより、複数の画像を渡すことができます。
各画像が正常にロードされる(または失敗)すると、成功(またはエラー)メソッドが呼び出され、対応する画像URLが渡されます。
しかし、このようなコールバックを頻繁にコールバックする必要がない場合があります。画像URL配列を渡します。この配列内のすべての画像が処理されると、コールバックで十分です。
1つのオプションを追加するだけです。
コードコピーは次のとおりです。
var imagepool = initimagepool(10);
ImagePool.Load(["Image 1Url"、 "Image 2url"]、{
成功:function(sarray、earray、count){
console.log( "sarray ::::"+sarray);
console.log( "Earray ::::"+Earray);
console.log( "count :::::"+count);
}、
エラー:function(src){
console.log( "error ::::"+src);
}、
一度:true
});
オプションに一度属性を追加し、それをtrueに設定することにより、コールバックを1回しか達成できません。
今回は、成功方法を呼び戻す必要があり、この時点でエラー方法は無視されます。
現時点では、コールバック成功方法は画像URLパラメーターを渡すのではなく、3つのパラメーターを渡します。つまり、URL配列の成功、URL配列の失敗、および処理された画像の総数です。
さらに、接続プールの内部状態を取得する方法があります。
コードコピーは次のとおりです。
var imagepool = initimagepool(10);
console.log(imagepool.info());
情報方法を呼び出すことにより、現在の時刻に接続プールの内部状態を取得でき、データ構造は次のとおりです。
object.task.count接続プールでの処理を待っているタスクの数
object.thread.count接続プールへの接続の最大数
object.thread.無料接続の数の接続プールへの無料接続
この方法を頻繁に呼び出さないことをお勧めします。
最後に、画像がロードに失敗した場合、最大3回試行することに注意する必要があります。画像が最終的に読み込まれない場合、エラーメソッドが呼び出されます。試行回数はソースコードで変更できます。
最後に、読者は過度の並行性を心配することなく、できる限り接続プールに画像を押し込むことができることを強調しましょう。 ImagePoolは、これらの画像を混乱にロードするのに役立ちます。
最後に、ImagePoolは理論的には画像の読み込み速度を低下させないことに注意する必要があります。これは単なるスムーズな負荷です。
ソースコード
コードコピーは次のとおりです。
(function(exports){
//シングル
var instance = null;
var emptyfn = function(){};
//初期デフォルト設定
var config_default = {
//スレッドプールの「スレッド」の数
スレッド:5、
// retryの数が画像のロードに失敗しました
// 2回試して、元のものを追加し、合計3回を追加します
「試してみてください」:2
};
//道具
var _helpers = {
// dom属性を設定します
setattr :( function(){
var img = new Image();
//ブラウザがHTML5データセットをサポートしているかどうかを判断します
if(img.dataset){
return function(dom、name、value){
dom.dataset [name] = value;
返品値。
};
}それ以外{
return function(dom、name、value){
dom.setattribute( "data-"+name、value);
返品値。
};
}
}())、
// dom属性を取得します
getattr :( function(){
var img = new Image();
//ブラウザがHTML5データセットをサポートしているかどうかを判断します
if(img.dataset){
return function(dom、name){
return dom.dataset [name];
};
}それ以外{
return function(dom、name){
return dom.getattribute( "data-"+name);
};
}
}())
};
/**
*構築方法
* @param max接続の最大数。価値。
*/
関数imagepool(max){
//並行性の最大数
this.max = max || config_default.thread;
this.linkhead = null;
this.linknode = null;
//プールのロード
// [{img:dom、free:true、node:node}]
//ノード
// {src: ""、options:{success: "fn"、error: "fn"、and:true}、try:0}
this.pool = [];
}
/**
*初期化
*/
ImagePool.prototype.initpool = function(){
var i、img、obj、_s;
_s = this;
for(i = 0; i <this.max; i ++){
obj = {};
img = new Image();
_helpers.setattr(img、 "id"、i);
img.onload = function(){
var id、src;
//折り返し電話
//_s.getNode(this ).options.success.call(null、this.src);
_s.notice(_s.getNode(this)、 "success"、this.src);
//タスクの処理
_s.executelink(this);
};
img.onerror = function(e){
var node = _s.getNode(this);
//試行回数を判断します
if(node.try <config_default.try){
node.try = node.try + 1;
//タスクリストの最後にもう一度追加します
_s.AppendNode(_s.CreatENode(node.src、node.options、node.notice、node.group、node.try));
}それ以外{
//コールバックをエラーします
//node.options.error.call(null、this.src);
_s.notice(node、 "error"、this.src);
}
//タスクの処理
_s.executelink(this);
};
obj.img = img;
obj.free = true;
this.pool.push(obj);
}
};
/**
*コールバックカプセル化
* @paramノードノード。物体。
* @paramステータスステータス。弦。オプションの値:成功|エラー(失敗)
* @param SRCイメージパス。弦。
*/
ImagePool.Prototype.Notice = function(node、status、src){
node.notice(status、src);
};
/**
*リンクリストタスクの処理
* @param dom image domオブジェクト。物体。
*/
ImagePool.prototype.executelink = function(dom){
//リンクリストにノードがあるかどうかを識別します
if(this.linkhead){
//次の画像をロードします
this.setsrc(dom、this.linkhead);
//リンクヘッダーを削除します
this.shiftnode();
}それ以外{
//独自のステータスをアイドル状態に設定します
this.status(dom、true);
}
};
/**
*アイドル「スレッド」を取得する
*/
ImagePool.prototype.getFree = function(){
varの長さ、i;
for(i = 0、length = this.pool.length; i <length; i ++){
if(this.pool [i] .free){
this.pool [i]を返します。
}
}
nullを返します。
};
/**
* SRC属性設定をカプセル化します
* SRC属性を変更することは画像の読み込みと同等であるため、操作をカプセル化する
* @param dom image domオブジェクト。物体。
* @paramノードノード。物体。
*/
ImagePool.prototype.setsrc = function(dom、node){
//プール内の「スレッド」を非アイドルに設定します
this.status(dom、false);
//関連ノード
this.setNode(dom、node);
//画像をロードします
dom.src = node.src;
};
/**
*プールの「スレッド」ステータスを更新します
* @param dom image domオブジェクト。物体。
* @paramステータスステータス。ブール。オプションの値:true(idle)| false(adlen)
*/
ImagePool.Prototype.Status = function(dom、status){
var id = _helpers.getattr(dom、 "id");
this.pool [id] .free = status;
//アイドル状態、関連するノードをクリアします
if(status){
this.pool [id] .node = null;
}
};
/**
*プール内の「スレッド」の関連ノードを更新します
* @param dom image domオブジェクト。物体。
* @paramノードノード。物体。
*/
ImagePool.prototype.setNode = function(dom、node){
var id = _helpers.getattr(dom、 "id");
this.pool [id] .node = node;
this.pool [id] .node === nodeを返します。
};
/**
*プール内の「スレッド」の関連ノードを取得します
* @param dom image domオブジェクト。物体。
*/
ImagePool.prototype.getNode = function(dom){
var id = _helpers.getattr(dom、 "id");
this.pool [id] .nodeを返します。
};
/**
*外部インターフェイス、ロード写真
* @Param SRCは、SRC文字列またはSRC文字列の配列にすることができます。
* @paramオプションユーザー定義パラメーター。含まれる:サクセスコールバック、エラーコールバック、1回のタグ。
*/
ImagePool.prototype.load = function(src、options){
var srcs = []、
free = null、
長さ= 0、
i = 0、
//コールバック戦略を一度初期化します
Notion =(function(){
if(option.once){
return function(status、src){
var g = this.group、
o = this.options;
//記録
g [status] .push(src);
//すべての再編成が処理されたかどうかを識別します
if(g.success.length + g.error.length === g.count){
//非同期
//実際には、コールバック関数が長すぎて画像の負荷速度に影響を与えるのを防ぐための別のタスクとして個別に実行されます
setimeout(function(){
o.success.call(null、g.success、g.error、g.count);
}、1);
}
};
}それ以外{
return function(status、src){
var o = this.options;
//ダイレクトコールバック
setimeout(function(){
o [status] .call(null、src);
}、1);
};
}
}())、
group = {
カウント:0、
成功: []、
エラー: []
}、
node = null;
オプション=オプション|| {};
options.success = options.success || emptyfn;
options.error = options.error || emptyfn;
srcs = srcs.concat(src);
//グループ要素の数を設定します
group.count = srcs.length;
//ロードする必要がある写真の上を移動します
for(i = 0、length = srcs.length; i <length; i ++){
//ノードを作成します
node = this.createNode(srcs [i]、options、nocation、group);
//スレッドプールが無料かどうかを判断します
free = this.getFree();
if(free){
//自由時間がある場合は、すぐに写真を読み込みます
this.setsrc(free.img、node);
}それ以外{
//アイドルなし、リンクリストにタスクを追加します
this.appendnode(node);
}
}
};
/**
*内部ステータス情報を取得します
* @returns {{}}
*/
ImagePool.prototype.info = function(){
var info = {}、
長さ= 0、
i = 0、
node = null;
//糸
info.thread = {};
//スレッドの総数
info.thread.count = this.pool.length;
//アイドルスレッドの数
info.thread.free = 0;
//タスク
info.task = {};
//保留中のタスクの数
info.task.count = 0;
//無料の「スレッド」の数を取得します
for(i = 0、length = this.pool.length; i <length; i ++){
if(this.pool [i] .free){
info.thread.free = info.thread.free + 1;
}
}
//タスクの数(タスクチェーンの長さ)を取得する
node = this.linkhead;
if(node){
info.task.count = info.task.count + 1;
while(node.next){
info.task.count = info.task.count + 1;
node = node.next;
}
}
情報を返す;
};
/**
*ノードを作成します
* @param SRCイメージパス。弦。
* @paramオプションユーザー定義パラメーター。含まれる:サクセスコールバック、エラーコールバック、1回のタグ。
* @param通知コールバック戦略。関数。
* @paramグループグループ情報。物体。 {count:0、success:[]、error:[]}
* @param Trの再生エラーの数。価値。デフォルトは0です。
* @returns {{}}
*/
ImagePool.prototype.createNode = function(src、options、nocation、group、tr){
var node = {};
node.src = src;
node.options = options;
node.notice = nocation;
node.group = group;
node.try = tr || 0;
ノードを返す;
};
/**
*タスクリストの最後にノードを追加します
* @paramノードノード。物体。
*/
ImagePool.Prototype.AppendNode = function(node){
//リンクされたリストが空であるかどうかを判断します
if(!this.linkhead){
this.linkhead = node;
this.linknode = node;
}それ以外{
this.linknode.next = node;
this.linknode = node;
}
};
/**
*リンクのヘッダーを削除します
*/
imagepool.prototype.shiftnode = function(){
//リンクリストにノードがあるかどうかを識別します
if(this.linkhead){
//リンクリストヘッダーを変更します
this.linkhead = this.linkhead.next ||ヌル;
}
};
/**
*外部インターフェイスをエクスポートします
* @param max接続の最大数。価値。
* @returns {{load:function、info:function}}
*/
Exports.InitimagePool = function(max){
if(!instance){
instance = new ImagePool(Max);
instance.initpool();
}
戻る {
/**
*写真の読み込み
*/
load:function(){
instance.load.apply(instance、arguments);
}、
/**
*内部情報
* @returns {* | any | void}
*/
情報:function(){
return instance.info.call(instance);
}
};
};
}(これ));
上記は、この特に素晴らしいJavaScriptのフロントエンド画像ロードマネージャーを使用する方法の例です。使用方法を学びましたか?