Pramuat Gambar CSS

118

Saya memiliki formulir kontak tersembunyi yang digunakan mengklik tombol. Kolomnya disetel sebagai gambar latar belakang CSS, dan selalu muncul sedikit lebih lambat dari div yang telah diubah.

Saya menggunakan potongan ini di <head>bagian tersebut, tetapi tidak berhasil (setelah saya membersihkan cache):

<script>
$(document).ready(function() {
        pic = new Image();
        pic2 = new Image();
        pic3 = new Image();
        pic.src="<?php bloginfo('template_directory'); ?>/images/inputs/input1.png";
        pic2.src="<?php bloginfo('template_directory'); ?>/images/inputs/input2.png";
        pic3.src="<?php bloginfo('template_directory'); ?>/images/inputs/input3.png";
});
</script>

Saya menggunakan jQuery sebagai perpustakaan saya, dan alangkah baiknya jika saya bisa menggunakannya juga untuk mengatur masalah ini.

Terima kasih atas pemikiran Anda.

Kacang kacangan
sumber
Tolong, tunjukkan kode Anda. Bagaimana Anda mengubah formulir ini?
n1313
1
n1313, saya menggunakan cara yang paling sederhana: $ ('# toggle'). click (function () {$ ('# contact'). slideToggle ();});
Peanuts

Jawaban:

257

Gambar pramuat hanya menggunakan CSS

Pada kode di bawah ini saya memilih bodyelemen secara acak , karena ini adalah satu-satunya elemen yang dijamin ada di halaman.

Agar "trik" berfungsi, kita akan menggunakan contentproperti yang memungkinkan pengaturan beberapa URL untuk dimuat, tetapi seperti yang ditunjukkan, ::afterelemen pseudo disimpan disembunyikan sehingga gambar tidak akan dirender:

body::after{
   position:absolute; width:0; height:0; overflow:hidden; z-index:-1; // hide images
   content:url(img1.png) url(img2.png) url(img3.gif) url(img4.jpg);   // load images
}

Demo


lebih baik menggunakan gambar sprite untuk mengurangi permintaan http ... (jika ada banyak gambar berukuran relatif kecil) dan pastikan gambar di-host di mana HTTP2 digunakan.

vsync
sumber
27
Ini luar biasa!
Hengjie
4
Teknik terbaik sejauh ini karena kesederhanaannya, dan pendekatan CSS murni! Satu-satunya kelemahan adalah bahwa gambar-gambar ini dimuat pada waktu yang sama dengan konten yang langsung terlihat, dan tidak ditunda hingga konten utama dimuat, yang akan membutuhkan Javascript. Tetapi kecuali Anda memuat lusinan gambar sebelumnya, ini seharusnya tidak menjadi pemecah masalah.
Benjamin
2
ini bagus untuk pramuat aset hover untuk tombol CSS dan semacamnya - dengan begitu Anda tidak mendapatkan flicker ketika Anda menekan tombol Anda saat aset dimuat
Robert Petz
16
Solusi bagus. Saya akan merekomendasikan untuk tidak menerapkan ini ke body, karena gambar-gambar ini akan dimuat ke setiap halaman yang mereferensikan stylesheet. Sebaliknya, Anda harus menggunakan .contact_form:after {...}atau beberapa kelas lain yang kurang global. Kecuali, tentu saja, formulir kontak Anda ada di setiap halaman;)
CloudMagick
3
@vsync, itu masuk akal, terutama untuk gif dan kecil yang dapat digunakan kembali. Situasi yang saya temui baru-baru ini adalah untuk gambar bg besar untuk carousel yang kaya konten, dan saya tentunya tidak ingin file besar itu dimuat di mana-mana :)
CloudMagick
30

Saya dapat mengonfirmasi bahwa kode asli saya tampaknya berfungsi. Saya dengan santai menempel pada gambar dengan jalan yang salah.

Berikut tesnya: http://paragraphe.org/slidetoggletest/test.html

<script>
    var pic = new Image();
    var pic2 = new Image();
    var pic3 = new Image();
    pic.src="images/inputs/input1.png";
    pic2.src="images/inputs/input2.png";
    pic3.src="images/inputs/input3.png";
</script>
Kacang kacangan
sumber
Setelah beberapa tes dengan CSS-ONLY dan solusi ini, dalam kasus saya secara khusus, ini adalah yang terbaik.
zequinha-bsb
Terima kasih yang termudah dari Semua :)
BetaCoder
4
URL di jawaban tidak lagi valid.
Brandon Buck
Hai, saya mengunggah ulang konten pada URL itu ( paragraphe.org/slidetoggletest/test.html ), maaf telah melewatkan ini. Cheers,
Peanuts
25

Pramuat gambar menggunakan HTML <link> Tag

Saya yakin sebagian besar pengunjung pertanyaan ini mencari jawaban dari "Bagaimana saya dapat melakukan pramuat gambar sebelum perenderan halaman dimulai?" dan solusi terbaik untuk masalah ini adalah menggunakan <link>tag karena <link>tag mampu memblokir rendering halaman selanjutnya. Lihat preemptive

