>  기사  >  웹 프론트엔드  >  JavaScript 이미지의 지연 로딩 및 사전 로딩 분석 요약

JavaScript 이미지의 지연 로딩 및 사전 로딩 분석 요약

高洛峰
高洛峰원래의
2016-12-08 15:17:161148검색

이 기사에서는 지연 로딩과 사전 로딩이라는 두 가지 기술에 대한 분석을 주로 소개합니다.

지연 로딩이라고도 합니다. 이전 기사에서 소개한 JS 이미지 지연 로딩 또는 특정 조건이 충족될 때만 특정 이미지를 로딩합니다.

미리 로드: 이미지를 미리 로드하고 사용자가 이미지를 확인해야 할 때 로컬 캐시에서 직접 렌더링합니다.

두 기술의 본질은 두 기술의 동작이 정반대라는 것입니다. 하나는 미리 로드되고, 다른 하나는 느리게 로드되거나 전혀 로드되지 않습니다. 지연 로딩은 서버 프런트엔드의 부담을 완화하는 데 일정한 효과가 있는 반면, 사전 로딩은 서버 프런트엔드의 부담을 증가시킵니다.

지연 로딩의 의미와 구현 방법은 다음과 같습니다.

의미: 지연 로딩의 주요 목적은 서버 프런트 엔드를 최적화하여 요청 수를 줄이거나 요청 수를 지연시키는 것입니다. .

구현 방법:

1. 첫 번째는 로딩 지연을 위해 setTimeOut 또는 setInterval을 사용하는 순수 지연 로딩입니다.

2. 특정 조건이나 특정 이벤트가 트리거될 때만 시작됩니다.

3. 세 번째 유형은 시각적 영역 로딩으로, 사용자가 볼 수 있는 영역만 로드하는 것을 의미합니다. 이는 주로 스크롤 막대를 모니터링하여 구현됩니다. 특정 사진을 로드하면 사용자가 사진을 아래로 당길 때 정확하게 볼 수 있습니다.

프리로드의 의미와 구현 방법은 다음과 같습니다.

프리로드는 더 나은 사용자 경험을 제공하는 대가로 서버의 프런트엔드 성능을 희생하여 사용자의 작업을 원활하게 하는 것을 의미한다고 할 수 있습니다. 최대한 빨리 반영하겠습니다. CSS(배경), JS(이미지), HTML(6ed09268cbdd0015bce8dcbbdfa9bfe4)을 포함하여 사전 로드를 구현하는 방법에는 여러 가지가 있습니다. 일반적으로 new Image();가 사용되며, src를 설정하여 사전 로드를 구현한 다음 onload 메서드를 사용하여 사전 로드 완료 이벤트를 콜백합니다. 브라우저가 이미지를 로컬로 다운로드하는 한 동일한 src가 캐시됩니다. 이는 가장 기본적이고 실용적인 사전 로드 방법입니다. Image가 이미지 헤더를 다운로드한 후 너비와 높이를 가져오므로 미리 로드하기 전에 이미지 크기를 가져올 수 있습니다(타이머를 사용하여 너비와 높이 변경을 순환하는 방법입니다).

사전 로딩을 어떻게 달성하나요?

Google을 통해 검색할 수 있습니다. 많은 사람들이 이 방법을 사용하여 미리 로드하는 것을 볼 수 있습니다. 코드는 다음과 같습니다.

function loadImage(url,callback) {
  var img = new Image();
   
  img.src = url;
  img.onload = function(){
    img.onload = null;
    callback.call(img);
  }
}

다른 브라우저는 정상인 이유 : 사실 이유는 매우 간단합니다. 즉, IE6을 제외한 브라우저 캐시입니다. 어쩌면 지금은 수정되었을 수도 있습니다.), 다른 브라우저는 다시 클릭하면 onload 메서드를 다시 실행하지만 IE6은 브라우저에서 직접 가져옵니다.

