SVG 기반 느린 이미지 로드

2017년 11월 어느 날, 우리 팀은 José M.Pérezthis article의 작품을 만났는데 그 중에서 이미지 방치와 게으름에 관한 새로운 작품이 대량으로 포함되었다.글에서 언급한 예와 우리가 그날의 처리 방식을 비교하는 것을 보면 인상적이다.인상적인 것은 Blue World라는 이름의 blue-tomato.com content section 에서 내연 SVG를 사용하여 이미지 게으름 로드 기술을 실현하기로 결정했다는 것이다.

거의 저희가 노력해서 얻은 과도예요.
SVG가 고해상도 이미지로 해석될 때 인상적인'신기한 발생'순간을 제외하고는 사용자 경험을 개선하는 더 많은 장점을 만났습니다.
  • DOM이 준비되었을 때 즉시 시각적 응답을 한다. SVG 자리 표시자는 내부 연결이기 때문에 html 소스 코드의 일부이다
  • 모든 픽셀 게으름을 가져오기 위한 초기 자리 표시자 불러오기 요청량 감소
  • 앞에서 언급한 바와 같이 우리는 그것을 실현할 방법을 강구했고 이미 그것을 배치했기 때문에 check it out 우리의 파란색 세계 부분에서 또는 아래의 영상을 신속하게 조회하여 실현을 볼 수 있다.
    -slowmo 쇼케이스 실시
    개발 과정은 기술적 도전, 개념적 임무와 수반되고 마지막으로 실현에 대한 재구성이다.따라서 SVG 기반 이미지가 느리게 로드되고 직접 로드되기를 원한다면 저희가 곧 발표할 알림과 구현 설명을 보십시오. 그러면 귀찮은 재작성이 필요 없습니다.우리는 그것을 실현하기 위해 사용되는 메인 창고는 다음과 같은 훌륭한 창고로 구성되어 있다.

  • Primitive: 형상 엔티티를 사용하여 이미지를 재현하는 Golang 도구

  • Svgo: SVG 벡터 그래픽 파일 최적화를 위한 Nodejs 도구

  • appear.js: DOM 요소가 뷰 내외부에 나타나면 콜백

  • Processwire: PHP 기반 cms;이 cms를 사용할 필요가 없습니다. 저희가 다음에 제시한 개념과 해결 방안
  • 에 따라 원하는 cms를 선택하십시오

    SVG 기반 이미지 로드 세부 사항


    SVG 기반 이미지 로드 작업을 게을리하기 위해 저장소에 전송되는 각 행 코드를 반복하지 않습니다.우리의 코드는 우리의 내부 시스템 (주로 Processwire cms) 과 밀접하게 결합되어 있기 때문에 우리가 어떻게 해결하고 실현했는지 잘 설명할 수 없다.반대로, 만약 우리가 처음부터 다시 해야 한다면, 우리는 당신에게 우리가 오늘 고려한 노선도를 제공할 것입니다.다음은 다음 주요 단계를 안내합니다.
  • SVG 자리 표시자 생성 및 저장
  • SVG 가용성 확인 및 배송
  • 올바른 SVG lazyload 자리 표시자 프런트엔드 처리
  • SVG 자리 표시자 처음 생성 및 저장


    도전하다
    우리의 첫 번째 방법은 cms의 관리 패널에서 업로드하는 과정에서 SVG를 생성하는 것이다.우리가 직면한 첫 번째 문제는 우리가 우수한 Primitive 라이브러리를 사용하여 전환 과정을 촉발했기 때문에 이미지의 업로드 과정은 더욱 오래 걸릴 것이다.그러나 이것은 두 문제 중 비교적 작은 것이다.두 번째 문제는 우리의 이미지 자산 관리 시스템(Adobe Scene7)이 필요한 모든 이미지 형식을 동적으로 만들었다는 것이다.따라서 처음에 우리는 이미지를 업로드하는 형식으로만 SVG를 만들었을 뿐 이미지 자산 관리 시스템 처리의 다른 형식은 고려하지 않았다.

    이미지 형식에 따라 다른 SVG 형식이 필요합니다.
    인스턴스
    업로드된 이미지 형식:
    15:4
    그러나 템플릿에 사용된 형식은 다음과 같습니다.
    슬라이더 사진.jpg?형식 = 16:9
    슬라이더 사진.jpg?형식 = 4:3
    슬라이더 사진.jpg?형식 = 1: 1
    원본 업로드 이미지의 폭/높이 비율을 기반으로 하는 SVG가 하나밖에 없기 때문에 서버에서 불러온 후 SVG에서 원본 이미지로 전환할 때 어색한 효과가 발생할 수 있습니다.
    우리의 두 번째 방법은 동적으로 SVG 파일을 생성하고 캐시로 생성된 모든 html 파일을 저장하는 것이다. 그 중에서 필요한 모든 SVG를 포함한다.모든 SVG를 포함하여 전체 태그 파일을 생성하고 캐시하는 데 많은 시간이 소요된다는 것을 알고 있습니다.그러나 결국은 사용자 체험에 영향을 주지 않는다.우리의 가설도 마찬가지다.마지막으로, 우리는 http 시간 초과 문제에 부딪혔다. 우리의 편집기는 SVG가 순환하는 페이지를 만드는 데 시간이 오래 걸리는 페이지를 저장할 때 이런 문제에 부딪힌다.
    솔루션
    우리의 세 번째 방법은 현재의 업무 해결 방안을 초래했다.편집기가 이미지를 업로드하고 SVG가 네트워크 파일 시스템에서 생성되지 않으면 자동으로 생성될 SVG.json 파일이 생성됩니다.이 파일에는 생성해야 하는 SVG에 대한 정보 객체(차원, 이미지 서버 소스, 해싱 이름 등)가 포함되어 있습니다.
    {  
       "jpgTmpFilePath":"/root_path/assets/primitives/tmp/kwleklsl090309f0g0.jpg",
       "svgFilePath":"/root_path/assets/primitives/svg/kwleklsl090309f0g0.svg",
       "svgMinFilePath":"/root_path/assets/primitives/svg/kwleklsl090309f0g0.min.svg",
       "bgColor":null,
       "inputUrl":"http://s7w2p3.scene7.com/is/image/bluetomato/ugc/2-1508153542.tif?$mc1$",
       "inputUrlHash":"kwleklsl090309f0g0",
       "env":"production"
    }
    
    곧 생산될 svg 예시.json 파일
    보시다시피 이 생성될svg 대상은 상당히'하시 밀집'입니다.이 산열inputUrlHash 속성을 사용하여 이미지와 SVG를 일치시켜 SVG 생성부터 템플릿 파일에 이르기까지 적절한 자산 식별 과정을 거칩니다.
    따라서 곧 모든 새로운svg가 생산될 것이다.json 파일은 대기열의 일부입니다.cronjob은 SVG를 생성하기 위해 시간마다 한 번씩 터치합니다.그것이 무슨 작용을 하는지 봅시다.
    #!/bin/bash
    
    for jsonFile in /root_path/primitives/queue/*.json
    do
      echo "Processing $jsonFile"
    
      primitiveBinary="${root_path}tools/primitive" 
    
      # primitive image
      goPrimitiveCommand="$primitiveBinary -i $jpgTmpFilePath -o $svgFilePath -n 64 -m 1 -r 256 -bg='$bgColor'"
      eval $goPrimitiveCommand
    
      # svgo
      svgoBinary="${root_path}node_modules/svgo/bin/svgo"
      svgoCommand="$svgoBinary $svgFilePath -o $svgMinFilePath"
      eval $svgoCommand
    
      rm -f -- $jsonFile
    done
    
    echo "All SVGs created"
    exit
    
    간소화된cronjob는 네 가지 주요 기능이 있습니다.
  • 모든 새로운svg를 순환하고 가능한 한 빨리 생산한다.json 파일
  • 원어 바이너리를 가져와 SVG
  • 를 만들기 위해 실행합니다.
  • svgo 바이너리 파일을 가져와 SVG 코드를 최적화하기 위해 실행
  • 생성할svg를 삭제합니다.json 파일
  • 이미지 업로드와 게시 페이지 사이의 시간은 보통 한 시간을 초과합니다.반가운 결과는 이미 사용 가능한 대부분의 SVG가 우리 사용자가 아니라 우리 사용자에게 전달되었다는 것이다(내부가 멋지지 않다는 것이다.)lazyload 반환 옵션.
    그래서 저희가 드디어 성공했어요!SVG를 만들고 저장했습니다.다음 단계로 넘어가서 팬시와performant 자리 표시자 이미지를 사용자에게 보냅니다.

    두 번째 SVG 가용성 확인 및 배송


    SVG 생성이 완료되면 간단하고 직접적인 작업이 수행됩니다.우리는 코드 라이브러리에 createPrimitiveSvg 함수를 정의했습니다. 이 함수는 이미지와 형식을 매개 변수로 하고base64 기반 데이터uri의 최종 SVG 코드로 되돌려줍니다.
    function createPrimitiveSvg($image, $format) {
      if(inSvgCache($image)) {
        $svgFromCache = loadFromSvgCache($image); // svg already available, get it
        return makeBase64DataUri($svgFromCache);
      } else {
        pushToSvgGenerationQueue($image, $format); // svg not available, make sure it will be made
        return getBlurryImageUrl($image); // ship old lazyload fallback
      }
    }
    
    우리의 PHPcreatePrimitiveSvg 함수는 우리의 템플릿을 위한 SVG 처리
    이 함수를 한층 더 사용하고 이미지의 루트 데이터를 우리 cms에서 전달합니다. 아래와 같습니다.
    <div class="imageContainer">
      <img
        class="js-lazyload"
        src='{$image->url|createPrimitiveSvg:"16:9"}'
      />
    </div>
    
    <div class="imageContainer">
      <img
        class="js-lazyload"
        src='{$image->url|createPrimitiveSvg:"4:3"}'
      />
    </div>
    

    세 번째 올바른 SVG lazyload 자리 표시자 프런트엔드 처리


    보이다js는 DOM의 목표 자산이 뷰포트에 도달했는지 확인하는 데 매우 잘했다.그것을 사용하면 우리는 경량급 코드를 사용하여 전방에서 게으른 불러오는 것을 관리할 수 있다.
    appear({
      elements: () => document.querySelectorAll("img.js-lazyload"),
      appear: (element) => {
        const img = $(`<img class='${element.className} image--fadeIn' alt='${element.alt}' />`)
          .attr('src', element.dataset.original)
          .bind('load', () => {
            img.insertAfter(element);
            window.setTimeout(() => {
              $(element).remove();
            }, 2000);
          });
      }
    });
    
    그 역할을 살펴보겠습니다.
  • 호출 appear(config: Object) 모든 설정 대상의 속성을 초기화합니다.js 요구 사항
  • lazyload SVG 이미지가 사용자의 뷰포트에 도달하면 appear 고해상도 이미지 태그 생성
  • 을 리셋합니다.
  • 고해상도 이미지를 로드하면 표시되는 SVG
  • 뒤에 삽입됩니다.
  • CSS3 및 모호 변환 옵션
  • 을 사용하면 SVG 이미지가 페이드 아웃됩니다.
  • 2초 후 DOM에서 lazyload SVG 이미지 삭제
  • 그렇습니다!

    결론


    우리는 우리의 Blue World에서 SVG 기반의 lazyloading을 실현한 결과와 수익에 대해 매우 기쁘다.적어도 감지하기를 좋아하는 사용자 체험이 있지 않도록 하세요.해봐.이 모든 것이 당신의 프로젝트에서 일어나는 것을 보면 당신은 매우 흥미를 느낄 것이다.즐거움 코드, 즐거움 게으름 불러오기!

    좋은 웹페이지 즐겨찾기