Kedua opsi nilai atribut rel( hubungan antara dokumen saat ini dan dokumen tertaut ) ini paling relevan dengan masalah:

  • prefetch : memuat sumber daya yang diberikan saat merender halaman
  • preload : memuat sumber daya yang diberikan sebelum rendering halaman dimulai

Jadi jika Anda ingin memuat sumber daya ( dalam hal ini adalah gambar ) sebelum proses rendering <body>tag dimulai, gunakan:

<link rel="preload" as="image" href="IMAGE_URL">

dan jika Anda ingin memuat sumber daya saat <body>rendering tetapi Anda berencana untuk menggunakannya nanti secara dinamis dan tidak ingin mengganggu pengguna dengan waktu pemuatan, gunakan:

<link rel="prefetch" href="RESOURCE_URL">
mertyildiran
sumber
Perlu dicatat bahwa mesin browser Mozilla hanya akan memuat prefetchsaat browser menganggur, yang ditentukan oleh nsIWebProgressListenerAPI. Lihat ini untuk info lebih lanjut.
Matthew Beckman
1
Menurut saya ini tidak benar-benar memblokir rendering: w3c.github.io/preload "Misalnya, aplikasi dapat menggunakan kata kunci pramuat untuk memulai pengambilan sumber daya CSS awal, prioritas tinggi, dan non-pemblokiran perenderan yang kemudian dapat diterapkan oleh aplikasi pada waktu yang tepat "
Michael Crenshaw
1
@MichaelCrenshaw benar, <link rel="preload">tidak tidak menghalangi rendering, saya percaya penulis salah paham definisi. Dari konten Pramuat MDN dengan rel = "preload" , "... yang ingin Anda mulai memuat lebih awal di siklus hidup halaman, sebelum mesin rendering utama browser dijalankan." Idenya adalah bahwa sumber daya diambil secepat mungkin, membuatnya lebih mungkin bahwa sumber daya tersedia saat diperlukan, misalnya saat <img>elemen sedang dirender.
MDMower
14

http://css-tricks.com/snippets/css/css-only-image-preloading/

Teknik # 1

Muat gambar pada keadaan biasa elemen, hanya geser dengan posisi latar belakang. Kemudian pindahkan posisi latar belakang untuk menampilkannya saat mengarahkan kursor.

#grass { background: url(images/grass.png) no-repeat -9999px -9999px; }
#grass:hover { background-position: bottom left; }

Teknik # 2

Jika elemen yang dimaksud sudah menerapkan gambar latar belakang dan Anda perlu mengubah gambar itu, cara di atas tidak akan berfungsi. Biasanya Anda akan memilih sprite di sini (gambar latar belakang gabungan) dan hanya menggeser posisi latar belakang. Tetapi jika itu tidak memungkinkan, coba ini. Terapkan gambar latar belakang ke elemen halaman lain yang sudah digunakan, tetapi tidak memiliki gambar latar belakang.

#random-unsuspecting-element { background: url(images/grass.png) no-repeat -9999px -9999px; }
#grass:hover { background: url(images/grass.png) no-repeat; }
Fatih Hayrioğlu
sumber
4
Selalu berikan konten tautan eksternal. Jika tidak, jawaban Anda tidak ada gunanya jika tautannya putus!
sra
@Fatih +1 untuk tautan yang sangat bagus. Versi yang lebih baru dari artikel terkait dengan 3 cara berbeda ada di sini perishablepress.com/3-ways-preload-images-css-javascript-ajax
xmojmr
@xmojmr Tidak ada solusi khusus CSS di tautan Anda.
Maks
10

coba dengan ini:

var c=new Image("Path to the background image");
c.onload=function(){
   //render the form
}

Dengan kode ini Anda melakukan pramuat gambar latar belakang dan merender formulir saat dimuat

mck89
sumber
mck89, terima kasih ini terlihat cukup bagus. Tapi, haruskah saya menggunakan kode ini di dalam 'head' atau inline? Maksud saya, haruskah saya mengisinya dengan html?
Kacang
Anda harus menggunakannya di kepala. Saya pikir Anda dapat menggunakannya di dalam $ (document] .ready
mck89
6

Untuk pramuat gambar latar belakang yang diatur dengan CSS, jawaban paling efisien yang saya dapatkan adalah versi modifikasi dari beberapa kode yang menurut saya tidak berfungsi:

$(':hidden').each(function() {
  var backgroundImage = $(this).css("background-image");
  if (backgroundImage != 'none') {
    tempImage = new Image();
    tempImage.src = backgroundImage;
  }
});

Manfaat besar dari ini adalah Anda tidak perlu memperbaruinya saat Anda membawa gambar latar belakang baru di masa mendatang, itu akan menemukan yang baru dan memuatnya sebelumnya!

Deminetix
sumber
Apakah saya memahaminya dengan benar bahwa Anda menambahkan elemen tersembunyi untuk setiap gambar? Itu tidak bisa memindai file CSS Anda untuk gambar kan? :)
bvdb
5

