shinsenter / defer.js

🥇 A lightweight JavaScript library that helps you lazy load (almost) anything. Defer.js is dependency-free, highly efficient, and optimized for Web Vitals.
https://shinsenter.github.io/defer.js/
MIT License
277 stars 45 forks source link

Is there a way defer DOM item while it's outside on the screen. #136

Closed ionurboz closed 1 month ago

ionurboz commented 1 month ago

Is there a way defer DOM item while it's outside on the screen? I'm meaning "defer while it's invisible". In this case the DOM item start load when it's visible of the screen.

shinsenter commented 1 month ago

Hi @ionurboz

I genuinely still don't fully understand your question.

The functionality of Defer.dom() is closely tied to the IntersectionObserver API supported by browsers. This requires the DOM elements to have at least 1px visible on the webpage (whether inside or outside the viewport). Therefore, you cannot defer DOM elements that are hidden (those with attributes like display:none, visibility:hidden, or <input type="hidden">, etc.).

Additionally, if you want to reveal an element before it enters the viewport, you can pass Intersection observer options (for example, {rootMargin: '200%'}) to the 5th argument of the Defer.dom() to reveal the element before it enters the viewport.

You can check my example of lazy-loading a Twitter post with Intersection observer options are set, under Defer.js() section.

<div id="demo-twitter">
  <a class="lazy-timeline" <!-- the original is class="twitter-timeline" -->
    href="https://twitter.com/xai"
    data-chrome="nofooter noborders"
    data-width="480" data-height="600" data-dnt="true" data-theme="dark">
    Tweets by @xAI
  </a>

  <blockquote class="lazy-tweet" data-width="480" <!-- the original is class="twitter-tweet" -->>
    <!-- content is truncated -->
  </blockquote>
</div>
<script>
Defer.js('https://platform.twitter.com/widgets.js', 'twitter-sdk', 0, function() {
  Defer.dom('.lazy-timeline', 0, 'twitter-loaded', function(node) {
    // adds the correct class name for tweet element
    node.className = 'twitter-timeline';

    // For better performance,
    // we only search within the parent DOM tree for uninitialized widgets
    twttr.widgets.load(node.parentNode);
    console.info('Twitter timeline is loaded.'); // debug
  }, {rootMargin: "200%"});

  Defer.dom('.lazy-tweet', 0, 'twitter-loaded', function(node) {
    // adds the correct class name for timeline element
    node.className = 'twitter-tweet';

    // For better performance,
    // we only search within the parent DOM tree for uninitialized widgets
    twttr.widgets.load(node.parentNode);
    console.info('Twitter post is loaded.'); // debug
  }, {rootMargin: "200%"});
});
</script>

Best regards