웹 프론트엔드/기타

[번역] 미디어 쿼리 & 에셋 다운로드 결과

아로리(arori) 2018. 7. 12. 22:43
반응형

원문: Media Query & Asset Downloading Results


조금 전, 미디어 쿼리를 포함할 때 이미지가 다운로드 되는 방법에 대한 에 대해 조사 중이라고 말했었습니다. 조사를 돕기 위해 JavaScript가 이미지 요청 여부를 결정할 수 있는 자동화된 테스트를 작성했고, 테스트 검토를 위해 Browserscope에서 결과를 수집할 수 있었습니다. 최초 발견한 내용을 포스팅했었지만, 이제는 더 자세히 말할 수 있을 만큼 충분한 데이터를 가지고 있다고 생각합니다.

먼저, 모든 공로는 Cloud Four에 있는 멋진 팀에게 돌아가야합니다. 대부분의 테스트는 그들이 자신의 업무를 테스트하기 위해 만들었습니다. 저는 단지 테스트를 자동화하기위해 자바스크립트를 추가했습니다.

결과를 봅시다!

테스트 1: 이미지 태그

이 페이지는 display:none을 사용하여 div에 포함된 이미지를 숨기려고 했습니다. HTML과 CSS는 다음과 같습니다:

<div id="test1">
  <img src="images/test1.png" alt="" />
</div>
@media all and (max-width: 600px) {
  #test1 { display:none; }
}

결과

이미지를 가리는 방법 중에 100% 확실하게 피해야 하는 방법이 있다고 하면, display: none을 사용하는 방법입니다. 이것은 완전 쓸모없습니다. 오페라 모바일과 오페라 미니는 이미지를 다운로드 하지 않는 것 같습니다(그 이유는 이전 글 참조). 하지만 다른 모든 것은 이미지를 요청합니다.

테스트 대상 이미지 요청
Android 2.1+ O
Blackberry (6.0+) O
Chrome (4.1)+ O
Chrome Mobile O
Fennec (10.0+) O
Firefox (3.6+) O
IE O
iOS (4.26+) O
Kindle (3.0) O
Opera (11.6+) O
Opera Mini (6.5+) X
Opera Mobile (11.5) X
RockMelt O
Safari (4+) O

결론

간단합니다. 쓰지 마세요.

테스트 2: 배경 이미지 display: none

이 테스트에서 div에 배경 이미지를 주었습니다. 화면의 너비가 600px 미만인 경우에는, div가 display:none으로 설정됩니다. HTML과 CSS는 다음과 같습니다:

<div id="test2"></div>
#test2 {
  background-image:url('images/test2.png');
  width:200px;
  height:75px;
}
@media all and (max-width: 600px) {
  #test2 {display:none;}
}

결과

첫번째 테스트와 동일합니다. 오페라 모바일, 오페라 미니를 제외한 테스트한 모든 브라우저가 이미지를 다운로드합니다.

테스트 대상 이미지 요청
Android 2.1+ O
Blackberry (6.0+) O
Chrome (4.1)+ O
Chrome Mobile O
Fennec (10.0+)
O
Firefox (3.6+)
X
IE
O
iOS (4.26+)
O
Kindle (3.0) O
Opera (11.6+)
O
Opera Mini (6.5+)
X
Opera Mobile (11.5)
X
RockMelt
O
Safari (4+)
O
Silk O

결론

다시 말합니다. 쓰지 마세요. 다행히도 다른 테스트에서 보여 주듯이, 이미지 요청 없이 배경 이미지를 숨기는 몇가지 쉬운 방법이 있습니다.

테스트 3: 배경 이미지, 부모 오브젝트를 display: none

이 테스트에서 div 에 배경 이미지를 주었습니다. 화면의 너비가 600px 미만인 경우에는, div의 부모(또 다른 div)가 diplay: none으로 설정됩니다. HTML과 CSS는 다음과 같습니다.

<div id="test3">
  <div></div>
</div>
#test3 div {
  background-image:url('images/test3.png');
  width:200px;
  height:75px;
}
@media all and (max-width: 600px) {
  #test3 {
    display:none;
  }
}

결과

이것을 발견한 제이슨 그릭스비(Jason Grigsby)에게 영광을 돌립니다. 표면적으로는 이것이 왜 테스트 2와 다른지 명백하지 않습니다. 하지만 연구 초기에 제이슨 그릭스비는 이것이 차이가 있는 것처럼 보였으므로 테스트했습니다. 이 방법은 실제로 꽤 신뢰할만 하기 때문에 우리로서는 다행입니다.

