Czy „display: none” uniemożliwia załadowanie obrazu?

336

W każdym samouczku dotyczącym programowania witryn responsywnych zaleca się korzystanie z display:nonewłaściwości CSS w celu ukrycia treści przed ładowaniem w przeglądarkach mobilnych, aby strona ładowała się szybciej. Czy to prawda? Nie display:noneładuje zdjęć lub nadal ładuje zawartość w przeglądarce mobilnej? Czy jest jakiś sposób, aby zapobiec ładowaniu niepotrzebnych treści w przeglądarkach mobilnych?

paskudny
źródło
6
Wydaje się, że istnieją pewne sposoby, aby zapobiec pobieraniu z wyświetlaczem: brak, po prostu nie waniliowy sposób: timkadlec.com/2012/04/media-query-asset-downloading-results
mrwweb
1
W3C aktywnie go testuje: w3.org/2009/03/image-display-none/test.php
Pino

Odpowiedzi:

191

Przeglądarki stają się inteligentniejsze. Dzisiaj Twoja przeglądarka (w zależności od wersji) może pominąć ładowanie obrazu, jeśli może stwierdzić, że nie jest to przydatne.

Obraz ma display:nonestyl, ale jego rozmiar może być odczytany przez skrypt. Chrome v68.0 nie ładuje obrazów, jeśli rodzic jest ukryty.

Możesz to sprawdzić tutaj: http://jsfiddle.net/tnk3j08s/

Można to również sprawdzić, patrząc na kartę „sieć” narzędzi programistycznych przeglądarki.

Zauważ, że jeśli przeglądarka znajduje się na małym komputerze z procesorem, brak konieczności renderowania obrazu (i układu strony) przyspieszy całą operację renderowania, ale wątpię, czy jest to dzisiaj sensowne.

Jeśli chcesz zapobiec ładowaniu obrazu, możesz po prostu nie dodać elementu IMG do dokumentu (lub ustawić srcatrybut IMG na "data:"lub "about:blank").

Denys Séguret
źródło
50
pusty obraz src jest niebezpieczny. Wysyła dodatkowe żądanie do serwera. dobra lektura na ten temat nczonline.net/blog/2009/11/30/…
Srinivas
2
@SrinivasYedhuri Tak, masz rację. Edytowałem z lepszym rozwiązaniem.
Denys Séguret,
8
Ta odpowiedź jest tylko częściowo poprawna. Właśnie przetestowałem to w Google Chrome (v35) i mogę potwierdzić, że obrazy z ustawionym ustawieniem wyświetlania na none nie są pobierane. To prawdopodobnie ułatwi responsywne projektowanie dewelopera.
Shawn Whinnery
15
Ta odpowiedź nie jest już poprawna. Poniżej znajdują się zaktualizowane wyniki tego, w jaki sposób różne przeglądarki, w tym najnowsza wersja FF, radzą sobie z tą sytuacją w różny sposób
DMTintner
2
Nawet dzisiaj (październik 2017 r.) Najpopularniejsza przeglądarka Chrome pobierze wszystkie źródła elementów „img”, nawet jeśli są ukryte. Nie pobierze ukrytych obrazów tła.
TKoL
130

Jeśli uczynisz obraz jako tło obrazu div w CSS, gdy div ten jest ustawiony na „display: none”, obraz nie zostanie załadowany. Gdy CSS jest wyłączony, nadal się nie ładuje, ponieważ cóż, CSS jest wyłączony.

