offscreenCanvas+worker+IndexedDB实现无感大量图片缓存

这篇具有很好参考价值的文章主要介绍了offscreenCanvas+worker+IndexedDB实现无感大量图片缓存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一个有必要实现的需求

因为项目中需要使用canvasTexture(一个threejs3d引擎中的材质类型),绘制大量的图片,每次使用都会请求大量的oss图片资源,虽然重复请求会有磁盘缓存但毕竟这个磁盘缓存时效过短,

这里需要了解一下知识才能正常阅读。

Transferable objects https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects

Web Worker https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API

OffScreenCanvas https://developer.mozilla.org/zh-CN/docs/Web/API/OffscreenCanvas

需要注意项目所处浏览器环境是否支持其中的某些Api



  • 因为有了将有了将图片缓存到本地的需求,那么大量的资源缓存必然是使用indexedDB了

  • 其次为了方便存储和使用就需要将图片专为Blob对象。我们如果在程序中批量的将 canvasTexture 输出为图片并专为Blob对象并存到本地的话,会因为大量长时间的占用主线程造成页面渲染帧时隔过长,造成卡顿影响用户体验,

  • 那么我们就需要将canvasTexture输出图片和转为Blob对象这个耗时的过程放到worker中进行

  • 而如果要在worker中进行操作我们需要用到OffScreenCanvas来进行图片的绘制输出和转为Blob对象

  • 虽然worker可以传递OffScreenCanvas对象但是无法传递它的渲染空间Context所以我们只能在主线程中把canvasTexture中的画面输出为ArrayBuffer然后传递给worker中新创建的OffScreenCanvas然后通过OffScreenCanvas重新绘制并输出为Blob对象返回给主线程进行存储(ArrayBuffer,和 Blob都是可转移对象Transferable object 所以我们不需要担心它们的通信效率)自此这个流程就算完成了

    文章来源地址https://www.toymoban.com/news/detail-746312.html

这段代码是对普通图片进行缓存操作

    //此段以及下一段代码中都使用了localforage(一个封装了web端多个本地存储策略的npm包)这个Api作为存储策略
    setImageLocalCache(image, key) {
        const cacheKey = key
        const ofsCanvas = new OffscreenCanvas(image.width, image.height);
        let context = ofsCanvas.getContext('2d')
        context.drawImage(image, 0, 0, image.width, image.height)
        const imageData = context.getImageData(0, 0, ofsCanvas.width, ofsCanvas.height);
        const dataArray = imageData.data; //Unit8ClampedArray 
        const arrayBuffer = dataArray.buffer; // ArrayBuffer
        const worker = new Worker('worker/makeBlobCache.js')

        worker.postMessage({
            arrayBuffer,
            width: image.width,
            height: image.height
        }, [arrayBuffer])

        context.clearRect(0, 0, ofsCanvas.width, ofsCanvas.height)
        context = null

        worker.onmessage = (e) => {
            localforage.setItem(cacheKey, e.data).then(() => {
                URL.revokeObjectURL(URL.createObjectURL(e.data)) // 存储结束后释放Blob对象
            })
            worker.terminate(); //释放worker线程
        }
    }

这段代码是使用缓存的资源操作

    let blob = localforage.getItem(cacheKey)
    if(blob) {
      const image = new Image()
      image.src = URL.createObjectURL(blob)
      blob = null
      image.onerror = (e) => {
        console.log(e)
      }
      image.onload = () => {
        console.log('执行到这里图片就加载完成了')
        URL.revokeObjectURL(url)
      }
    }

这段代码是上述两段代码中的worker文件代码

self.onmessage = (e) => {
    const arrayBuffer = e.data.arrayBuffer;
    const width = e.data.width;
    const height = e.data.height;
    const uint8View = new Uint8ClampedArray(arrayBuffer);

    const imageData = new ImageData(uint8View, width, height); 
    const offscreen = new OffscreenCanvas(width, height)
    let ctx = offscreen.getContext('2d')

    ctx.putImageData(imageData, 0, 0)
    offscreen.convertToBlob({
        type: 'image/png',
        quality: 1
    }).then(blob => {
        ctx.clearRect(0, 0, offscreen.width, offscreen.height);
        ctx = null;
        self.postMessage(blob)
    })

};

