最近被 Safari “玩”了一把,为了适配它,做了不少的工作。Safari 在Canvas 上确实留了一手,让我们不得不妨,不过正因为有了 Safari 的限制才能够让我的程序更优,占用更少的内存空间。

Safari 在实现 Canvas 时对内存进行了限制,在不同设备上允许使用的内存不同,具体根据你设备 RAM 的大小计算。当你使用 Canvas 时占用的内存超过限制时会提示:

一但超出限制,使用 getContext('2d') 将会返回 null。但我们不知道 Safari 是如何计算 Canvas 占用的内存空间的。

这就不得不够从源码中找答案,翻开 webkit 的源码(如果你不知道如何查看 webkit 的源码,可以看这篇文章,阅读量已有 8000+)

简看 Canvas 源码,突发奇想

按提示,直接在源码中搜索相关内容:

从源码中可以看到 Canvas 的内存占用空间为 4 * width * height,允许使用的最大内存空间由 maxActivePixelMemory 这个函数计算,这个函数计算规则如下:

可能你会好奇为啥计算画布的内存空间公式 4 * width * height有个 4,代表什么意思?

想一下画布的本质是什么?比如我在画布上写下 SY 时,它的 data 是什么样的?

我创建一块画布,然后写下 S、Y这两个字母,并打印 imageData

图中返回的数组长度为 4096 = 4 * 32 * 32

看下 data 中具体的值,因为 S、Y 两个字符绘制时发生了重叠,你看到的数值不是 RGB 对应的值。

字母在画布中的本质其实是色值,4 表示 RGBA 的具体内容,这就是 4 的来源。

问题来了,有时候不得不创建很多 Canvas,如何才能够避免内存限制,比如实现 2000页的这种文档,每页内容都由 Canvas 绘制:

难道要创建2000个Canvas?

当然不能这样,需要采用一定的优化策略,比如只绘制可视区域的内容,不可见的部分不进行绘制。当页面即将出现时再进行绘制。这就涉及到一个问题,已经渲染后的内容如何让其释放内存空间。

以前想过通过 clearRect 清除画布中的内容,这种想法可笑至极,即使清空了内容,只要画布还在,内存空间就不会被释放。

也可以把 Canvas 这个元素从 DOM 中删除,来释放内存空间。这样会频繁操作 DOM。

还有一种方法,可以设置 CanvasElement 的 width 和 height 为 0,设置这两个值后画布上内的内容会被清空,内存空间也会被释放。

到这里,只要能够监听每页出现即可,可以直接使用 IntersectionObserver 这个 API,它是异步的,不会卡主线程,相比以前监听滚动事件计算可视区域的元素,更优秀,但是不兼容 IE,好在官方提供了 polyfill 来解决这个问题。详细地址:

https://github.com/w3c/IntersectionObserver/blob/main/polyfill/intersection-observer.js

使用 IntersectionObserver 后我们即可在元素出现时设置 Canvas 的宽度,并进行绘制。

详细代码如下所示:

可能有人会担心每次页面出现时渲染会不会很卡,如果绘制的内容比较少,可以忽略不记。比如每页绘制 4000 个文字,感受不到卡顿,当然在绘制过程中可根据实际情况进行优化。

到此,即使存在2000页也不会消耗很大的内存,相比之前内存空间可节约 90%。

说到这里,不得不提 Safari 还有一个限制,就是它的画布大小有限制,不过其它浏览器也会有限制,所以在创建画布的时候,需要留意画布不要太大。从下面的源码中看到,在 iOS 设备上画布会更小。

前几天,我还踩过个坑:留意 drawImage 的坑,Canvas教程大升级

最后再说一件事,前段时间把 Canvas 的教程升级了,内容还在撰写中。效果如下:

大家加油!!!

demo地址:https://github.com/lefex/FE/tree/master/learn-canvas

长按关注

素燕《前端小课》

帮助 10W 人入门并进阶前端

官网:https://lefex.gitee.io/

