วิธีโหลดภาพแบบไดนามิก (หรืออย่างเกียจคร้าน) เมื่อผู้ใช้เลื่อนดู


97

ฉันสังเกตเห็นสิ่งนี้ในเว็บไซต์ "สมัยใหม่" จำนวนมาก (เช่นการค้นหาภาพบน Facebook และ Google) ซึ่งรูปภาพด้านล่างของฝาพับจะโหลดเฉพาะเมื่อผู้ใช้เลื่อนหน้าลงมามากพอที่จะนำภาพเหล่านั้นเข้าไปในพื้นที่วิวพอร์ตที่มองเห็นได้ ( ตามแหล่งที่มาของการดูหน้าเว็บจะแสดงXจำนวน<img>แท็ก แต่ไม่ได้ดึงมาจากเซิร์ฟเวอร์ทันที ) เทคนิคนี้เรียกว่าอะไรทำงานอย่างไรและมีกี่เบราว์เซอร์ทำงานอย่างไร และมีปลั๊กอิน jQuery ที่สามารถบรรลุพฤติกรรมนี้ด้วยการเข้ารหัสขั้นต่ำหรือไม่

แก้ไข

โบนัส: ใครสามารถอธิบายได้ว่ามี "onScrolledIntoView" หรือเหตุการณ์ที่คล้ายกันสำหรับองค์ประกอบ HTML ถ้าไม่ปลั๊กอินเหล่านี้ทำงานอย่างไร


คุณต้องการเพียงการโหลดภาพแบบขี้เกียจหรือไม่? หากคุณต้องการเนื้อหาที่ขี้เกียจโหลดปลั๊กอิน infinite scroll คือคำตอบที่ถูกต้อง
โซจู

@rsp @jwegner @Nicholas ขอโทษด้วย แต่นั่นไม่ใช่สิ่งที่ Salman ถาม
Alec Smart

@soju: ฉันสนใจแค่ขี้เกียจโหลดภาพ; แต่ฉันอาจมองไปที่ความเป็นไปได้อื่น ๆ ในอนาคต (ค่อนข้างไกล)
Salman A

21
ทำให้คุณสงสัยว่าทำไมพฤติกรรมเริ่มต้นของเบราว์เซอร์จึงไม่โหลดเฉพาะภาพที่มองเห็นได้ ลองนึกดูว่าในช่วง 18 ปีที่ผ่านมาแบนด์วิดท์จะประหยัดไปได้เท่าใดหากเป็นเช่นนั้น!
Matthew Lock

2
ในขณะที่ฉันเข้าใจเหตุผลเบื้องหลังการโหลดที่ขี้เกียจ ... ฉันทนไม่ได้จริงๆเมื่อฉันไปที่ไซต์ที่ใช้วิธีนั้น ภาพที่กะพริบทำให้ฉันแทบคลั่ง! :)
Booski

คำตอบ:


64

คำตอบบางส่วนมีไว้สำหรับเพจที่ไม่มีที่สิ้นสุด สิ่งที่ซัลมานถามคือขี้เกียจโหลดภาพ

เสียบเข้าไป

การสาธิต

แก้ไข: ปลั๊กอินเหล่านี้ทำงานอย่างไร

นี่คือคำอธิบายที่เรียบง่าย:

  1. ค้นหาขนาดหน้าต่างและค้นหาตำแหน่งของรูปภาพทั้งหมดและขนาด
  2. หากรูปภาพไม่อยู่ในขนาดหน้าต่างให้แทนที่ด้วยตัวยึดที่มีขนาดเท่ากัน
  3. เมื่อผู้ใช้เลื่อนลงและตำแหน่งของภาพ <scroll + window height ภาพจะถูกโหลด

ในแอปพลิเคชันพวกเขาจะไม่ทำงานเหมือนกันหรือ? การเลื่อนที่ไม่มีที่สิ้นสุดในคอลัมน์เดียวของภาพจะเหมือนกับการขี้เกียจโหลดใช่ไหม? บางทีฉันก็สับสน
jwegner

1
@jwegner Infinite scroll จะช่วยให้คุณเพิ่มรายการใหม่ที่ด้านล่างของหน้าเมื่อผู้ใช้มาถึง (หรือเข้าใกล้) ด้านล่าง รูปภาพที่โหลดแบบขี้เกียจอาจมีตัวยึดที่มีขนาดเท่ากันบนหน้าโดยที่รูปภาพจะโหลดเองเมื่อเลื่อน ดังนั้นหลังสามารถโหลดได้โดยไม่ส่งผลกระทบต่อเค้าโครงหน้า
Annika Backstrom

