loading=lazy 자원 읽기 시간

7640 단어 HTMLJavaScript

입문


이 글은 ZOZO 기술 #2 Advent Calendar 2019 9일째 글입니다.
Chrome76에서 구현된loading 속성 및
다음은loading=lazy를 지정할 때의 자원 읽기 시기를 소개합니다.

속성 로드 정보

<img src="image.png" loading="lazy" alt="" width="200" height="200">
지원되는 값은 현재(2019/12/9시) 다음과 같습니다.
수치
행위
auto
브라우저 기본 읽기 지연 동작
lazy
뷰포트에서 계산된 거리에 도달할 때까지 자원 읽기 지연
eager
페이지의 위치를 고려하지 않고 자원을 즉시 불러옵니다.
참고로 10x10보다 작은 내연 크기를 지정하는 요소는 지연되지 않을 것 같습니다.

임계값 정보


신경 쓰이는 것은loading=lazy를 지정할 때의 자원 읽기 시기입니다.
DevTools에서 확인데모 페이지
실제로 읽은 그림이viewportHeight보다 훨씬 낮은 것을 볼 수 있습니다.

Chrome Engineering Manager 기반 Addy Osmani의 글
Chrome’s lazy-loading implementation is based not just on how near the current scroll position is, but also the connection speed. The lazy frame and image loading distance-from-viewport thresholds for different connection speeds are hardcoded
즉, 읽기 지연의 한도값은 연결 속도에 따라 하드코딩된 것이다
확인chromium의 상응하는 코드.

현재 (2019/12/9시) 에는 다음과 같은 임계값이 정의되어 있는 것으로 보입니다.
connection speed
image
iframe
4G
3000
4000
3G
4000
5000
2G
6000
6000
slow 2g
8000
8000
offline
8000
8000
알 수 없다
5000
6000

그러니까


4G 상황에서image부터 viewportHeight까지
들어갈 때부터 읽는 규격입니다.
식으로 표현하면 아래 느낌인가요?
targetImageElement.getBoundingClientRect().top - window.innerHeight <= 3000

겸사겸사 말씀드리다


lazyImageLoadingDistance는 명령줄에서 덮어쓸 수 있을 것 같습니다.
canary --user-data-dir="$(mktemp -d)" --enable-features=LazyImageLoading --blink-settings=lazyImageLoadingDistanceThresholdPxUnknown=1,lazyImageLoadingDistanceThresholdPxOffline=1,lazyImageLoadingDistanceThresholdPxSlow2G=1,lazyImageLoadingDistanceThresholdPx2G=1,lazyImageLoadingDistanceThresholdPx3G=1,lazyImageLoadingDistanceThresholdPx4G=1 'https://mathiasbynens.be/demo/img-loading-lazy'

임의의 임계값을 설정하려면


결과적으로 현재 상황에서 임의의 한도값을 설정하려는 상황에서3000px 등은 단독으로 설치해야 한다.
<img class="lazy" src="placeholderImage.gif" data-src="originalImage.jpg" alt="">

const lazyImages = [].slice.call(document.querySelectorAll('img.lazy'))

const lazyImageObserver = new IntersectionObserver(
    (entries, observer) => {
        entries.forEach( entry => {
            if (entry.isIntersecting) {
                const lazyImage = entry.target
                lazyImage.src = lazyImage.dataset.src
                lazyImage.classList.remove('lazy')
                lazyImageObserver.unobserve(lazyImage)
            }
        })
    }, { rootMargin: '100px 0px 100px 0px' }
)

lazyImages.forEach((lazyImage) => {
    lazyImageObserver.observe(lazyImage)
})

참고 자료

  • https://addyosmani.com/blog/lazy-loading/
  • https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/frame/settings.json5?l=937-1003&rcl=e8f3cf0bbe085fee0d1b468e84395aad3ebb2cad
  • https://web.dev/native-lazy-loading/
  • 좋은 웹페이지 즐겨찾기