Vue自定義指令結合阿里雲OSS優化圖片

圖片每每在加載前端項目中佔大頭,如何既不損失圖片質量,又提高加載速度呢?前端

  1. 根據顯示設備pixelRatio和元素寬高來顯示合適圖片
  2. 略微壓縮圖片質量
  3. 使用webp

註冊全局自定義指令

Vue.directive('img-condense', {
  bind: (el, binding, vnode) => {
    let src = el.getAttribute('src')
    let newSrc = compressImg(src, el)
    el.setAttribute('src', newSrc)
  }
})
複製代碼

獲取元素寬高和顯示設備pixelRatio

let compressImg = (imgUrl, el) => {
  // 獲取顯示設備 pixelRatio
  let pixelRatio = window.devicePixelRatio
  let elWidth = elStyle.width * pixelRatio
  let elHeight = elStyle.height * pixelRatio
  let resize = '/resize'
  if (elWidth) {
    resize += `,w_${elWidth}`
  }
  if (elHeight) {
    resize += `,h_${elHeight}`
  }
})
複製代碼

判斷webp

let canUseWebp = document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0
let webp = ''
if (canUseWebp) {
  webp = '/format,webp'
}
複製代碼

質量下降至80%

let ossParam?x-oss-process=image${resize}/auto-orient,1/quality,Q_80/bright,-1${webp}
複製代碼

完整版

<img v-img-condense alt="Vue logo" src="../assets/logo.png">
Vue.directive('img-condense', {
  bind: (el, binding, vnode) => {
    let src = el.getAttribute('src')
    let newSrc = compressImg(src, el)
    el.setAttribute('src', newSrc)
  }
})
let compressImg = (imgUrl, el) => {
  // 若是不是oss 或者已經壓縮過的圖片直接返回
  if (imgUrl.includes('aliyuncs.com') || imgUrl.indexOf('blob') === 0 || imgUrl.includes('x-oss-process=')){
    return imgUrl  
  }
  // 獲取顯示設備 pixelRatio
  let pixelRatio = window.devicePixelRatio
  let elWidth = el.width * pixelRatio
  let elHeight = el.height * pixelRatio
  let resize = '/resize'
  if (elWidth) {
    resize += `,w_${elWidth}`
  }
  if (elHeight) {
    resize += `,h_${elHeight}`
  }
  if (!elWidth && !elHeight) {
    resize = ''
  }
  // 判斷webp
  let canUseWebp = document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0
  let webp = ''
  if (canUseWebp) {
    webp = '/format,webp'
  }
  return `${imgUrl}?x-oss-process=image${resize}/auto-orient,1/quality,Q_80/bright,-1${webp}`
}
複製代碼
相關文章
相關標籤/搜索