테스트 대상 이미지 요청
Android 2.1+ X
Blackberry (6.0+) X
Chrome (4.1)+ X
Chrome Mobile X
Fennec (10.0+)
O
Firefox (3.6+)
X
IE
X
iOS (4.26+)
X
Kindle (3.0) X
Opera (11.6+)
X
Opera Mini (6.5+)
X
Opera Mobile (11.5)
X
Safari (4+)
X

결론

이 방법은 잘 동작합니다. 테스트를 거친 모든 브라우저는 필요한 경우에만 이미지를 다운로드합니다. 너무 열심히 다운받는 Fennec를 제외하고요. 이 방법의 문제점은 포함하고 있는 요소도 숨겨야 한다는 점입니다. 만약 숨겨도 된다면 자유롭게 이 방식을 사용하세요.

테스트 4: 배경 이미지를 캐스케이드로 오버라이드(Cascade Overide)

이 테스트에서 div 에 배경 이미지를 주었습니다. 화면의 너비가 600px 미만인 경우에는, div에 다른 이미지를 주었습니다. 이 테스트에서는 두 개 다 요청했는지, 필요한 한 개만 요청했는지 확인합니다. HTML과 CSS는 다음과 같습니다.

<div id="test4"></div>
#test4 {
  background-image:url('images/test4-desktop.png');
  width:200px;
  height:75px;
}
@media all and (max-width: 600px) {
  #test4 {
    background-image:url('images/test4-mobile.png');
  }
}

결과

확실히 display:none을 사용하는 것 보단 낫지만, 이 방법은 약간 흠이 있습니다.

테스트 대상 이미지 요청
Android 2.1-3.0? O
Android 4.0 X
Blackberry 6.0 O
Blackberry 7.0 X
Chrome (16)+ X
Chrome Mobile X
Fennec (10.0+)
O
Firefox (3.6+)
X
IE 9+
X
iOS (4.26+)
X
Kindle (3.0) O
Opera (11.6+)
X
Opera Mini (6.5+)
X
Opera Mobile (11.5)
X
Safari 4.0
O
Safari 5.0+
X

결론

저는 피할 것입니다. 상황은 나아지고 있지만, 안드로이드 시장 점유율을 지배하고 있는 안드로이드 2.x는(역주: 2012년 글입니다) Fennec와 Kindle처럼 두 이미지를 다운로드합니다. 세 가지, 특히 안드로이드 때문에 다른 방법을 보는 것을 권합니다.

테스트 5: 배경 이미지의 데스크탑용 이미지를 min-width로 셋팅

이 테스트에서 div 에 미디어 쿼리 (min-width: 601px)가 일치하면 어떤 배경 이미지를 주고, (max-width: 500px)가 일치하면 다른 이미지를 주었습니다. HTML과 CSS는 다음과 같습니다.

<div id="test5"></div>
@media all and (min-width: 601px) {
  #test5 {
    background-image:url('images/test5-desktop.png');
    width:200px;
    height:75px;
  }
}
@media all and (max-width: 600px) {
  #test5 {
    background-image:url('images/test5-mobile.png');
    width:200px;
    height:75px;
  }
}

결과

상황이 조금 더 나아졌습니다.

테스트 대상 이미지 요청
Android 2.1+ X
Blackberry (6.0+) X
Chrome (16+) X
Chrome Mobile X
Fennec (10.0+)
O
Firefox (3.6+)
X
IE 9+
X
iOS (4.26+)
X
Kindle (3.0) X
Opera (11.6+)
X
Opera Mini (6.5+)
X
Opera Mobile (11.5)
X
Safari (4+)
X

결론

이제 더 많은 브라우저가 실행됩니다. Fennec는 여전히 제어 불가합니다.

이 방법을 사용하면 Internet Explorer 이하의 대체 옵션을 생각해야 합니다. 그 버전의 브라우저는 미디어 쿼리를 지원하지 않으므로 이미지가 적용되지 않습니다. 물론 조건부 주석이나 IE 특정 스타일 시트로 해결할 수 있는 간단한 문제입니다.

테스트 6: 배경 이미지 display: none (max-device-width)

이 테스트는 테스트2와 동일하지만 미디어 쿼리를 max-width 대신 max-device-width를 사용했습니다. HTML과 CSS는 다음과 같습니다.

<div id="test6"></div>
#test6 {
  background-image:url('images/test6.png');
  width:200px;
  height:75px;
}
@media all and (max-device-width: 600px) {
  #test6 {
    display:none;
  } 
}

결론

이것에 많은 시간을 할애하지 않겠습니다. 왜냐하면 결국 이 시험은 버려지는 시험이였기 때문입니다. 이것은 테스트2와 차이가 없었습니다. 이 테스트는 누군가가 Cloud Four의 원래 테스트와는 다른 결과를 얻었다고 언급한 트윗 때문에 추가되었지만, 그 다른 부분은 완전히 다른 것 때문에 발생했습니다. (기억이 맞다면 오타때문이였습니다)