Brent
źródło
17
Moim zdaniem jest to bardzo przydatna wskazówka dotycząca responsywnego projektowania.
ryandlf
3
Działa to w FF, Chrome, Safari, Opera, Maxthon. Nie próbowałem żadnego IE.
Brent
13
Nowość z przodu! <div hidden style="display:none;width:0;height:0;visibility:hidden;background:url('test.jpg')"></div>. Wyniki: Firefox 29 i Opera 12 nie ładują się. Obciążenie IE 11 i Chrome 34.
CoolCmd
3
@CoolCmd dla elastycznego projektowania to wciąż realną opcją, jak można w zestawie multimedialnymi CSS zapytaniu background-imagedo noneprzypadków, w których nie chcesz, aby załadować obraz. Nie znalazłem lepszej alternatywy dla tego przypadku użycia, który nie korzysta z JS.
Qtax
1
Przetestowałem suwak obrazu (wykorzystujący obrazy tła), który miał zapytanie o media o minimalnej szerokości. Poniżej tej szerokości div-rodzic miał CSS display: none;. Testy sieciowe z oknem poniżej tej szerokości: Chrome 35, IE11 i Edge nie załadowały obrazów
binaryfunt
57

Odpowiedź nie jest tak prosta jak zwykłe tak lub nie. Sprawdź wyniki testu, który niedawno przeprowadziłem:

  • W Chrome: wszystkie 8 zrzutów ekranu * * załadowanych obrazów (img 1)
  • W przeglądarce Firefox: ładowany jest tylko 1 zrzut ekranu *, który jest aktualnie wyświetlany (img 2)

Po dalszym kopaniu znalazłem to , co wyjaśnia, jak każda przeglądarka obsługuje ładowanie zasobów img na podstawie wyświetlania css: none;

Fragment postu na blogu:

  • Chrome i Safari (WebKit):
    WebKit pobiera plik za każdym razem, z wyjątkiem sytuacji, gdy tło zostanie zastosowane poprzez niepasujące zapytanie o media.
  • Firefox:
    Firefox nie pobierze obrazu wywoływanego z obrazem tła, jeśli style są ukryte, ale nadal będą pobierać zasoby z tagów img.
  • Opera:
    Podobnie jak Firefox, Opera nie ładuje bezużytecznych obrazów tła.
  • Internet Explorer:
    IE, podobnie jak WebKit, pobierze obrazy tła, nawet jeśli mają display: none; Coś dziwnego pojawia się w IE6: Elementy z obrazem w tle i wyświetlaczem: żaden zestaw wstawiony nie zostanie pobrany ... Ale będą, jeśli te style nie zostaną zastosowane wstawione.

Chrome - wszystkie 8 zrzutów ekranu * * załadowanych obrazów

Firefox - ładowany jest tylko 1 zrzut ekranu *, który jest aktualnie wyświetlany

DMTintner
źródło
1
Dopóki wyniki te nie są częścią standardów, są zupełnie bezcelowe. Chrome zmienia silnik renderowania, zmiany także w operze, a IE zostanie zastąpione czymś innym. Po prostu nie możesz liczyć na implementację takich dodatkowych funkcji, aby pozostały stabilne w czasie. Rozwiązanie będzie sposobem na wskazanie przeglądarce, kiedy zasób powinien zostać załadowany leniwie, jeśli w ogóle.
Mark Kaplun
5
@MarkKaplun Nie sugerowałem, że te wyniki testu powinny dokładnie pokazać, czego możesz się spodziewać w każdej przeglądarce przez cały czas. Chciałem tylko wykazać, że odpowiedź „nie jest tak prosta jak tak lub nie”. każda przeglądarka obecnie wdraża to inaczej i prawdopodobnie tak będzie jeszcze przez jakiś czas
DMTintner
@DMTintner dokładnie w porządku. i od dzisiaj mogę potwierdzić załadowane do iOS safari obrazy tła div, które były wyświetlane: „display: none”. najlepszym podejściem jest nie zakładanie niczego, a jeśli nie chcesz, aby obraz był ładowany, nie
odwołuj się
34

<picture>Tag HTML5 pomoże ci znaleźć właściwe źródło obrazu w zależności od szerokości ekranu

Najwyraźniej zachowanie przeglądarek niewiele się zmieniło w ciągu ostatnich 5 lat i wielu nadal pobierałoby ukryte obrazy, nawet gdyby była display: nonena nich ustawiona właściwość.