이제 무엇을 해야 할까요? 가장 좋은 경우는 이미지가 성공적으로 로드되었는지 여부를 나타내는 상태 값을 가질 수 있다는 것입니다. 캐시에서 로드할 때는 기다릴 필요가 없기 때문에 이 상태 값은 다운로드되었음을 직접 나타냅니다. http 요청에서 로드할 때는 다운로드를 기다려야 하기 때문에 이 값은 불완전으로 표시됩니다. 이 경우에는 가능합니다. Google에서 검색한 후 소개하겠습니다. 다양한 브라우저와 호환되는 Image 속성이 있음을 발견했습니다. 따라서 이미지 로딩 이벤트가 발생하기 전에 이 값을 판단하시기 바랍니다. 마지막으로 코드는 다음과 같습니다.

function loadImage(url,callback) {
  var img = new Image();
   
  img.src = url;
 
  if(img.complete) { // 如果图片已经存在于浏览器缓存,直接调用回调函数
     
    callback.call(img);
    return; // 直接返回,不用再处理onload事件
  }
 
  img.onload = function(){
    img.onload = null;
    callback.call(img);
  }
}

즉, 이미지가 이미 브라우저 캐시에 있는 경우 브라우저 캐시에서 직접 가져오는 것을 지원합니다. img.complete에서 함수를 실행한 다음 반환합니다.

그러나 위의 코드를 볼 수 있습니다. 이미지가 로드될 때까지 기다려야 하며 콜백 함수를 실행할 수도 있습니다. 이미지가 로드된 후에는 이미지 너비와 높이를 얻을 수 있습니다. 그렇다면 이미지의 크기를 미리 알고 싶다면 어떻게 해야 할까요? 인터넷 경험에 따르면 브라우저가 이미지를 로드할 때 이미지가 먼저 영역을 차지한 다음 천천히 로드되는 것을 볼 수 있습니다. 브라우저가 헤더 데이터를 얻을 수 있으므로 너비와 높이 속성을 미리 설정할 필요가 없습니다. 이미지. 이를 바탕으로 이미지 크기 준비 상태를 알기 위해서는 자바스크립트를 사용하여 이미지의 크기 상태를 정기적으로 감지하기만 하면 됩니다. 코드는 다음과 같습니다. (하지만 이 방법은 제가 생각한 것도 아니고, 제가 작성한 코드도 아니라는 전제가 있습니다. 온라인 친구들이 정리한 코드입니다. 그런 원리가 있다는 것만 알고 있습니다)

var imgReady = (function(){
  var list = [],
    intervalId = null;
 
  // 用来执行队列
  var queue = function(){
 
    for(var i = 0; i < list.length; i++){
      list[i].end ? list.splice(i--,1) : list[i]();
    }
    !list.length && stop();
  };
   
  // 停止所有定时器队列
  var stop = function(){
    clearInterval(intervalId);
    intervalId = null;
  }
  return function(url, ready, error) {
    var onready = {},
      width,
      height,
      newWidth,
      newHeight,
      img = new Image();
    img.src = url;
 
    // 如果图片被缓存,则直接返回缓存数据
    if(img.complete) {
      ready.call(img);
      return;
    }
    width = img.width;
    height = img.height;
 
    // 加载错误后的事件
    img.onerror = function () {
      error && error.call(img);
      onready.end = true;
      img = img.onload = img.onerror = null;
    };
 
    // 图片尺寸就绪
    var onready = function() {
      newWidth = img.width;
      newHeight = img.height;
      if (newWidth !== width || newHeight !== height ||
        // 如果图片已经在其他地方加载可使用面积检测
        newWidth * newHeight > 1024
      ) {
        ready.call(img);
        onready.end = true;
      };
    };
    onready();
    // 完全加载完毕的事件
    img.onload = function () {
      // onload在定时器时间差范围内可能比onready快
      // 这里进行检查并保证onready优先执行
      !onready.end && onready();
      // IE gif动画会循环执行onload,置空onload即可
      img = img.onload = img.onerror = null;
    };
     
     
    // 加入队列中定期执行
    if (!onready.end) {
      list.push(onready);
      // 无论何时只允许出现一个定时器,减少浏览器性能损耗
      if (intervalId === null) {
        intervalId = setInterval(queue, 40);
      };
    };
  }
})();

호출 방법은 다음과 같습니다.

imgReady(&#39;http://img01.taobaocdn.com/imgextra/i1/397746073/T2BDE8Xb0bXXXXXXXX-397746073.jpg&#39;,function(){
  alert(&#39;width:&#39; + this.width + &#39;height:&#39; + this.height);
});

위는 이 글 전체 내용


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.