• 이미지 미리 불러오기(image preload) :: 마이구미
    Javascript 2017. 12. 27. 20:12
    반응형

    이 글은 이미지를 미리 로딩하는 법에 대해 다룬다.

    흔히 이미지 프리로딩(Image Preloading) 이라고 불린다.

    참고 - https://www.photo-mark.com/notes/image-preloading/


    웹 사이트에는 많은 이미지가 존재한다.

    특히 갤러리 관련 페이지에는 더욱 많을 것이다.

    많은 자원을 통해 웹 페이지는 무거워질 수 밖에 없다.

    그에 대한 해결책으로 현재는 이미지의 크기, 질 등을 최소화하는 작업이 존재한다.


    다른 방법 중에는 preloading 이 존재한다.

    용어 그대로 이미지를 미리 로딩해놓는다는 의미가 된다.

    즉, preloading 은 미리 로딩하고 캐시로 가져오게 하는 방식이다.


    preloading 을 구현하는 방법은 여러가지가 존재한다.

    자바스크립트를 활용한 대표적인 방법은 다음과 같다.

    그 외에도 css, ajax 등 많은 방법이 있지만, 어렵지도 중요하지 않기에 다른 방식은 생략하겠다.


    function preloading (imageArray) { let n = imageArray.length; for (let i = 0; i < n; i++) { let img = new Image(); img.src = imageArray[i]; } } preloading([ '1.png', '2.png', '3.png' ])


    위 방식을 통해 각 이미지들을 가져올 수 있게 된다.


    preloading 병렬


    개발자 도구를 통해 확인해볼 수 있듯이 미리 로딩할 이미지들이 로드된 것을 볼 수 있다.

    거의 비슷한 시간에 모든 이미지들이 로딩이 시작된 것을 볼 수 있다.

    왜냐하면 비동기(async)로 동작하기 때문이다.


    우리의 목적은 미리 로딩하는 것이기 때문에 크게 신경쓰지 않을 것이다.

    하지만 우선순위가 높은 이미지가 보이지 않을 수도 있다.

    이러한 문제를 피하기 위해 preloading 을 적용했는데 무슨 말인지 의아할 수도 있다.


    위 개발자 도구의 그림을 다시 보면, 비동기적으로 인해 병렬적으로 처리되는 모습을 볼 수 있다.

    병렬과 직렬의 차이를 생각해보면 된다.

    병렬은 여러개를 동시에 처리할 수 있다는 장점이 있지만, 그 의미가 직렬보다 훨씬 빠르다는 것은 아니다. (경우에 따라, 오히려 느릴 수도 있다.)

    그림을 보다시피, 병렬처리로 인해 비슷하게 완료되지만, 다운로드 시간이 길다는 것을 알 수 있다.

    그로 인해, 우선순위와 상관없이 한번에 처리한다면, 우선순위가 높은 이미지의 로딩이 지연될 수 있다.


    이러한 경우, 동기식 처리가 필요하다.

    동기적으로 인해 순차적으로 처리되는 그림은 다음과 같다.


    preloading 직렬


    비록 전체적인 시간은 느린 모습을 보였지만, 각 이미지 다운로드 시간은 확실히 줄어든 모습을 볼 수 있다.

    병렬 처리에 대한 문제점을 기준으로 잡았지만, 반대의 상황에서는 당연히 순차적 처리가 문제가 된다.

    결국 사용자 경험, 상황, 목적 등에 따라 어떠한 방식으로 preloading 할 것인지 선택해야한다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    class Preloader {
     
      constructor () {}
     
      static series (imageArray) {
        let n = imageArray.length
        for (let i = 0; i < n; i++) {
          let img = new Image()
          img.src = imageArray[i]
        }
      }
     
      static parallel (imageArray, idx) {
        let index = idx || 0
        if (imageArray && imageArray.length > index) {
          let img = new Image()
          img.onload = function () {
            preload(imageArray, index + 1)
          }
          img.src = imageArray[index]
        }
      }
     
      static inject (id) {
        let div = document.createElement("div")
        div.id = id
    div.style.position= 'absolute'
        div.style.top = '-9999px'
    div.style.left = '-9999px'
        document.body.appendChild(div)
      }
     
    }
    cs


    반응형

    댓글

Designed by Tistory.