Mimo że istnieje obejście zapytań o media , może to być przydatne tylko wtedy, gdy obraz został ustawiony jako tło w CSS.

Podczas gdy myślałem, że istnieje tylko rozwiązanie JS problemu ( leniwe ładowanie , wypełnianie obrazów itp.), Okazało się , że istnieje ładne, czyste rozwiązanie HTML, które wychodzi z pudełka z HTML5.

I to jest <picture>tag.

Oto jak MDN to opisuje:

Element HTML<picture> to kontener służący do określania wielu <source>elementów dla określonego <img>w nim zawartego elementu . Przeglądarka wybierze najbardziej odpowiednie źródło zgodnie z bieżącym układem strony (ograniczenia pola, w którym pojawi się obraz) oraz urządzenie, na którym będzie wyświetlane (np. Urządzenie normalne lub hiDPI).

A oto jak go użyć:

<picture>
 <source srcset="mdn-logo-wide.png" media="(min-width: 600px)">
 <img src="mdn-logo-narrow.png" alt="MDN">
</picture>

Logika z tyłu

Przeglądarka załaduje źródło imgtagu, tylko jeśli żadna z reguł multimediów nie ma zastosowania. Gdy <picture>element nie jest obsługiwany przez przeglądarkę, ponownie przejdzie do wyświetlania imgtagu.

Zwykle umieszczasz najmniejszy obraz jako źródło, <img>a tym samym nie ładujesz ciężkich obrazów na większe ekrany. Odwrotnie, jeśli obowiązuje reguła medialna, źródło <img>nie zostanie pobrane, zamiast tego pobierze zawartość adresu URL odpowiedniego <source>tagu.

Jedyną pułapką jest to, że jeśli element nie jest obsługiwany przez przeglądarkę, załaduje tylko mały obraz. Z drugiej strony w 2017 r. Powinniśmy pomyśleć i kodować w pierwszym podejściu mobilnym .

I zanim ktoś zostanie zbyt podekscytowany, oto bieżąca obsługa przeglądarki dla <picture>:

Przeglądarki stacjonarne

Obsługa przeglądarek stacjonarnych

Przeglądarki mobilne

Obsługa przeglądarek mobilnych

Więcej informacji na temat obsługi przeglądarki można znaleźć w części Czy mogę używać .

Dobrą rzeczą jest to, że zdaniem html5please jest użycie go z rezerwą . I ja osobiście zamierzam skorzystać z ich rad.

Więcej informacji o znaczniku można znaleźć w specyfikacji W3C . Jest tam zastrzeżenie, które uważam za ważne:

pictureElementem jest nieco różni się od podobnych wyglądające videoi audioelementów. Chociaż wszystkie zawierają sourceelementy, srcatrybut elementu źródłowego nie ma znaczenia, gdy element jest zagnieżdżony w pictureelemencie, a algorytm wyboru zasobów jest inny. Również picturesam element niczego nie wyświetla; zapewnia jedynie kontekst dla zawartego imgelementu, który pozwala mu wybierać spośród wielu adresów URL.

Mówi więc, że pomaga tylko poprawić wydajność podczas ładowania obrazu, zapewniając mu pewien kontekst.

Nadal możesz użyć magii CSS, aby ukryć obraz na małych urządzeniach:

<style>
  picture { display: none; }

  @media (min-width: 600px) {
    picture {
      display: block;
    }
  }
</style>

<picture>
 <source srcset="the-real-image-source" media="(min-width: 600px)">
 <img src="a-1x1-pixel-image-that-will-be-hidden-in-the-css" alt="MDN">
</picture>

W ten sposób przeglądarka nie wyświetli rzeczywistego obrazu i pobierze tylko 1x1obraz pikselowy (który można buforować, jeśli użyjesz go więcej niż jeden raz). Należy jednak pamiętać, że jeśli <picture>znacznik nie jest obsługiwany przez przeglądarkę, nawet na ekranach pulpitu rzeczywisty obraz nie będzie wyświetlany (więc na pewno będziesz potrzebować kopii zapasowej wypełniania wielu pól).