ใช้งานได้ดีบนเบราว์เซอร์เดสก์ท็อปและ iOS แต่ใช้ไม่ได้กับ Android (รวมถึง 3.x / 4.x) คิดว่าทำไม? ไม่รองรับเหตุการณ์เลื่อนหรือไม่
lahsrah

ฉันกำลังอ่านเอกสารสำหรับปลั๊กอินนี้และดูเหมือนว่าจะดีมาก จะใช้สิ่งนี้ในโครงการถัดไปของฉัน
The Muffin Man

นี่คือปลั๊กอินที่เกี่ยวข้องซึ่งอาจใช้งานได้ในลักษณะเดียวกัน: afarkas.github.io/lazysizesยกเว้นฉันเชื่อว่ามันมีประสิทธิภาพมากกว่าและใช้สิ่งที่มีอยู่แล้วได้มากขึ้น (เช่นไม่จำเป็นต้องใช้ตัวยึด แต่คุณสามารถมีได้หากคุณ ต้องการ).
cregox

10

( แก้ไข:แทนที่ลิงก์ที่เสียด้วยสำเนาที่เก็บถาวร)

Dave Artz จาก AOL ได้พูดคุยเกี่ยวกับการเพิ่มประสิทธิภาพที่ jQuery Conference Boston เมื่อปีที่แล้ว AOL ใช้เครื่องมือที่เรียกว่า Sonar สำหรับการโหลดตามความต้องการตามตำแหน่งการเลื่อน ตรวจสอบโค้ดสำหรับรายละเอียดว่าจะเปรียบเทียบ scrollTop (และอื่น ๆ ) กับการชดเชยองค์ประกอบอย่างไรเพื่อตรวจสอบว่ามองเห็นบางส่วนหรือทั้งหมดขององค์ประกอบ

jQuery Sonar

พูดคุยเกี่ยวกับเดฟ Sonar ในภาพนิ่งเหล่านี้ โซนาร์เริ่มต้นในสไลด์ 46 ในขณะที่การอภิปราย "โหลดตามความต้องการ" โดยรวมจะเริ่มในสไลด์ 33


ฉันสงสัยว่าสิ่งนี้เปรียบเทียบกับ lazyload ของ Appelsinii ได้อย่างไร? มีน้ำหนักเบากว่าหรือไม่? ใช้งานได้กับทุกเบราว์เซอร์หรือไม่? ฉันจำได้ว่า lazyload ไม่ทำงานบน Chrome
deathlock

8

ฉันคิดวิธีพื้นฐานของตัวเองซึ่งดูเหมือนจะใช้ได้ดี (จนถึงตอนนี้) อาจมีหลายสิบอย่างที่อยู่สคริปต์ยอดนิยมที่ฉันไม่ได้นึกถึง

หมายเหตุ - โซลูชันนี้รวดเร็วและใช้งานง่าย แต่แน่นอนว่าไม่ดีต่อประสิทธิภาพ ตรวจสอบIntersection Observerใหม่อย่างแน่นอนตามที่Apoorvกล่าวถึงและอธิบายโดยdevelopers.googleหากประสิทธิภาพเป็นปัญหา

JQuery

$(window).scroll(function() {
    $.each($('img'), function() {
        if ( $(this).attr('data-src') && $(this).offset().top < ($(window).scrollTop() + $(window).height() + 100) ) {
            var source = $(this).data('src');
            $(this).attr('src', source);
            $(this).removeAttr('data-src');
        }
    })
})

ตัวอย่างโค้ด html

<div>
    <img src="" data-src="pathtoyour/image1.jpg">
    <img src="" data-src="pathtoyour/image2.jpg">
    <img src="" data-src="pathtoyour/image3.jpg">
</div>

อธิบาย

เมื่อเลื่อนหน้าแล้วแต่ละภาพในหน้าจะถูกตรวจสอบ ..

$(this).attr('data-src') - หากรูปภาพมีแอตทริบิวต์ data-src

และภาพเหล่านั้นอยู่ห่างจากด้านล่างของหน้าต่างแค่ไหน ..

$(this).offset().top < ($(window).scrollTop() + $(window).height() + 100)

ปรับ + ​​100 ตามที่คุณต้องการ (- 100 เช่น)

var source = $(this).data('src');- รับค่าของdata-src=URL รูปภาพ

$(this).attr('src', source); - ใส่ค่านั้นลงใน src=

$(this).removeAttr('data-src'); - ลบแอตทริบิวต์ data-src (เพื่อให้เบราว์เซอร์ของคุณไม่ต้องเสียทรัพยากรไปยุ่งกับภาพที่โหลดไปแล้ว)

