图片

web 优化专家一定是图片优化专家

显示优化

  • 缩略图到原图过渡

web 前端图片加载优化,从图片模糊到清晰的实现过程open in new window

图片格式

不同格式适用场景

无损,压缩级别只是编码不同?

格式使用场景劣势
JPG/JPEG1. 大的背景图; 2. 轮播图; 3. Banner 图 4. 照片
PNG1. 小 Logo; 2. 透明背景
GIF动态图片
SVG能适应不同设备且画质不能损坏的图片
Base64大小不超过 2KB,且更新率低的图片无法缓存,不适合大图片
WebP现代浏览器

PNG - 维基百科,自由的百科全书open in new window

响应式展示

srcset/sizes

Use Imagemin to compress images  |  web.devopen in new window

占位图工具

iphopen in new window

h2 lazy

问题:一般期望首屏图片尽快下载完,但使用了 H2,优先级低的图片可能拖慢优先级高的图片下载,

  • h2 并行,对下行带宽来说,相当于在请求一个合并文件
  • 开发工具,切换到 image 标签,可以看当图片请求数,总请求大小
  • 图片总体积 9Mb,网速 500KB/s,那 9 * 1000 / 500 = 18,理论要 18s 全部下载完
  • 并行请求,充分利用带宽,但导致单个资源可用带宽爱限
  • 假定 50 张图片,每张图片分配的下行 500 / 50 = 10 kb/s,实际考虑有的图片较小,下载完会释放
  • 带来的问题,优先级高的图片下载也慢了
  • 用户带宽限制,服务器带宽一般远大于用户带宽

第 2、3 张走了不同的域名,所以快。第一张因为首页 h2 并发下载图片太多了(56 个请求,9Mb 大),4Mb 带宽下 较大图片并行请求 20 张每张分 配大概是 50kb/s,一张 200kb 的图至少需要 4s (实测,swiper 第一张 5s 多)

结论:

  • 所以用 h2,如果图片比较多的话,需要给图片排优先级(优先级低的使用懒加载),优先保障当前视口内图片加载,限制一定时间内请求数据量
  • 图片上单独 cdn

lazy load

chrome 原生已支持

默认已经按优先级加载。使用 lazy 可以节省资源

传统方法 scroll 性能不好

IntersectionObserver 交叉观察者接口,异步,空闲时执行

Chrome 51+,不支持 IE,兼容性很好

触发加载规则:图片元素出现在视口内,即检查元素与父元素或视口(root)是否交叉,交叉比例 threshold

应用场景:lazy load,无限滚动 IntersectionObserver - Web APIs | MDNopen in new window

缺点:依赖 JS 才能正确设置 src,Chrome 原生的好处

Tips for rolling your own lazy loading | CSS-Tricksopen in new window

示例 Interaction observer exampleopen in new window

webp

  • 支持检测原理,src base64 onload
  • polyfill 支持原理,打包了libwebp解码库,webp -> image data -> canvas -> done
  • 兼容性:IE11/Safari
  • 文件 Giziped 95KB

chase-moskal/webp-hero: browser polyfill for the webp image formatopen in new windowEssential Image Optimizationopen in new window

高清图

Sketch用一倍图做设计稿还是二倍图?|UI|教程|Olaf_Chou - 原创文章 - 站酷 (ZCOOL)open in new window

二倍图设计默认导出的图片是 2x 高清的,可直接使用。 二倍图导出时省去了点击+号 再选 2x ,操作方便。

图片压缩

表单图片压缩

  • 图片 → canvas 压缩 → 图片
  • canvas 设置宽度
  • toBlob(),转换成二进制,后端友好

imageConversion 大文件 png 测试open in new window

图片预览,可以用 URL.creatObjectUrl(blob) 或 FileReader.readAsDataURL(blob)

在线压缩

Squooshopen in new window

本地手动压缩

imageoptim-cli 不支持 svg,因为已经有 svgo

注意参数需要有引号

imageoptim './*'

gui 更全面,且支持异步同步调用

自动优化图像  |  Web Fundamentals  |  Google Developersopen in new window

工具压缩 gulp

  • 首先原图往往尺寸很大,先缩小
  • 把大文件挑出来,用智图的在线服务,压缩效果好,它的 gulp 工具依赖在线 api,不支持多层目录,有待观察
  • gulp-imagemin 支持多层目录
gulp.task('imagemin', function() {
  gulp
    .src('./h5/group4/M00/**/**/*.{png,jpg,gif,ico}')
    .pipe(imagemin())
    .pipe(gulp.dest('./h5/group4/M00-dist/'))
})

图片预览

  • filereader onload

处理上传

  • blob 必须设置 name
  blobToFile (theBlob, fileName) {
      theBlob.lastModifiedDate = new Date()
      theBlob.name = fileName
      return theBlob
  },

  const newFile = this.blobToFile(blob, 'upload.png')
  const formData = new FormData()
  formData.append('file', newFile, newFile.name)

原理:Vue 实现图片预览、裁剪并获取被裁剪区域的 base64(无组件) - hhzzcc_的博客 - CSDN 博客open in new window

Vue+element-ui 图片上传剪裁组件 - 掘金open in new window

  • element-ui
  el-upload.avatar-uploader(action='https://jsonplaceholder.typicode.com/posts/', :show-file-list='false', :on-success='handleAvatarSuccess', :before-upload='beforeAvatarUpload')
      el-button(type='primary') 上传

AVIF

AV1 video keyframe

All we need to do is repack AVIF as a single-frame AV1 video and decode it using native decoder. polyfill 原理:将图片重打包成 AV! 视频,再复用浏览器原生支持能力解码 AVIF -> MP4 -> <video> -> canvas -> output.bmp喂给浏览器,不必再压缩 SW 不能创建<video>,需要主线程配合

保持比例

object-fit: contain;

background-size: contain;

图片压缩原理

TODO

优化思路

  1. 选择合适格式 png jpg webp avif
  2. 减少请求 base64 http 1.1 雪碧图
Last Updated:
Contributors: cyio