Evgenia Manolova
źródło
4
Wybrałem podobną trasę jak ty, ale zamiast tego używam im-data :) Oto wpis, który napisałem na nim swimburger.net/blog/web/…
Swimburger
10

Tak, renderuje się szybciej, tylko dlatego, że nie musi renderować obrazu i jest o jeden element mniejszy do sortowania na ekranie.

Jeśli nie chcesz, aby był ładowany, pozostaw DIV pusty, w którym możesz później załadować HTML zawierający <img>tag.

Spróbuj użyć firebuga lub wiresharka, jak wspomniałem wcześniej, a zobaczysz, że pliki zostaną przesłane, nawet jeśli display:nonesą obecne.

Opera jest jedyną przeglądarką, która nie załaduje obrazu, jeśli ekran jest ustawiony na none. Opera została teraz przeniesiona do pakietu Webkit i będzie renderować wszystkie obrazy, nawet jeśli ich wyświetlanie jest ustawione na brak.

Oto strona testowa, która to udowodni:

http://www.quirksmode.org/css/displayimg.html

dorycki
źródło
9

** Odpowiedź 2019 **

W normalnej sytuacji display:noneobraz nie uniemożliwia pobrania obrazu

/*will be downloaded*/

#element1 {
    display: none;
    background-image: url('https://picsum.photos/id/237/100');
}

Ale jeśli element przodka ma display:none, obrazy potomka nie zostaną pobrane


/* Markup */

<div id="father">
    <div id="son"></div>
</div>


/* Styles */

#father {
    display: none;
}

/* #son will not be downloaded because the #father div has display:none; */

#son {
    background-image: url('https://picsum.photos/id/234/500');
}

Inne sytuacje, które uniemożliwiają pobranie obrazu:

1- Element docelowy nie istnieje

/* never will be downloaded because the target element doesn't exist */

#element-dont-exist {
    background-image: url('https://picsum.photos/id/240/400');
}

2- Dwie równe klasy ładujące różne obrazy

/* The first image of #element2 will never be downloaded because the other #element2 class */

#element2 {
    background-image: url('https://picsum.photos/id/238/200');
}

/* The second image of #element2 will be downloaded */

#element2 {
    background-image: url('https://picsum.photos/id/239/300');
}

Tutaj możesz uważać: https://codepen.io/juanmamenendez15/pen/dLQPmX

Juanma Menendez
źródło
8

Dziwactwa Tryb: obrazy i wyświetlanie: brak

Gdy obraz ma display: nonelub znajduje się w elemencie display:none, przeglądarka może nie pobierać obrazu, dopóki nie display zostanie ustawiona inna wartość.

Tylko Opera pobiera obraz po przełączeniu displaysię block. Wszystkie inne przeglądarki pobierają go natychmiast.

onlyurei
źródło
8

Obraz tła elementu div zostanie załadowany, jeśli element div jest ustawiony na „display: none”.

W każdym razie, jeśli ten sam div ma element nadrzędny i ten element nadrzędny jest ustawiony na „display: none”, obraz tła elementu podrzędnego nie zostanie załadowany . :)

Przykład użycia bootstrap:

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


<div class="col-xs-12 visible-lg">
	<div style="background-image: url('http://via.placeholder.com/300x300'); background-repeat:no-repeat; height: 300px;">lg</div>
</div>
<div class="col-xs-12 visible-md">
	<div style="background-image: url('http://via.placeholder.com/200x200'); background-repeat:no-repeat; height: 200px;">md</div>
</div>
<div class="col-xs-12 visible-sm">
	<div style="background-image: url('http://via.placeholder.com/100x100'); background-repeat:no-repeat; height: 100px">sm</div>
