Giter Club home page Giter Club logo

web-performance's People

Contributors

ailingangel avatar

Watchers

 avatar

web-performance's Issues

图片懒加载和图片预加载

图片懒加载和图片预加载是常见的两种进行性能优化的手段

图片预加载

图片预加载就是提前把要用到的图片下载下来,然后等到需要查看的图片的时候浏览器直接从缓存中读取

实现原理: 利用 new Image(), 当新建一个图片对象时,并且给这个对象赋值src属性浏览器就会自动将图片缓存下来; 然后后续用到相同src路径的Img标签会自动从缓存中读取图片文件。缓存时间的话,我测试了一下感觉就是浏览器当前的会话~~~~~

方法一: 使用js预加载图片

function loadImage(url, callback) {    
    var img = new Image(); // 创建一个Image对象,实现图片的预下载    
    img.onload = function(){
        img.onload = null; // 解决闭包的问题
        callback(img);
    }
    img.src = url;
}

注意事项:

  • 项目中可以先加载较小的缩略图,再预加载大图,这样可以减少图片空白的时间
  • 图片预加载通常用在鼠标Hover到img上时切换图片的效果

方法二:使用css预加载图片

// 放在onload事件回调里是为了不方案html的下载,而是等到html文件下载完成再开始预加载
window.onload = function() {
    let style = document.getElementById("preload-01").style
    style.display = 'none';
    style.background = "url(http://domain.tld/image-01.png) no-repeat";
}

方法三:使用ajax预加载(js, css)

window.onload = function() {
    setTimeout(function() {
        // XHR to request a JS and a CSS  
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://domain.tld/preload.js');
        xhr.send('');
        xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://domain.tld/preload.css');
        xhr.send('');
        // preload image  
        new Image().src = "http://domain.tld/preload.png";
    }, 1000);
};

图片懒加载

图片懒加载就是一开始访问一个页面的时候并不会下载所有的图片,而是等到满足一定条件(条件应该根据具体的需求来定,通常应该是图片元素出现在可是区域中),才开始下载图片。

实现原理: 不给Img标签赋值src属性,浏览器就不会开始下载图片,利用html元素的data自定义属性来设置图片的下载地址,比如data-url,等到满足条件,就从data-url中取出图片的地址然后赋值给图片的src属性

<img src="" data-url="http://your.image.png" />

下载图片的函数

function loadImg(el){
  let url = el.dataset.url;
  el.src = url;
}

判断元素是否在可视区域内

方法一(不推荐!这种方式是在是太麻烦了!各种算算算!!!!)

  • 通过document.documentElement.clientHeight 获取屏幕的可视窗口高度
  • 通过document.documentElement.scrollTop获取浏览器窗口顶部与文档顶部之间的距离
  • 通过element.offsetTop获取元素相对于文档顶部的距离

方法二

  • 利用element.getBoundingClientRect api 返回的top, bottom, right, left 都是相对于视口左上角而言的
  • 利用这个方法需要添加到鼠标滚轮事件中,会触发的比较频繁,因此可以结合函数节流来做
function isInViewPort(element) {
    let windowHeight = window.innerHeight || document.documentElement.clientHeight;
    let windowWidth = window.innerWidth || document.documentElement.clientWidth;
    let rect = element.getBoundingClientRect();
    if (rect.top > 0 && (rect.top + rect.height) <= windowHeight && rect.left > 0 && ((rect.left + rect.width) < windowWidth)) {
        return true;
    }
    return false;
}

window.addEventListener('wheel', throttle(function() {
    let imgs = document.getElementsByTagName('img');
    imgs.forEach(img => {
        if (isInViewPort(img) && !img.hasLoaded) {
            loadImg(img);
            img.onload = img.onerror = () => img.hasLoaded = true;
        }
    })
}, 500));

方法三

  • 利用 IntersectionObserver api, 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法
  • intersectionRatio <=0时完全不可见, 等于1的时候完全可见
let imgs = document.getElementsByTagName('img');
var ob = new IntersectionObserver(function(entries) {
  entries.forEach(entry=>{
    let el = entry.target;
    if(entry.intersectionRatio > 0) {
      loadImg(el);
      entry.onload = entry.onerror = ()=>ob.unobserve(el);
    }
  });
});

Array.from(imgs).forEach(img=>ob.observe(img))

事件代理

事件流:指元素接收事件的顺序;
事件捕获: 不那么具体的元素(父元素)先接收到事件,具体的元素后接收到事件
事件冒泡:具体的元素(子元素)先接受事件,然后父元素再接受事件

事件代理

事件代理利用了事件冒泡的机智,在父元素指定一个事件处理程序就可以管理一类事件

优点:

  • 添加到页面上的事件处理程序的数量和页面的性能有关,添加的事件处理函数越多占用的内存也就越多。利用事件代理只需要给父元素添加一个事件处理程序,就可以帮助处理子元素这类的事件
  • 添加一个新的子元素时不需要单独处理这个子元素的事件
  • 删除一个子元素时也不需要单独移除这个元素的事件

预加载和预获取

预加载pre-load

浏览器会预先加载声明在html中的资源,但是可以通过在js或者css的标签中添加preload让浏览器也预先加载css或者js资源,如下:

<link href=/wa/js/chunk-vendors.44474edb.js rel=preload as=script>

预获取pre-fetch

浏览器在后台空闲时获取将来可能用到的资源,并将他们存储在浏览器的缓存中

  • link prefetching
<link href=/wa/js/slot.546afd12.js rel=prefetch>
  • dns prefetching
<link rel="dns-prefetch" href="//img.alicdn.com"></link>
  • pre-rendering
    在后台tab中加载显示所有的资源

预获取和预加载的区别

  • 预加载专注于当前页面,以较高的优先级下载
  • 预获取专注于下一个页面要用到的资源,以较低的优先级下载

预连接 pre-connect

浏览器在一个http请求正式发送给服务器前执行一些操作,包括dns解析,tcp握手等

<link href="https://cdn.domain.com" rel="preconnect" crossorigin>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.