美文网首页
针对页面的全部静态图片加载情况上报服务器的思考🤔

针对页面的全部静态图片加载情况上报服务器的思考🤔

作者: 尤小小 | 来源:发表于2018-12-26 11:37 被阅读4次

    最近遇到一上神,称他为上神,是基于他的识人能力、对行业痛点的思考以及解决问题的能力,这些都足以让他成为我的师傅,其实我跟他也就简单的聊十几分钟,他就可以找到我的问题所在,帮我认识自己,这是自我认知的有效途径之一。

    我的问题一:不爱思考

    其实在两年前,我就知道我有这个毛病,没想到我认为的小毛病,现在却成为限制我发展的瓶颈。当上神指出我的问题的时候,我还“狡辩”说,太过于专注业务的开发,而没去做这些思路。上神指责我,我思维就有问题,在做的时候就应该思考,而不是只做不思考。

    培养思维

    想想也是只有不断的思考,抛出问题,虽然当时没有搞懂,没有满意的答案,但是脑海里有这个问题库。在后面的读书、查资料、做业务、沟通交流的时候,就能碰上每个问题,就消灭掉一个问题。与此同时,随着问题的抛出,问题的延伸,自然而然对这个领域有了一定的思想沉淀,不管是深度和广度上都有了一定的扩展。

    修炼内功

    我也不应该去逃避现实,面对自身的短板,去调整自己才是上上策,才能迎接更好的自己。只有达到一定的层次,夯实基础才有资格成为上神的徒弟。毕竟我算不上天赋异禀,没有深厚的内功。上神又有什么理由要收我为徒。

    如何监听当前页面上的所有img图片的加载情况

    言归正传,回到今天的主题:如何监听当前页面上的所有img图片的加载情况,每张图片什么时候开始加载,什么时候加载成功,或者加载失败。将图片的加载情况汇总,然后上报到服务器。

    最初思考

    最近在做vue项目,找了一个正在开发业务练手,我选择在mounted生命周期里去处理。

    最初的思路是:先获取到当前页面所有的img图片,遍历所有图片,遍历到每张图片开始记录加载开始时间,同时监听图片的加载成功、失败、缓存的时间以及状态。计数统计处理的图片,当统计完成,向服务上报。

    imgLoadCtrl();
    
    function imgLoadCtrl() {
      let imgs = document.querySelectorAll('img');
      let arr = [] // 图片的加载情况
      let count = 0 // 图片加载完成张数(包含加载失败图片 和缓存图片)
      let progress = 0 // 图片加载进度
    
      // console.time()
      Array.from(imgs).forEach((item, index) => {
        arr[index] = {
          startTime: +new Date()
        };
    
        // 获取新加载的图片
        item.onload = (e) => {
          addLoadMessage(arr, item, index, 'loadFinished')
        }
    
        // 获取加载失败的图片
        item.onerror = (e) => {
          addLoadMessage(arr, item, index, 'loadError')
        }
    
        // 获取缓存的图片
        item.oncomplete = (e) => {
          addLoadMessage(arr, item, index, 'loadCache')
        }
      })
    
      // 图片加载情况数据整理
      function addLoadMessage(arr, item, index, load) {
        arr[`${index}`].endTime = +new Date()
        arr[`${index}`].src = item.getAttribute('src')
        arr[`${index}`].index = index
        arr[`${index}`].loadTime = (arr[`${index}`].endTime - arr[`${index}`].startTime) + 'ms'
        arr[`${index}`].load = load 
        // console.log(arr)
        sumAdd()                
      }
    
      // 计数函数
      function sumAdd() {
        count++
        // 预留图片加载进度
        progress = Math.ceil(count/7*100);
        (progress>=100) ? 100 : progress
        // console.log(progress) 
        
        // 图片加载完成 向服务器上报
        if (count == arr.length) {
          message()
        }
      }
    
      // 向服务器发送当前页面的图片加载情况
      function message () {
        let imgObject = {
          url: location.href,
          count: count,
          loadArr: arr
        } 
    
        // 请求接口
        console.log(imgObject)
      }
      // console.timeEnd()      
    }
    
    

    向服务器回报:

    • (1)当前页面地址;
    • (2)图片张数;
    • (3)每张图片的加载情况;
    {url: "https://m2.qschou.com/v8/glowwormPlan/guide.html?islogin=1&islogin=1", count: 4, loadArr: Array(4)}
    count: 4
    loadArr: Array(4)
    0: {startTime: 1545284954692, endTime: 1545284954760, src: "https://static2.qschou.com/img/v8/glowwormPlan/guide/assets/g-head-bg.png", index: 0, loadTime: "68ms", …}
    1: {startTime: 1545284954692, endTime: 1545284954781, src: "https://static2.qschou.com/img/v8/glowwormPlan/guide/assets/g-icon1.png", index: 1, loadTime: "89ms", …}
    2: {startTime: 1545284954692, endTime: 1545284954784, src: "https://static2.qschou.com/img/v8/glowwormPlan/guide/assets/g-icon2.png", index: 2, loadTime: "92ms", …}
    3: {startTime: 1545284954692, endTime: 1545284954795, src: "https://static2.qschou.com/img/v8/glowwormPlan/guide/assets/g-icon3.png", index: 3, loadTime: "103ms", …}
    length: 4
    __proto__: Array(0)
    url: "https://m2.qschou.com/v8/glowwormPlan/guide.html?islogin=1&islogin=1"
    __proto__: Object
    

    发现新问题

    看上去这样处理,好像可以得到,一个当前页面的所有图片的加载情况。实际上并没有拿到图片真正开始加载的时间。而且Date对象的方法都只能精确到毫秒级别(一秒的千分之一),想到得到精确的时间差别Date对象也是无能为力,无法知道图片加载的时间进度。

    遇上performance

    在ES5中有一个“高精度时间戳API”,部署在 performance 对象。它的精度可以达到微秒(1毫秒的千分之一)。

    performance.getEntries() 带给我们的惊喜

    浏览器在获取网页时,会对网页中每一个对象(脚本文件、样式表、图片文件等等)发出一个http请求。performance.getEntries方法以数组形式,返回这些请求的时间统计信息,有多少个请求,返回数组就会多少个成员。该方法只能在浏览器中使用。window.performance.getEntries(),返回一个高精度的时间戳对象,每个属性的单位是微秒(microsecond), 即百万分之一秒。

    萤火虫计划攻略 页面上测试performance.getEntries()

    performance.png

    performance.getEntries()可以获取到所有资源的请求信息。我们需要过滤掉无用的资源信息,只保留图片。在过滤图片的

    let arr = window.performance.getEntries()
    let newArr = []
    
    arr.forEach((item) => {
      if (item.initiatorType == 'img' && item.name.indexOf('https://hm.baidu.com') == -1 && item.name.indexOf('https://recevapi.qschou.com/dtas') == -1) {
        newArr.push(item)
      }
    })
    
    console.log(newArr) 
    

    拿到所有图片的请求时间统计信息。取performance.getEntries()[0] 第一张图片的统计信息:

    connectEnd: 0 // 返回浏览器与服务器之间的连接建立时的Unix毫秒时间戳。如果建立的时持久连接,则返回值等同与fetchStart属性的值。连接建立指的是所有握手和认证过程全部结束。
    connectStart: 0 // 返回http请求开始向服务器发送时的Unix毫秒时间戳。如果使用持久连接(persistent connection),则返回等同于fetchStart属性的值
    decodedBodySize: 0 
    domainLookupEnd: 0 //返回域名查询结束时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。
    domainLookupStart: 0// 返回域名查询开始时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回等同与fetch属性的值。
    duration: 0
    encodedBodySize: 0
    entryType: "resource"
    fetchStart: 774.6000000042841//返回浏览器准备使用http请求读取文档时的Unix毫秒时间戳。该事件在网页查询本地缓存之前发生。
    initiatorType: "img"
    name: "https://static2.qschou.com/img/v8/glowwormPlan/guide/assets/g-head-bg.png"
    nextHopProtocol: "http/1.1"
    redirectEnd: 0 // 返回最后一个http跳转结束时的 unix毫秒时间戳。如果没有跳转,或者不是通一个域名内部的跳转,则返回值为0
    redirectStart: 0 // 返回最后一个http跳转开始时的 unix毫秒时间戳。如果没有跳转,或者不是通一个域名内部的跳转,则返回值为0
    requestStart: 0 // 返回浏览器向服务器发出http请求时(或从本地缓存读取)最后一个字节时的毫秒时间戳。
    responseEnd: 774.6000000042841 // 返回浏览器从服务器收到最后一个字节时的毫秒时间戳
    responseStart: 0
    secureConnectionStart: 0//返回浏览器与服务器开始安全连接的握手时的毫秒时间戳。如果当前网页不需要安全连接,则返回0
    serverTiming: []
    startTime: 774.6000000042841
    transferSize: 0
    workerStart: 0
    

    其中重要的是 duration、fetchStart、responseEnd、startTime,我们就知道图片的开始加载时间,结束加载时间,以及加载持续时间。

    duration: 24.900000003981404 //加载持续时间

    fetchStart: 570.2999999921303 //返回浏览器准备使用HTTP请求读取文档时的毫秒时间戳

    responseEnd: 595.1999999961117 //返回浏览器从服务器收到最后一个字节时的毫秒时间戳

    startTime: 570.2999999921303//开始时间加载时间

    TODO List

    背景图片的加载情况

    封装成SDK

    启node服务 创建数据库和表

    相关文章

      网友评论

          本文标题:针对页面的全部静态图片加载情况上报服务器的思考🤔

          本文链接:https://www.haomeiwen.com/subject/fwfhlqtx.html