การเพิ่มรหัสที่มีอยู่

ในการแปลง html ของคุณในตัวแก้ไขเพียงแค่ค้นหาและแทนที่src="ด้วยsrc="" data-src="


1
สมบูรณ์แบบ อวยพร fam 🙏
LifterCoder

5

มีปลั๊กอินการเลื่อนแบบไม่มีที่สิ้นสุดที่ดีที่นี่

ฉันไม่เคยตั้งโปรแกรมด้วยตัวเอง แต่ฉันคิดว่านี่คือวิธีการทำงาน

  1. เหตุการณ์ถูกผูกไว้กับการเลื่อนหน้าต่าง

    $(window).scroll(myInfinteScrollFunction);
    
  2. ฟังก์ชั่นที่เรียกจะตรวจสอบว่าเลื่อนด้านบนมากกว่าขนาดหน้าต่างหรือไม่

    function myInfiniteScrollFunction() {  
        if($(window).scrollTop() == $(window).height())  
        makeAjaxRequest();  
    }
    
  3. มีการร้องขอ AJAX โดยระบุผลลัพธ์ # ที่จะเริ่มต้นจำนวนที่จะคว้าและพารามิเตอร์อื่น ๆ ที่จำเป็นสำหรับการดึงข้อมูล

    $.ajax({
        type: "POST",
        url:  "myAjaxFile.php",
        data: {"resultNum": 30, "numPerPage": 50, "query": "interesting%20icons" },
        success: myInfiniteLoadFunction(msg)
    });
    
  4. ajax ส่งคืนเนื้อหาบางส่วน (เป็นไปได้มากที่สุดในรูปแบบ JSON) และส่งต่อไปยังฟังก์ชัน loadnig

หวังว่าจะสมเหตุสมผล


3

ขี้เกียจโหลดภาพโดยการแนบ Listener เพื่อเลื่อนเหตุการณ์หรือโดยการใช้ setInterval นั้นไม่มีประสิทธิภาพสูงเนื่องจากการเรียกใช้ getBoundingClientRect () แต่ละครั้งบังคับให้เบราว์เซอร์ต้องจัดวางใหม่ทั้งหน้าและจะทำให้เว็บไซต์ของคุณมีปัญหามาก

ใช้Lozad.js (เพียง 569 ไบต์โดยไม่มีการอ้างอิง) ซึ่งใช้IntersectionObserverในการโหลดภาพแบบเกียจคร้าน


คุณสามารถเพิ่มPolyfillแบบไดนามิกในกรณีที่ไม่รองรับเบราว์เซอร์
Apoorv Saxena

การสนับสนุนเบราว์เซอร์ดีขึ้นมากในทุกวันนี้ - ฉันสามารถ
ใช้ได้ไหม

1

มีดสวิสกองทัพของภาพโหลดขี้เกียจเป็น YUI ของImageLoader

เนื่องจากปัญหานี้มีมากกว่าการดูตำแหน่งเลื่อน


0

ลิงก์นี้ใช้งานได้สำหรับฉันการสาธิต

1. โหลดปลั๊กอิน jQuery loadScroll หลังไลบรารี jQuery แต่ก่อนแท็กเนื้อหาปิด

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script><script src="jQuery.loadScroll.js"></script>

2. เพิ่มรูปภาพลงในหน้าเว็บของคุณโดยใช้แอตทริบิวต์ Html5 data-src คุณยังสามารถแทรกตัวยึดตำแหน่งโดยใช้แอตทริบิวต์ src ของ img ปกติ

<img data-src="1.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="2.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="3.jpg" src="Placeholder.jpg" alt="Image Alt">

3. เรียกใช้ปลั๊กอินบนแท็ก img และระบุระยะเวลาของเอฟเฟกต์เฟดอินเมื่อรูปภาพของคุณถูกแสดง

$('img').loadScroll(500); // in ms

0

Im ใช้jQuery ขี้เกียจ ฉันใช้เวลาประมาณ 10 นาทีในการทดสอบและหนึ่งหรือสองชั่วโมงในการเพิ่มลิงก์รูปภาพส่วนใหญ่ในเว็บไซต์ของฉัน ( CollegeCarePackages.com ) ฉันไม่มีความสัมพันธ์แบบNO (ไม่มี / ศูนย์)ใด ๆ กับนักพัฒนา แต่มันช่วยให้ฉันประหยัดเวลาได้มากและโดยพื้นฐานแล้วช่วยปรับปรุงอัตราตีกลับของเราสำหรับผู้ใช้มือถือและฉันขอขอบคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.