Safari难道是下一个IE?兼容性这么“差”相关推荐

  1. ios html 表单,iOS Safari HTML表单下一个/上一个按钮 - 它们如何工作?

    免责声明:我正在使用JQuery Mobile. 我有一堆不同形式的页面,但是当按下下一个/上一个按钮时,其中一些页面似乎表现出不同的行为. 所有表单都使用制表符索引进行设置. Form 1完美运行, ...

  2. js 兼容性封装获取第一个子元素,最后一个子元素,下一个兄弟元素,上一个兄弟元素

    高级浏览器: chrome firefox ie9及以上符合web标准浏览器. 低版本浏览器: ie6,ie7,ie8. 节点和元素的适用范围:以firstChild和firstElementChil ...

  3. 下一个嵌入式大神,难道不是你吗?

    上次给大家送过30本5米长的linux地图册: 下一个嵌入式大神,就是你. .... 好多朋友表示没有拿到,和极客时间的小姐姐说了好久. 这不,我又争取了很多本,哈哈哈.数量嘛,我只能说,以百为单位~ ...

  4. 前方高能!AI 大牛 LeCun 设想下一个新前沿:摈弃深度学习的所有概率技巧,改而掌握不断转变的能量值...

    来源:云头条 据深度学习界的领军人物Yann LeCun声称,AI的下一个发展阶段可能是摈弃深度学习的所有概率技巧,改而掌握不断转变的能量值. 据说工程师(以及一些科学家,但以工程师为主)早在坐到板凳 ...

  5. 通过修改程序解决Vista/Win7/Win8下应用程序兼容性问题

    在Vista/Win7/Win8下,有一个系统兼容性助手功能,使得程序在安装完成后或运行时,总是弹出应用程序兼容性助手相关的提示,很是烦人,事实上我们的程序兼容性是没有问题的,只不过是在程序中没有指定 ...

  6. 互联网周刊:谁是下一个IE?

    谁是下一个IE?最多三年后,这个问题或将成为一个伪命题.显然,IE优势开始动摇,昔日风光不再.至少,随着欧洲浏览器捆绑诉讼尘埃落定,浏览器在把选择权交给用户的基调下,恐难形成洗牌后一家独霸的局面. 上 ...

  7. C++20 - 下一个大版本功能确定

    C++20的功能特性已经于3月份冻结,显然这次终于来了一波大的改进,而不再是像之前C++14/C++17那般小打小闹的做小步快跑,尤其是三个讨论很久的大feature终于被合入主干:并且这些featu ...

  8. 凯文·凯利:下一个5000天的12个必然趋势!

    我想讲一些长期的趋势,这种必然的趋势都是交织在一起的.互相依赖的,但最后朝同一个方向前进. --凯文·凯利 你能想象,智能手机问世只有不到5000天吗?与人类历史相比,5000天实在太过于短暂.然而就 ...

  9. 超云将成为数据中心演化的下一个阶段

    如今,各行业组织的数字化转型基本上都是由创新.自动化和差异化的需求驱动的.云计算和存储已经在基础设施现代化中发挥了核心作用,但引入和支持新兴应用和服务的市场竞争并没有放缓的迹象. 人工智能.机器学习. ...

最新文章

  1. nginx重点优化合集一
  2. Java运行时动态加载类之ClassLoader加载class及其依赖jar包
  3. vista下文件夹拒绝访问的解决办法
  4. C#LeetCode刷题之#697-数组的度( Degree of an Array)
  5. 开发不能上外网怎么查资料_中考生不能复读,近一半上不了高中,怎么办?
  6. 使用ISynchronizeInvoke无痛地创建线程安全用户界面
  7. python中的字典和类的区别_Python:我应该使用类还是字典?
  8. 360深度实践:Flink 与 Storm 协议级对比
  9. matlab学习技巧
  10. 通过代码下载全国范围详细区县行政区Shp数据
  11. 深圳大数据学习:怎样进行大数据的入门级学习?
  12. 【工具分享】一个阿里出品的免费在线图表制作工具(ChartCube 图表魔方)
  13. AI语音技术的应用与发展前景
  14. QT应用编程: Visual Studio里编写activex控件在网页中运行(dll插件形式)
  15. 再生龙linux多挂载点备份,利用Clonezilla(再生龙)对Linux系统备份与恢复
  16. 使用串口发送实现ACX720开发板时钟显示
  17. 总有一条适合你|程序猿的女朋友
  18. 戴维·考克斯爵士去世
  19. 在Mac中使用OpenNI
  20. Unity Tutorial - Adventure Game

热门文章

  1. RecyclerView的notifyDateSetChanged()等不起作用,必须点击屏幕列表才会刷新的解决方法
  2. 华为机试——简单题整合(二)(C++)
  3. 大数据Hadoop,spark学习
  4. 华为java模拟器下载手机版,华为ism模拟器|华为存储ISM模拟器下载 V100R005
  5. 安装oracle出现oraclenet,安装ORACLE服务出现Oracle Net Configuration Assistant 失败问题【我】...
  6. vim配置文件.vimrc
  7. 电子合同第三方服务平台是干嘛的
  8. 扫地机器人发火_盘点扫地机器人那些让人吐血三升的事,你有遇到过吗?
  9. 服务器三种虚拟化技术
  10. Docker Swarm使用NFS作为共享存储