Jika Anda menggunakan kembali gambar bg ini di tempat lain di situs Anda untuk input formulir, Anda mungkin ingin menggunakan sprite gambar. Dengan cara itu Anda dapat mengelola gambar Anda secara terpusat (alih-alih memiliki pic1, pic2, pic3, dll ...).

Sprite umumnya lebih cepat untuk klien, karena mereka hanya meminta satu (walaupun sedikit lebih besar) file dari server, bukan beberapa file. Lihat artikel SO untuk manfaat lebih lanjut:

Sprite gambar CSS

Kemudian lagi, ini mungkin tidak membantu sama sekali jika Anda hanya menggunakan ini untuk satu formulir dan Anda benar-benar hanya ingin memuatnya jika pengguna meminta formulir kontak ... mungkin masuk akal.

http://www.alistapart.com/articles/sprites

ajhit406
sumber
Ya, CSS Sprite adalah cara yang harus dilakukan. Pastikan salah satu gambar di sprite tersebut muncul sebelum formulir tersembunyi diluncurkan (seperti saat pemuatan halaman).
Steve
1

bagaimana dengan memuat gambar latar belakang itu di suatu tempat yang tersembunyi. Dengan cara itu akan dimuat saat halaman dibuka dan tidak akan memakan waktu lama setelah formulir dibuat menggunakan ajax:

body {
background: #ffffff url('img_tree.png') no-repeat -100px -100px;
}
Santi
sumber
1

Anda bisa menggunakan plugin jQuery waitForImage atau Anda dapat menempatkan gambar Anda ke div tersembunyi atau (lebar: 0 dan tinggi: 0) dan menggunakan acara onload pada gambar.

Jika Anda hanya memiliki 2-3 gambar, Anda dapat mengikat peristiwa dan memicunya dalam sebuah rantai sehingga setelah setiap gambar Anda dapat melakukan beberapa kode.

pengguna1236048
sumber
1

Satu-satunya cara adalah dengan Base64 menyandikan gambar dan menempatkannya di dalam kode HTML sehingga tidak perlu menghubungi server untuk mengunduh gambar.

Ini akan menyandikan gambar dari url sehingga Anda dapat menyalin kode file gambar dan memasukkannya ke halaman Anda seperti ...

body {
  background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...);
}
mheager
sumber
2
jika Anda ingin menggunakan gambar yang sama lagi di CSS Anda ... itu tidak akan di-cache dan Anda harus memuatnya lagi.
vsync
1

Jika tidak ada cara untuk mengubah kode CSS dan memuat gambar dengan aturan CSS untuk :beforeatau :afterelemen semu, pendekatan lain dengan kode JavaScript yang melintasi aturan CSS dari stylesheet yang dimuat dapat digunakan. Untuk membuatnya berfungsi, skrip harus disertakan setelah stylesheet di HTML, misalnya, sebelum bodytag penutup atau setelah stylesheet.

getUrls() {
    const urlRegExp = /url\(('|")?([^'"()]+)('|")\)?/;

    let urls = [];
    for (let i = 0; i < document.styleSheets.length; i++) {
        let cssRules = document.styleSheets[i].cssRules;
        for (let j = 0; j < cssRules.length; j++) {
            let cssRule = cssRules[j];
            if (!cssRule.selectorText) {
                continue;
            }

            for (let k = 0; k < cssRule.style.length; k++) {
                let property = cssRule.style[k],
                    urlMatch = cssRule.style[property].match(urlRegExp);
                if (urlMatch !== null) {
                    urls.push(urlMatch[2]);
                }
            }
        }
    }
    return urls;
}

preloadImages() {
    return new Promise(resolve => {
        let urls = getUrls(),
            loadedCount = 0;

        const onImageLoad = () => {
            loadedCount++;
            if (urls.length === loadedCount) {
                resolve();
            }
        };

        for (var i = 0; i < urls.length; i++) {
            let image = new Image();
            image.src = urls[i];
            image.onload = onImageLoad;
        }
    });
}

document.addEventListener('DOMContentLoaded', () => {
    preloadImages().then(() => {
        // CSS images are loaded here
    });
});
ezze.dll
sumber
0

Jika elemen halaman dan gambar latar belakangnya sudah ada di DOM (yaitu Anda tidak membuat / mengubahnya secara dinamis), gambar latar belakangnya sudah dimuat. Pada saat itu, Anda mungkin ingin melihat metode kompresi :)


sumber
mmmm ... poin bagus cpharmston, dan ini menjelaskan mengapa masalah tetap ada bahkan dengan gambar yang di-cache. Jadi, apakah itu berarti tidak ada solusi?
Peanuts
Buat gambar yang lebih kecil! JPEG mudah dikompresi, ada alat baris perintah untuk mengurangi ukuran PNG ( pmt.sourceforge.net/pngcrush ), dan Anda dapat mengurangi jumlah warna pada gambar untuk mengurangi ukuran GIF. Tentu saja, Anda juga dapat mencari layanan internet yang lebih cepat;)