</div>
<div class="col-xs-12 visible-xs">
	<div style="background-image: url('http://via.placeholder.com/50x50'); background-repeat:no-repeat; height: 50px">xs</div>
</div>

ninja_corp
źródło
4

Jeśli uczynisz obraz jako tło obrazu div w CSS, gdy div ten jest ustawiony na „display: none”, obraz nie zostanie załadowany.

Rozwijam tylko rozwiązanie Brenta.

Możesz wykonać następujące czynności dla czystego rozwiązania CSS, dzięki temu pole img faktycznie zachowuje się jak pole img w responsywnym ustawieniu projektowym (do tego właśnie służy przezroczysty png), co jest szczególnie przydatne, jeśli twój projekt używa responsive-dynamicznie- zmiana rozmiaru zdjęć.

<img style="display: none; height: auto; width:100%; background-image: 
url('img/1078x501_1.jpg'); background-size: cover;" class="center-block 
visible-lg-block" src="img/400x186_trans.png" alt="pic 1 mofo">

Obraz zostanie załadowany tylko wtedy, gdy uruchomione zostanie zapytanie o media powiązane z widocznym-lg-blokiem i display: none nie zmieni się na display: block. Przezroczysty png służy do umożliwienia przeglądarce ustawienia odpowiednich proporcji wysokości: szerokości dla bloku <img> (a tym samym obrazu tła) w płynnym projekcie (wysokość: auto; szerokość: 100%).

1078/501 = ~2.15  (large screen)
400/186  = ~2.15  (small screen)

W rezultacie otrzymujesz coś takiego, jak na 3 różne rzutnie:

<img style="display: none; height: auto; width:100%; background-image: url('img/1078x501_1.jpg'); background-size: cover;" class="center-block visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/517x240_1.jpg'); background-size: cover;" class="center-block visible-md-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/400x186_1.jpg'); background-size: cover;" class="center-block visible-sm-block" src="img/400x186_trans.png" alt="pic 1">

Podczas ładowania początkowego ładowane są tylko obrazy domyślnego rozmiaru rzutni multimediów, a następnie, w zależności od rzutni, obrazy będą ładowane dynamicznie.

I bez javascript!

ats
źródło
2

Cześć chłopaki, walczyłem z tym samym problemem, jak nie ładować obrazu na telefon komórkowy.

Ale wymyśliłem dobre rozwiązanie. Najpierw utwórz tag img, a następnie załaduj pusty plik svg do atrybutu src. Teraz możesz ustawić adres URL obrazu jako styl wbudowany z zawartością: url („link do obrazu”) ;. Teraz zawiń swój tag img w wybrane opakowanie.

<div class="test">
  <img src="data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/‌​svg%22/%3E" style="content:url('https://blog.prepscholar.com/hubfs/body_testinprogress.gif?t=1495225010554')">
</div>

  @media only screen and (max-width: 800px) {
      .test{
       display: none;
      }
    }

Ustaw opakowanie, aby nie wyświetlało żadnego w punkcie przerwania, w którym nie chcesz ładować obrazu. Wbudowane css znacznika img jest teraz ignorowane, ponieważ styl elementu owiniętego w opakowanie z wyświetlaczem none nie zostanie zignorowany, dlatego obraz nie jest ładowany, dopóki nie osiągniesz punktu przerwania, w którym opakowanie ma blok wyświetlania.

Proszę bardzo, naprawdę prosty sposób, aby nie ładować obrazu na mobilny punkt przerwania :)

Sprawdź ten codepen, na działający przykład: http://codepen.io/fennefoss/pen/jmXjvo

Mikkel Fennefoss
źródło
Uwielbiam, jak sieć ciągle się rozwija, nie widziałem wcześniej tej sztuczki, używając content-property do zmiany wyświetlanego obrazu. Czy możesz podać kilka statystyk na temat kompatybilności?
Windgazer
Szkoda, że ​​Edge: / przynajmniej działa w najnowszych wersjach Firefox, Chome i Safari.
Mikkel Fennefoss
2

