2018년 11월 31일

오늘 한 일

Progressive Loading

렌더링을 블록하는 자원

script 태그

해결: script의 defer 속성을 이용하면 렌더링 된 후에 스크립트를 실행할 수 있음

<script src="app.js" defer></script>

css file

해결: media 타입을 지정해 조건에 따라 스타일을 로드하도록 함

<link rel="stylesheet" href="print.css" media="print">

이미지 처리

일단 여기와 같은 페이지에서 이미지 용량을 줄이고 시작하자

placeholder image

placeholder 이미지를 먼저 다운받고 js를 통해 src를 대체하는 방법

<img src="placeholder.jpg" data-src="origin.jpg">
const images = document.querySelector('img');
const loadImage = (image) => {
    image.setAttribute('src', image.dataset.src);
    image.onload = function() {
        image.removeAttribute('data-src');
    }
}
images.forEach(loadImage);

css의 blur 이용하기

blur를 이용하면 더 매끄러운 사용자 경험을 줄 수 있다

img[data-src] {
    filter: blur(0.2em);
}
img {
    filter: blur(0em);
    transition: filter .5s;
}

Loading on demand

이제 그때그때 필요한 이미지만 다운받아 보자

Intersection Observer API

과거에는 Element.getBoundingClientRect() api를 사용

target 엘리먼트와 root 엘리먼트(일반적으로 viewport)의 교차시에 호출되는 callback을 설정할 수 있다.

intersection ratio: target과 root의 교차 정도(0.0 ~ 1.0)

사용법 1. intersection observer 생성하기

const option = {
    root: document.querySelector('#scrollArea'),
    rootMargin: 0,
    threshold: 1.0, // 1.0일 경우 root안에서 target이 100% 보일경우 콜백함수가 호출된다
}
const observer = new IntersectionObserver(callback, option);

사용법 2: target 설정하기

const target = document.querySelector('#listItem');
observer.observe(target);

이제 해당 타겟이 조건을 만족하면 callback을 호출한다. 다음은 callback의 모습

const callback = (entries, observer) => {
    entries.forEach((entry) => {
        // entry.boudingClientRect
        // entry.intersectionRatio
        // entry.intersectionRect
        // entry.isIntersecting
        // entry.rootBounds
        // entry.target
        // entry.time
    })
}

참고 자료

https://developer.mozilla.org/en-US/docs/Web/Apps/Progressive/Loading

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API