테스트 7: 고해상도 대응을 위한 캐스케이드로 오버라이드

마지막 테스트는 좀 늦게 추가 되었습니다. 레티나 iPad를 코앞에 두고, 고해상도 디스플레이에 이미지를 제공하는 방법에 대한 많은 게시물이 있었습니다. 한 게시물에서 Brad Frost는 이 테스트의 결과를 보는 것이 흥미로울 거라고 언급해서 추가했습니다.

이 테스트에서 div 에 배경 이미지를 주었습니다. 그런 다음, min-device-pixel-ratio 미디어 쿼리를 사용하여 최소 비율이 1.5인 경우 새로운 배경 이미지를 적용했습니다.

HTML과 CSS는 다음과 같습니다.

<div id="test7"></div>
#test7 {
  background-image:url('images/test7-lowres.png');
  width:200px;
  height:75px;
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
  only screen and (min--moz-device-pixel-ratio: 1.5),
  only screen and (-o-min-device-pixel-ratio: 3/2),
  only screen and (min-device-pixel-ratio: 1.5) {
    #test7 {
      background-image:url('images/test7-highres.png');
      width:200px;
      height:75px;
    }
}

결과

모든 테스트 중에서 이 테스트가 많은 사람들이 테스트를 해주는 게 가장 도움이 됩니다. 말하자면, 다음과 같은 결과가 정확해 보입니다.

테스트 대상 이미지 요청
Android 2.1-3.0? O
Android 4.0 X
Blackberry 6.0 X
Blackberry 7.0 X
Chrome (16+) X
Chrome Mobile X
Fennec (10.0+)
X
Firefox (3.6+)
X
IE 9+
X
iOS (4.26+)
X
Kindle (3.0) X
Opera (11.6+)
X
Opera Mini (6.5+)
X
Opera Mobile (11.5)
X
Safari (4+)
X

결론

다시 한번 말하지만, 이 테스트는 안정성을 위해 조금 더 실행되는 것이 좋습니다. 이 방법은 대부분은 작동하는 것으로 보입니다. 안타깝게도, Android 2.x에서 디바이스 비율 픽셀이 1.5 이상이면(혹은 미디어 쿼리에서 설정한 값 이상) 이미지를 모두 다운로드 합니다. 따라서 위 테스트의 경우 Android 2.x를 실행하는 고해상도 장치가 있다면 안타까운일입니다.

좋은 소식은, 지금 1.5 이상의 디바이스 픽셀 비율이 1.5가 넘는 안드로이드 디바이스를 모른다는 점입니다. 따라서 레티나 디스플레이 iOS 디바이스를 타겟으로한다면, min-device-pixel-ratio를 2로 설정하면 안전할 것입니다. 그리고 이제 이렇게 말했으니, 이 글의 첫 세개의 댓글이 글을 바로잡고, 내가 증명한 것이 틀렸다는것을 지적하는 안드로이드 기기가 나오는 것을 기대하고 있습니다.

이 테스트 실행 초반에는 Android가 잘 동작하는 것처럼 보였기 때문에, 좀 실망스럽습니다. 안드로이드는 테스트를 엉망으로 만드는 것처럼 보이는 유일한 브라우저지만, 또한 가장 많이 사용되기도 합니다.

추천

display: none을 설정해서 콘텐츠 이미지를 숨길 수는 없습니다. JavaScript 또는 서버 기반 방식을 사용하는 것이 좋습니다.

배경 이미지를 숨기는 가장 좋은 방법은 부모 요소를 숨기는 것입니다. 그렇게 할 수 없다면, 캐스케이드로 오버라이드(테스트 5와 같음)해서 background-image를 none으로 설정하세요.

배경 이미지를 바꾸려면, 미디어 쿼리 내부에서 정의하세요.

앞으로

테스트를 실행해서 위의 내용이 잘못되었다고 생각하면, 나에게 메일을 보내거나 GitHub에 잘못되었다고 리포트를 보내주세요. 제가 파헤쳐 보겠습니다. 테스트를 추가하는 것도 마찬가지입니다.


해당 글은 퍼포먼스 향상을 위해 불필요한 상황에서 이미지를 로드하지 않도록 하는게 주 목적인것 같습니다. 저는 반대로 스프라이트 이미지를 먼저 다운로드 받아야 하는데, 뒤늦게 받아서 렌더가 늦어지는 이슈 때문에 해당 글을 참고하였습니다.

반응형