图片那点事

273 阅读3分钟

背景介绍

拿破仑说过“一张图片胜过千言万语”

网站上的图片更是尤为重要,众所周知,一个页面上如果图片很多,很大,会导致页面加载时间过长,卡顿,用户体验极其不佳

so~出来一系列对图片处理的方案

  • 懒加载
  • 上传cdn
  • 图片压缩
  • 精灵图
  • icon
  • ...

主题介绍

你以为本篇文章是用来教你如何优化图片?

错!

这次,我们讲的不止是优化图片的方案,还包括性能检测-图片

简单介绍一下,检测网站性能,从请求数,dns耗时,tcp耗时,文件体积,图片体积过大,图片未使用懒加载,图片未使用cdn后缀...这些指标来评出一个分数。

内容较多,这次就先讲一下如何实现懒加载和检测图片是否使用懒加载

懒加载的优点与实现

什么是懒加载

懒加载其实就是延迟加载,是一种对网页性能优化的方式,比如当访问一个页面的时候,优先显示可视区域的图片而不一次性加载所有图片,当需要显示的时候再发送图片请求,避免打开网页时加载过多资源。

什么时候用懒加载

当页面中需要一次性载入很多图片的时候,往往都是需要用懒加载的。

懒加载原理

我们都知道HTML中的img标签是代表文档中的一个图像,img标签有一个属性是src,用来表示图像的URL,当这个属性的值不为空时,浏览器就会根据这个值发送请求。如果没有src属性,就不会发送请求。嗯?貌似这点可以利用一下?我先不设置src需要的时候再设置?nice,就是这样。我们先不给img设置src,把图片真正的URL放在另一个属性data-src中,在需要的时候也就是图片进入可视区域的之前,将URL取出放到src中。

如何设置

react: react-lazyload。

vue: vue-lazyload。

检测图片是否使用懒加载实现方案

原理我们搞清楚了,接下来就是如何实现

这里我们借助一个强大的工具:无头浏览器--puppeteer

puppeteer文档请戳www.npmjs.com/package/pup…

requestfinished事件中,可以获取到进入首屏的所有请求url,将图片的请求过滤出来

page.on('requestfinished', async request => {
    let requestedUrl = '';
    const resourceType = request.resourceType();
    if (
        resourceType === 'image' &&
        requestedUrl.indexOf(';base64') < 0
    ) {
        requestedUrl = request.url();
    }
}

page.evaluate事件里可以获取dom树,记住:console和debugger是进不去的,在该函数里将所有的img的url和在dom上所处位置记录下来

 page.evaluate(() => {
      const data = document.getElementsByTagName('img');
      const clientHeight = document.documentElement.clientHeight;
      const clientWidth = document.documentElement.clientWidth;
      const newData = [];
      for (const item of data) {
        const str = item.src.indexOf('http') !== -1 ? item.src : item.dataset.src;
        newData.push({ url: str, top: item.y, left: item.x, clientHeight, clientWidth });
      }
      return newData;
    });

将首屏请求的集合和img标签信息集合做一下过滤处理,将首屏之外请求加载的url暴露出来,暴露出来的url就是未使用懒加载的图片路径,这样就可以自己针对性的去网站上找了

requestUrls.map(r => {
    const imgElement = imgElements.find(img => img.url === r.url);
    return imgElement
      ? {
          ...r,
          ...imgElement,
        }
      : null;
  })
  .filter(r => r && (r.top > 800 || r.left > 1280))

流程图

好了,本期到现在就结束了,关注我们查看下期关于网站性能的文章