到了这里,关于offscreenCanvas+worker+IndexedDB实现无感大量图片缓存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一个页面需要加载大量的图片,如何提升用户体验?

    当网站页面需要加载大量图片时,优化用户体验非常关键,以下是一些方法来提升用户体验: 图片懒加载(Lazy Loading) :只加载用户可以看到的图片,当用户向下滚动页面时,再加载其他图片。这减少了页面初始加载时间。 图片压缩 :使用工具压缩图片文件大小,而不显著

    2024年02月19日
    浏览(46)
  • Unity队列加载图片,解决大量同时加载资源卡顿问题与思路

    1、思路:加载图片的请求都加到队列中,然后一个加载完一个再去加载下一个,直到加载完。 2、问题:         问题是相对也存在的。当加载的数据还在队列中,但是已经跳转到其它的场景,则会出现报错的问题。         每次跳转场景的时候,需要把队列中的数据情况

    2024年02月16日
    浏览(39)
  • 前端实现token的无感刷新--VUE

    token刷新的方案    方案一:后端返回过期时间,前端判断token过期时间,去调用刷新token的接口    缺点:需要后端提供一个token过期时间的字段;使用本地时间判断,若本地时间被修改,本地时间比服务器时间慢,拦截会失败。    方案二:写个定时器,定时刷新token接口

    2024年02月19日
    浏览(30)
  • VUE前端实现token的无感刷新

    说实话,这个其实没啥好讲的,要说有复杂度的话,也主要是在后端。 实现token无感刷新对于前端来说是一项十分常用的技术,其本质都是为了优化用户体验,当token过期时不需要用户调回登录页重新登录,而是当token失效时,进行拦截,发送刷新token的请求,获取最新的tok

    2024年02月05日
    浏览(38)
  • VScode新增设备实现无感接入(不需要输入密码)

    VScode远程开发接入设备,默认是需要输入密码的,但是日常开发中刷新就需要重新输入密码,很烦人。配置ssh的RSA密钥后会,就可以直接系统级别验证接入,对开发人员来说验证步骤就透明了,实现无感接入,爽歪歪。 前提是设备上已安装配置好ssh环境,开发机上已生成ss

    2024年01月24日
    浏览(32)
  • 无感刷新:Vue前端实现Token的无缝刷新机制

    在现代Web应用程序中,用户身份验证和授权通常使用令牌(Token)机制来实现。然而,由于Token的过期时间限制,用户在长时间使用应用程序时可能需要重新登录。为了提供更好的用户体验,我们可以通过实现Token的无感刷新机制来避免用户在使用过程中的中断。本文将探讨如

    2024年02月10日
    浏览(30)
  • 为什么使用双token实现无感刷新用户认证?

    认证机制 :对与单token的认证机制在我们项目中仅使用一个Access Token的访问令牌进行用户身份认证和授权的方案处理。 不足之处: 安全性较低(因为只有一个token在客户端和服务器端之间进行传递,一目Acess Token被截获或者被泄露,攻击者就会在有效时间内完成模拟用户行为,

    2024年01月18日
    浏览(39)
  • 记录-使用双token实现无感刷新,前后端详细代码

    近期写的一个项目使用双token实现无感刷新。最后做了一些总结,本文详细介绍了实现流程,前后端详细代码。前端使用了Vue3+Vite,主要是axios封装,服务端使用了koa2做了一个简单的服务器模拟。 jwt:JSON Web Token。是一种认证协议,一般用来校验请求的身份信息和身份权限。

    2023年04月24日
    浏览(30)
  • el-upload实现可替换、删除、预览的图片上传。js 往返缓存(可判断当前页面是不是返回的页面)

    组件使用: UploadImage.vue 组件: BFCache是一种浏览器优化,可实现即时前进和后退载入页面。它改善了用户的浏览体验,尤其是那些网络或设备速度较慢的用户。 *我们可以通过这个方法判断当前页面是不是返回的页面* 在APP站内嵌套h5页面,判断进入拨号页返回情况: 我们需要通

    2024年01月25日
    浏览(36)
  • axios封装终极版实现token无感刷新及全局loading

    前言 关于axios全局loading的封装博主已经发过一次了,这次是在其基础上增加了token的无感刷新。 token无感刷新流程 首次登录的时候会获取到两个token(AccessToken,RefreshToken) 持久化保存起来(localStorage方案) 正常请求业务接口的时候携带AccessToken 当接口口返回401权限错误时,

    2024年02月21日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包