2018년 11월 31일
오늘 한 일
- 포트폴리오 사이트에 lazy loading 적용하기
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를 대체하는 방법
- 주의: placeholder 이미지 크기는 원본과 같아야 레이아웃 변경을 막을 수 있음
<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);
- data-attribute를 이용하는 방법
- js가 실행되면 이미지 태그의 src를 data-src로 변경해줌
- image의 로드가 완료되면 data-src 속성은 삭제
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);
- root: target의 visibility를 체크하는 뷰포트로서의 엘리먼트. target의 조상이어야 함. 정의하지 않거나
null
인 경우 브라우저 뷰포트가 디폴트 - rootMargin: root를 둘러싼 마진. root의 intersection bound 크기를 조정
- threshold: 콜백을 호출할 시점. 숫자 또는 숫자의 배열. 디폴트는 0
- 0.5 : 50% 보일경우 호출
- [0, 0.25, 0.5, 0.75, 1.0] : 0, 25%, 50%, 75%, 100% 때마다 호출
사용법 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
})
}
- entries: root와 target의 교차점
참고 자료
https://developer.mozilla.org/en-US/docs/Web/Apps/Progressive/Loading
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API