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 所以我们不需要担心它们的通信效率)自此这个流程就算完成了
这段代码是对普通图片进行缓存操作
//此段以及下一段代码中都使用了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实现无感大量图片缓存的更多相关文章
- Modelarts与无感识别技术生态总结(浅出版)
[摘要] Modelarts技术及相关产业已成为未来AI与大数据重点发展行业模式之一,为了促进人工智能领域科学技术快速发展,modelarts现状及生态前景成为研究热点.笔者首先总结modelarts ...
- Spring Cloud实战 | 最八篇:Spring Cloud +Spring Security OAuth2+ Axios前后端分离模式下无感刷新实现JWT续期
一. 前言 记得上一篇Spring Cloud的文章关于如何使JWT失效进行了理论结合代码实践的说明,想当然的以为那篇会是基于Spring Cloud统一认证架构系列的最终篇.但关于JWT另外还有一个 ...
- 无感刷新 Token
什么是JWT JWT是全称是JSON WEB TOKEN,是一个开放标准,用于将各方数据信息作为JSON格式进行对象传递,可以对数据进行可选的数字加密,可使用RSA或ECDSA进行公钥/私钥签名. 使 ...
- kaggle 欺诈信用卡预测——不平衡训练样本的处理方法 综合结论就是:随机森林+过采样(直接复制或者smote后,黑白比例1:3 or 1:1)效果比较好!记得在smote前一定要先做标准化!!!其实随机森林对特征是否标准化无感,但是svm和LR就非常非常关键了
先看数据: 特征如下: Time Number of seconds elapsed between each transaction (over two days) numeric V1 No de ...
- axios实现无感刷新
前言 最近在做需求的时候,涉及到登录token,产品提出一个问题:能不能让token过期时间长一点,我频繁的要去登录. 前端:后端,你能不能把token 过期时间设置的长一点. 后端:可以,但是那样做 ...
- 使用Retrofit和Okhttp实现网络缓存。无网读缓存,有网根据过期时间重新请求 (转)
使用Retrofit和Okhttp实现网络缓存,更新于2016.02.02原文链接:http://www.jianshu.com/p/9c3b4ea108a7 本文使用 Retrofit2.0.0-b ...
- php处理的图片无法进CDN缓存
今天发现线上有个问题,线上一个图片域名,在前端已经加了CDN缓存,不落缓存,则用PHP动态实现图片缩放,但经PHP处理过的图片输出后,每次都要从后端读取,后端服务器压力瞬间增加,经分析,PHP中没有作 ...
- spring boot logback无感配置
spring boot1.5.x版本的日志配置一直有一个问题,就是不能直接通过yml配置文件进行日志文件大小进行动态和方便的配置. 怎么解决?直接在springboot项目的maven工程中的src/ ...
- druid与知乎平台
背景 知乎作为知名中文知识内容平台,业务增长和产品迭代速度很快,如何满足业务快速扩张中的灵活分析需求,是知乎数据平台组要面临的一大挑战. 知乎数据平台团队基于开源的 Druid 打造的业务自助式的数据 ...
- 使用IndexedDB缓存给WebGL三维程序加速
前言 使用webgl开发三维应用的时候,经常会发现三维场景加载比较慢,往往需要等待挺长时间,这样用户的体验就很不友好. 造成加载慢的原因,主要是三维应用涉及到的资源文件会特别多,这些资源文件主要是模型 ...
随机推荐
- 2021-7-30 MySql函数的使用归类整理
Mysql字符的使用 SELECT ASCII(user_password) as 阿斯克码 FROM users;#返回首字符的ascii码 SELECT CHAR_LENGTH(user_pass ...
- 整理不错的opencv博客
https://me.csdn.net/column/u013095718 更全的博客: https://blog.csdn.net/zhmxy555/column/info/opencv-tutor ...
- 【高并发】SimpleDateFormat类到底为啥不是线程安全的?(附六种解决方案,建议收藏)
大家好,我是冰河~~ 首先问下大家:你使用的SimpleDateFormat类还安全吗?为什么说SimpleDateFormat类不是线程安全的?带着问题从本文中寻求答案. 提起SimpleDateF ...
- Java 生态需要新鲜的血液、需要狂飙的刺激。Solon v2.4.1 发布
Solon 是什么开源项目? 一个,Java 新的生态型应用开发框架.它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态规模).与其他框架相比,它解决了两个重要的痛点:启动慢 ...
- Blazor前后端框架Known-V1.2.11
V1.2.11 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行. Gitee: https://gitee.com/known/Known Git ...
- vivo 场景下的 H5无障碍适配实践
作者:vivo 互联网前端团队- Zhang Li.Dai Wenkuan 随着信息无障碍的建设越来越受重视,开发人员在无障碍适配中也遇到了越来越多的挑战.本文是笔者在vivo开发H5项目做无障碍适配 ...
- 11、Mybatis之逆向工程
11.1.正向与逆向工程概述 正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表:例如Hibernate是支持正向工程的. 逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成Ja ...
- Windows 虚拟地址 到底是如何映射到 物理地址 的?
一:背景 1. 讲故事 我发现有很多的 .NET程序员 写了很多年的代码都没弄清楚什么是 虚拟地址,更不用谈什么是 物理地址 以及Windows是如何实现地址映射的了?这一篇我们就来聊一聊这两者之间的 ...
- 分享一个 SpringBoot + Redis 实现「查找附近的人」的小技巧
前言 SpringDataRedis提供了十分简单的地理位置定位的功能,今天我就用一小段代码告诉大家如何实现. 正文 1.引入依赖 <dependency> <groupId> ...
- 试试用Markdown来设计表单
相信很多后端开发.对于前端知识是比较零碎的,所以很多时候写表单这样的工作,一般就是复制黏贴,然后改改字段.对于HTML格式,一直觉得比较杂乱,不够简洁. 最近TJ发现了一个有趣的小工具:Create ...