优化v-viewer加载性能

发布时间:2023年12月29日

v-viewer简介

v-viewer 是一个 Vue 组件,用于显示图片和其他媒体内容的全屏查看器。它基于 Viewer.js,一个强大的图片查看库。

以下是一个基本的使用示例:

<template>
  <div v-viewer>
    <img src="image1.jpg" />
    <img src="image2.jpg" />
    <img src="image3.jpg" />
  </div>
</template>

<script>
import Viewer from 'v-viewer'
import 'viewerjs/dist/viewer.css'

export default {
  name: 'MyComponent',
  directives: {
    viewer: Viewer
  },
  data() {
    return {
      viewerOptions: {
        inline: false,
        button: true,
        navbar: true,
        title: true,
        toolbar: true,
        tooltip: true,
        movable: true,
        zoomable: true,
        rotatable: true,
        scalable: true,
        transition: true,
        fullscreen: true,
        keyboard: true,
        url: 'data-source'
      }
    }
  }
}
</script>

在这个示例中,我们导入了 v-viewer 和相关的 CSS,然后在模板中使用 v-viewer 指令。每个 img 元素都会自动成为查看器的目标。

v-viewer 提供了许多选项,如 inline、button、navbar、title、toolbar 等,用于自定义查看器的行为和外观。你可以在 viewerOptions 对象中设置这些选项。

更多详细的信息,你可以查看 v-viewer 的 GitHub 页面。

问题及解决方案

改插件能够很方方便的用来进行图片的预览,放大缩小等各种操作。然而,在实际使用中,有用户反馈图片加载很慢的问题,希望能对此进行优化。

图片尺寸大

针对此种情况,我们首先针对用户反应的情况进行了排查,发现用户上传的图片很大,一般在5-7M左右。这种情况通常发生在用户手机端上传,由于现代手机都具有较高的拍照像素,所以通常而言图片会很大。
于是,首先我们对图片进行了压缩上传,尽可能降低图片的大小,用以提升用户预览体验。

多次重复加载

在上面进行了压缩上传以后,一段时间后,用户还是反馈图片预览慢。此时我们就排查了下预览时,前端的网络请求耗时等,发现v-viewer在对同一张图片预览时,加载了3次,直到3次下载完成后,图片预览才算完成。这就相当于用时是正常预期的3倍。
在这里插入图片描述
这里就需要查看dom,看看为什么加载了3次。dom结构如下
在这里插入图片描述
这3处dom都包含了同一图片,分别为渲染前的原始dom节点,v-viewer渲染的大图预览,以及隐藏的小图navbar。由此可以看到,即便我们没有启用小图索引,dom结构中依然有,只是隐藏了而已。这就导致造成额外的网络请求及加载延时问题。
项目中使用v-viewer的代码如下:

<template>
  <div v-loading="imgLoading" v-viewer.rebuild="{ ...imgViewerConfig }" class="image-preview">
    <img @load="imgLoading = false" :src="fileUrl" style="visibility: hidden" />
  </div>
</template>

v-viewer对应的config配置

imgViewerConfig = {
    inline: true,
    button: false,
    navbar: false,
    title: false,
    fullscreen: true,
    toolbar: {
      prev: 0,
      next: 0,
      zoomIn: 1,
      zoomOut: 1,
      oneToOne: 1,
      reset: 1,
      play: 0,
      rotateLeft: 1,
      rotateRight: 1,
      flipHorizontal: 1,
      flipVertical: 1
    }
  }

优化的思路就是尽可能只加载一次图片。如何在不改组件的情况下,实现该目标呢?
解决方案:如果我们先通过异步请求主动加载一次图片,将图片保存在内存中,后续v-viewer组件加载内存中的图片,就可以极大地提升图片预览的速度。避免不必要的网络请求。

async function loadFileBlobLink(url: string) {
  const response = await fetch<BlobPart>('GET', url, {}, true)
  const blob = new Blob([response.data])
  const link = window.URL.createObjectURL(blob)
  return link
}

我们通过createObjectURL创建一个URL,用于访问异步接口请求到的文件流数据。URL.createObjectURL() 是一个静态方法,用于创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期与创建它的窗口中的 document 绑定。新的对象 URL 表示指定的 File 对象或 Blob 对象。
可以通过在chrome地址栏中访问chrome://blob-internals/,查看chrome中blob的存储占用
在这里插入图片描述
请注意,由 URL.createObjectURL() 创建的 URL 应当在不再需要时释放,以便浏览器可以回收任何消耗的资源。这可以通过调用 URL.revokeObjectURL() 来完成:

URL.revokeObjectURL(url);

总结

通过转换图片的加载方式,异步下载图片文件流,并通过createObjectURL创建url引用,可以有效提升v-viewer预览图片的加载速度。在已经尝试过其他优化方案(图片压缩,提升网络带宽等)后,该方案也是进一步提升性能的可行方案。

文章来源:https://blog.csdn.net/Bekind2010/article/details/135290625
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。