Load a low-res background image first, then a high-res one

前端 未结 6 898
陌清茗
陌清茗 2020-12-04 17:56

I am trying to optimize the size of my site when it is being outputted to the client. I am down to 1.9MB and 29KB when caching. The issue is that the first load contains an

6条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-04 19:00

    Here's the method I use...

    CSS:

    #div_whatever {
       position: whatever;
       background-repeat: no-repeat;
       background-position: whatever whatever; 
       background-image: url(dir/image.jpg);
       /* image.jpg is a low-resolution at 30% quality. */
    }
    
    #img_highQuality {
        display: none;
    }
    

    HTML:

    
    
    
    

    JQUERY:

    $("#img_highQuality").off().on("load", function() {
        $("#div_whatever").css({
            "background-image" : "url(dir/image.png)"
        });
    });
    // Side note: I usually define CSS arrays because
    // I inevitably want to go back and add another 
    // property at some point.
    

    What happens:

    1. A low-res version of the background quickly loads.
    2. Meanwhile, the higher resolution version is loading as a hidden image.
    3. When the high-res image is loaded, jQuery swaps the div's low-res image with the high-res version.

    PURE JS VERSION

    This example would be efficient for changing one to many elements.

    CSS:

    .hidden {
       display: none;
    }
    
    #div_whatever {
       position: whatever;
       background-repeat: no-repeat;
       background-position: whatever whatever; 
       background-image: url(dir/image.jpg);
       /* image.jpg is a low-resolution at 30% quality. */
    }
    

    HTML:

    JAVASCRIPT:

    function upgradeImage(object) {
        var id = object.id;
        var target = "div_" + id.substring(4);
    
        document.getElementById(target).style.backgroundImage = "url(" + object.src + ")";
    }
    

    UPDATE / ENHANCEMENT (1/31/2017)

    This enhancement is inspired by gdbj's excellent point that my solution results in the image path being specified in three locations. Although I didn't use gdbj's addClass() technique, the following jQuery code is modified to extract the image path (rather than it being hardwired into the jQuery code). More importantly, this version allows for multiple low-res to high-res image substitutions.

    CSS

    .img_highres {
      display: none;
    }
    
    #div_whatever1 {
      width: 100px;
      height: 100px;
      background-repeat: no-repeat;
      background-position: center center;
      background-image: url(PATH_TO_LOW_RES_PHOTO_1);
    }
    
    #div_whatever2 {
      width: 200px;
      height: 200px;
      background-repeat: no-repeat;
      background-position: center center;
      background-image: url(PATH_TO_LOW_RES_PHOTO_2);
    }
    

    HTML

    JQUERY

      $(function() {
          $(".img_highres").off().on("load", function() {
             var id = $(this).attr("id");
             var highres = $(this).attr("src").toString();
             var target = "#div_" + id.substring(4);
             $(target).css("background-image", "url(" + highres + ")");
          });
       });
    

    What's happens:

    1. Low res images are loaded for each of the divs based on their CSS background-image settings. (Note that the CSS also sets the div to the intended dimensions.)
    2. Meanwhile, the higher resolution photos are being loaded as hidden images (all sharing a class name of img_highres).
    3. A jQuery function is triggered each time an img_highres photo completes loading.
    4. The jQuery function reads the image src path, and changes the background image of the corresponding div. In the example above, the naming convention is "div_[name]" for the visible divs and "img_[same name]" for the high res images loaded in the background.

提交回复
热议问题