머리말
ImagePool은 이미지 로딩을 관리하기위한 JS 도구입니다. ImagePool은 동시 이미지 로딩의 수를 제어 할 수 있습니다.
사진 로딩의 경우 가장 원시적 인 방법은 <img src = "image url" />와 같은 IMG 태그를 직접 작성하는 것입니다.
연속 최적화 후 이미지 지연 로딩 체계가 나타났습니다. 이번에는 이미지의 URL이 SRC 속성에 직접 쓰여지지 않고 다음과 같은 특정 속성에 다음과 같은 특정 속성으로 작성됩니다. 이러한 방식으로 브라우저는 사진을 자동으로로드하지 않습니다. 적절한 시간이 필요한 경우 JS를 사용하여 Data-SRC 속성의 URL을 IMG 태그의 SRC 속성에 넣거나 URL을 읽은 후 JS를 사용하여 그림을로드하고로드 후 SRC 속성을 설정하고 그림을 표시하십시오.
이것은 잘 통제되는 것처럼 보이지만 여전히 문제가있을 것입니다.
그림의 일부만 으로드 할 수 있지만 그림 의이 부분은 여전히 비교적 큰 순서 일 수 있습니다.
이것은 PC 쪽에서 큰 문제는 아니지만 모바일 측면의 경우 너무 많은 동시 이미지가로드되어 응용 프로그램 충돌이 발생할 가능성이 높습니다.
따라서 이미지 로딩 동시성을 제어하려면 이미지 버퍼링 메커니즘이 시급히 필요합니다. 백엔드 데이터베이스 연결 풀과 유사하게 연결되지 않으며 각 연결을 완전히 재사용 할 수 있습니다.
이 시점에서 ImagePool이 태어났습니다.
불량 회로도
사용 지침
먼저 연결 풀을 초기화하십시오.
var imagepool = initimagepool (5);
InitimagePool은 어디서나 직접 사용할 수있는 글로벌 방법입니다. 기능은 연결 풀을 만드는 것이며 연결 풀에 최대 연결 수를 지정할 수 있습니다. 선택적으로 기본값은 5입니다.
같은 페이지에서 initimagepool에 대한 여러 호출은 동일한 코어 인스턴스를 반환합니다. 이는 항상 첫 번째 싱글 톤 느낌으로 첫 번째입니다. 예를 들어:
코드 사본은 다음과 같습니다.
var imagepool1 = initimagepool (3);
var imagepool2 = initimagepool (7);
현재 ImagePool1과 ImagePool2 사이의 최대 연결 수는 3이며 동일한 코어 인스턴스가 내부적으로 사용됩니다. 내부 코어는 ImagePool1 === ImagePool2가 아니라 동일합니다.
초기화 후에는 자신감으로 사진을로드 할 수 있습니다.
가장 쉬운 호출 방법은 다음과 같습니다.
코드 사본은 다음과 같습니다.
var imagepool = initimagepool (10);
imagePool.load ( "Image URL", {
성공 : 기능 (SRC) {
Console.log ( "성공 :::::"+SRC);
},
오류 : 함수 (src) {
Console.log ( "오류 ::::"+SRC);
}
});
인스턴스에서로드 메소드를 호출하십시오.
로드 방법에는 두 개의 매개 변수가 있습니다. 첫 번째 매개 변수는로드 해야하는 이미지 URL이며, 두 번째 매개 변수는 성공 및 실패한 콜백을 포함한 다양한 옵션입니다. 이미지 URL은 콜백 중에 전달됩니다.
이런 식으로 하나의 사진 만 전달할 수 있으므로 다음 형식으로도 쓸 수도 있습니다.
코드 사본은 다음과 같습니다.
var imagepool = initimagepool (10);
imagePool.load ([ "image 1url", "image 2url"], {
성공 : 기능 (SRC) {
Console.log ( "성공 :::::"+SRC);
},
오류 : 함수 (src) {
Console.log ( "오류 ::::"+SRC);
}
});
이미지 URL 배열을 전달하면 여러 이미지를 전달할 수 있습니다.
각 이미지가 성공적으로로드되거나 실패하면 성공 (또는 오류) 메소드가 호출되고 해당 이미지 URL이 전달됩니다.
그러나 때때로 우리는 이런 식으로 자주 콜백을 할 필요가 없습니다. 이미지 URL 배열을 전달하십시오. 이 배열의 모든 이미지가 처리되면 콜백으로 충분합니다.
하나의 옵션 만 추가하십시오.
코드 사본은 다음과 같습니다.
var imagepool = initimagepool (10);
imagePool.load ([ "image 1url", "image 2url"], {
성공 : 기능 (Sarray, Earray, Count) {
Console.log ( "Sarray ::::"+Sarray);
Console.log ( "Earray ::::"+Earray);
Console.log ( "count :::::"+count);
},
오류 : 함수 (src) {
Console.log ( "오류 ::::"+SRC);
},
한 번 : 사실
});
옵션에 한 번 속성을 추가하고 True로 설정하면 콜백 만 한 번만 달성 할 수 있습니다.
이번에는 성공 방법을 다시 호출해야하며 현재 오류 메소드는 무시됩니다.
현재 콜백 성공 방법은 더 이상 이미지 URL 매개 변수를 전달하지 않고 성공적인 URL 배열, 실패한 URL 배열 및 처리 된 총 이미지 수를 전달합니다.
또한 연결 풀의 내부 상태를 얻는 방법이 있습니다.
코드 사본은 다음과 같습니다.
var imagepool = initimagepool (10);
console.log (imagePool.info ());
정보 메소드를 호출하면 현재 시간에 연결 풀의 내부 상태를 얻을 수 있으며 데이터 구조는 다음과 같습니다.
Object.task. 연결 풀에서 처리를 기다리는 작업 수 수수
Object.thread. 연결 풀에 최대 연결 수를 수수하십시오.
Object.thread. 연결 풀에 대한 무료 연결 수입니다
이 방법을 자주 호출하지 않는 것이 좋습니다.
마지막으로 이미지가로드되지 않으면 최대 3 번 시도합니다. 결국 이미지가로드되지 않으면 오류 메소드가 다시 호출됩니다. 소스 코드에서 시도 횟수를 수정할 수 있습니다.
마지막으로, 독자가 과도한 동시성에 대해 걱정하지 않고 이미지가 연결 풀에 이미지를 밀어 넣을 수 있음을 강조하겠습니다. ImagePool은 이러한 이미지를 혼란스럽게로드하는 데 도움이됩니다.
마지막으로 ImagePool은 이론적으로 이미지 로딩 속도를 줄이지 않고 부드러운 로딩 일뿐입니다.
소스 코드
코드 사본은 다음과 같습니다.
(기능 (수출) {
//하나의
var instance = null;
vally emptyfn = function () {};
// 초기 기본 구성
var config_default = {
// 스레드 풀의 "스레드"의 수입니다
글타래 (쓰레드) : 5,
// 재시도 수가 사진을로드하지 못했습니다
// 두 번 시도하고 원본을 추가, 총 3 번 추가하십시오.
"시도": 2
};
//도구
var _helpers = {
// DOM 속성을 설정합니다
setattr : (function () {
var img = new Image ();
// 브라우저가 HTML5 데이터 세트를 지원하는지 판단합니다
if (img.dataset) {
반환 함수 (dom, name, value) {
dom.dataset [name] = value;
반환 값;
};
}또 다른{
반환 함수 (dom, name, value) {
dom.setattribute ( "data-"+이름, 값);
반환 값;
};
}
} ()),
// dom 속성을 가져옵니다
getAttr : (function () {
var img = new Image ();
// 브라우저가 HTML5 데이터 세트를 지원하는지 판단합니다
if (img.dataset) {
반환 함수 (dom, name) {
반환 dom.dataset [이름];
};
}또 다른{
반환 함수 (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 : "", 옵션 : {success : "fn", 오류 : "fn", 일단 : true}, try : 0}
this.pool = [];
}
/**
* 초기화
*/
imagepool.prototype.initpool = function () {
var i, img, obj, _s;
_s = 이것;
for (i = 0; i <this.max; i ++) {
obj = {};
img = 새로운 이미지 ();
_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), "성공", 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. NONTICE (노드, "오류", this.src);
}
// 작업 처리
_s.ExecutElink (this);
};
obj.img = img;
obj.free = true;
this.pool.push (obj);
}
};
/**
* 콜백 캡슐화
* @param 노드 노드. 물체.
* @param 상태 상태. 끈. 선택적 가치 : 성공 | 오류 (실패)
* @Param SRC 이미지 경로. 끈.
*/
imagepool.prototype.notice = function (노드, 상태, SRC) {
node.notice (상태, 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];
}
}
널 리턴;
};
/**
* SRC 속성 설정을 캡슐화합니다
* SRC 속성을 변경하는 것은 그림을로드하는 것과 동일하기 때문에 작업을 캡슐화하십시오.
* @param dom image dom 객체. 물체.
* @param 노드 노드. 물체.
*/
im
// 수영장의 "스레드"를 비 이들로 설정합니다
this.status (dom, false);
// 제휴 노드
this.setNode (dom, node);
// 사진을로드합니다
dom.src = node.src;
};
/**
* 풀에서 "스레드"상태를 업데이트하십시오
* @param dom image dom 객체. 물체.
* @param 상태 상태. 부울. 선택적 값 : true (유휴) | 거짓 (비 이들)
*/
imagepool.prototype.status = function (dom, status) {
var id = _helpers.getAttr (dom, "id");
this.pool [id] .free = 상태;
// 유휴 상태, 연관된 노드를 지우십시오
if (상태) {
this.pool [id] .node = null;
}
};
/**
* 풀에서 "스레드"의 관련 노드 업데이트
* @param dom image dom 객체. 물체.
* @param 노드 노드. 물체.
*/
im
var id = _helpers.getAttr (dom, "id");
this.pool [id] .node = 노드;
this.pool [id] .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 옵션 사용자 정의 매개 변수. 포함 : 성공 콜백, 오류 콜백, 한 번 태그.
*/
imagePool.Prototype.load = function (src, 옵션) {
var srcs = [],
free = null,
길이 = 0,
i = 0,
// 콜백 전략을 한 번만 초기화합니다
통지 = (function () {
if (Options.once) {
반환 함수 (상태, SRC) {
var g = this.group,
o = this.options;
//기록
g [상태] .push (src);
// 모든 재구성이 처리되었는지 여부를 식별하십시오
if (g.success.length + g.error.length === g.count) {
// 비동기식
// 실제로 콜백 기능이 너무 길어지고 이미지로드 속도에 영향을 미치는 것을 방지하기 위해 다른 작업으로 별도로 실행됩니다.
settimeout (function () {
O.SUCCESS.CALL (NULL, G.SUCCESS, G.ERROR, G.COUNT);
}, 1);
}
};
}또 다른{
반환 함수 (상태, SRC) {
var o = this.options;
// 직접 콜백
settimeout (function () {
o [상태] .call (null, src);
}, 1);
};
}
} ()),
그룹 = {
수 : 0,
성공: [],
오류 : []
},
노드 = null;
옵션 = 옵션 || {};
옵션 .success = 옵션 .success || 빈도;
옵션 .ERROR = 옵션 .ERROR || 빈도;
srcs = srcs.concat (src);
// 그룹 요소 수를 설정합니다
group.count = srcs.length;
//로드 해야하는 그림을 여행합니다
for (i = 0, 길이 = srcs.length; i <length; i ++) {
// 노드를 만듭니다
노드 = this.createNode (srcs [i], 옵션, 통지, 그룹);
// 스레드 풀이 무료인지 판단합니다
free = this.getFree ();
if (무료) {
// 자유 시간이 있으면 즉시 사진을로드하십시오
this.setsrc (free.img, 노드);
}또 다른{
// 유휴 상태가 없으면 링크 된 목록에 작업을 추가하십시오
이. AppendNode (노드);
}
}
};
/**
* 내부 상태 정보를 얻습니다
* @returns {{}}
*/
imagepool.prototype.info = function () {
var info = {},
길이 = 0,
i = 0,
노드 = 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;
}
}
// 작업 수를 얻습니다 (작업 체인 길이)
노드 = this.linkhead;
if (노드) {
info.task.count = info.task.count + 1;
while (node.next) {
info.task.count = info.task.count + 1;
node = node.next;
}
}
반품 정보;
};
/**
* 노드를 만듭니다
* @Param SRC 이미지 경로. 끈.
* @param 옵션 사용자 정의 매개 변수. 포함 : 성공 콜백, 오류 콜백, 한 번 태그.
* @param 통지 콜백 전략. 기능.
* @param 그룹 그룹 정보. 물체. {count : 0, 성공 : [], 오류 : []}
* @param tr 레트리 오류 수. 값. 기본값은 0입니다.
* @returns {{}}
*/
ImagePool.Prototype.createNode = function (SRC, 옵션, 통지, 그룹, tr) {
var 노드 = {};
node.src = src;
node.options = 옵션;
node.notice = 통지;
node.group = 그룹;
node.try = tr || 0;
리턴 노드;
};
/**
* 작업 목록 끝으로 노드를 추가하십시오.
* @param 노드 노드. 물체.
*/
im
// 링크 된 목록이 비어 있는지 판단합니다
if (! this.linkhead) {
this.linkhead = 노드;
this.linknode = 노드;
}또 다른{
this.linknode.next = 노드;
this.linknode = 노드;
}
};
/**
* 링크의 헤더를 삭제합니다
*/
imagepool.prototype.shiftnode = function () {
// 링크 된 목록에 노드가 있는지 식별합니다
if (this.linkhead) {
// 링크 목록 헤더를 수정합니다
this.linkhead = this.linkhead.next || 널;
}
};
/**
* 외부 인터페이스를 내 보냅니다
* @param max 최대 연결 수. 값.
* @returns {{load : function, info : function}}
*/
Exports.initimagePool = function (max) {
if (! 인스턴스) {
인스턴스 = 새로운 ImagePool (max);
instance.initpool ();
}
반품 {
/**
* 사진로드
*/
로드 : function () {
instance.load.Apply (인스턴스, 인수);
},
/**
* 내부 정보
* @returns {* | any | void}
*/
정보 : function () {
return instance.info.call (인스턴스);
}
};
};
}(이것));
위는이 멋진 JavaScript 프론트 엔드 이미지 로딩 관리자를 사용하는 방법의 예입니다. 사용 방법을 배웠습니까?