Nie. Obraz zostanie załadowany w zwykły sposób i nadal będzie korzystał z przepustowości użytkownika, jeśli rozważasz oszczędność przepustowości użytkownika telefonu komórkowego. Możesz użyć zapytania mediów i filtrować urządzenia, które chcesz załadować. obraz musi być ustawiony jako obraz tła div itp., a NIE jako znacznik, ponieważ znacznik obrazu załaduje obraz niezależnie od rozmiaru ekranu i zestawu zapytań o media.

IsuNas Labs
źródło
1

Inną możliwością jest użycie <noscript>znacznika i umieszczenie obrazu wewnątrz <noscript>znacznika. Następnie użyj javascript, aby usunąć noscriptznacznik, ponieważ potrzebujesz obrazu. W ten sposób można ładować obrazy na żądanie przy użyciu progresywnego ulepszania.

Użyj tego wypełnienia, które napisałem, aby przeczytać zawartość <noscript>tagów w IE8

https://github.com/jameswestgate/noscript-textcontent

James Westgate
źródło
1

Użyj @media zapytanie CSS, po prostu wypuszczamy projekt, w którym mieliśmy ogromny obraz drzewa na pulpicie z boku, ale nie pokazano go na ekranach tabel / urządzeń mobilnych. Więc nie pozwól, aby obraz ładował się dość łatwo

Oto mały fragment:

.tree {
    background: none top left no-repeat; 
}

@media only screen and (min-width: 1200px) {
    .tree {
        background: url(enormous-tree.png) top left no-repeat;
    }
}

Możesz użyć tego samego CSS, aby wyświetlać i ukrywać za pomocą display / visibility / krycia, ale obraz wciąż się ładuje, był to najbardziej bezpieczny kod, jaki wymyśliliśmy.

Joakim Ling
źródło
0

mówimy o obrazach, które nie ładują się na telefon, prawda? więc co jeśli zrobiłeś @media (min-width: 400px) {background-image: thing.jpg}

czy nie szukałby wtedy obrazu tylko powyżej określonej szerokości ekranu?

Superfly5000
źródło
-2

Sztuką korzystania z display: none z obrazami jest przypisanie im identyfikatora. Było tak, że nie trzeba dużo kodu, aby działał. Oto przykład z wykorzystaniem zapytań o media i 3 arkuszy stylów. Jeden na telefon, jeden na tablet i jeden na komputer. Mam 3 zdjęcia, zdjęcie telefonu, tabletu i pulpitu. Na ekranie telefonu wyświetli się tylko obraz telefonu, tablet wyświetli tylko obraz tabletu, a pulpit zostanie wyświetlony na obrazie komputera stacjonarnego. Oto przykład kodu, aby to działało:

Kod źródłowy:

<div id="content">
<img id="phone" src="images/phone.png" />
<img id="tablet" src="images/tablet.png" />
<img id="desktop" src="images/desktop.png" />
</div>

Telefon CSS, który nie wymaga zapytania o media. To telefon img # sprawia, że ​​działa:

img#phone {
    display: block;
    margin: 6em auto 0 auto;
    width: 70%;
    }

img#tablet {display: none;}
img#desktop {display: none;}

Tablet css:

@media only screen and (min-width: 641px) {
img#phone {display: none;}

img#tablet {
    display: block;
    margin: 6em auto 0 auto;
    width: 70%;
    }
}

I css na pulpicie:

@media only screen and (min-width: 1141px) {
img#tablet {display: none;}

img#desktop {
    display: block;
    margin: 6em auto 0 auto;
    width: 80%;
    }
}

Powodzenia i daj mi znać, jak to działa dla Ciebie.

Duane
źródło
4
Nie chodzi o to, jak ustawić display: noneobraz. To: Czy „display: none” uniemożliwia załadowanie obrazu?
Evgenia Manolova