优化使用img标签加载svg大图导致的内存开销

问题背景

最近在排查系统内存泄漏问题时,发现某个页面的内存占用颇高(500M+),且访问过这个页面后,后续进入的页面的内存开销也会增加大约400M左右,怀疑存在内存泄漏问题

排查记录

未进入目标页面前的内存数据 进入目标页面后的内存数据 反复进入目标页面,发现内存数据始终稳定在 520M ~ 540M 左右,录制内存快照 发现占用最高的是 svg 相关节点,分析页面代码,发现业务上使用img标签加载了一张svg格式的图片,而这张图片高达 18M 浏览器使用img加载svg资源,是需要解析的,而18M左右的svg资源解析消耗的内存高达400M左右,而且这部分资源消耗不会随着img节点的销毁而释放。

结合业务场景,该页面的访问是一个相对低频的操作,用户一旦访问过该页面,内存可能在用户关闭页面前持续高位,导致页面卡顿、甚至浏览器崩溃(尤其是低配设备或移动端),因此需要手动干预这部分内存的回收

解决方案

可以手动在组件销毁阶段将img.src属性置为空,浏览器就会释放svg解析消耗的这部分资源

javascript 复制代码
<template>
   <img
    ref="imageRef"
    :src="imageUrl"
    :alt="altText"
    class="large-image__img"
    @load="handleImageLoad"
    @error="handleImageError"
    :style="{ maxWidth, maxHeight }"
  />
</template>
<scritp setup lang="ts">
import { onBeforeUnmount, useTemplateRef } from 'vue';

const imageRef = useTemplateRef<HTMLImageElement>('imageRef');

onBeforeUnmount(() => {
  if (imageRef.value) {
    imageRef.value.src = '';
  }
});

</script>

后续的思考

浏览器对svg解析资源的缓存可能是在某些场景下的一种优化手段,但如果加载的svg较大 且用户访问较低频 ,还是用完就销毁为好。

相关推荐
Mr_Mao20 分钟前
告别选型困难!集 VueUse、ahooks、Mantine 于一身:286 个 Hook 的 ReaUse 来了
前端·javascript·react.js
泡海椒1 小时前
趋势分析报表:jquick-pdf折线图PDF生成实战
java·大数据·运维·服务器·前端·pdf
默_笙1 小时前
🚙 一条腿走路会摔:ES 关键词检索、混合召回与 ReRank 裁判
前端·javascript
YIAN1 小时前
从跨域代理到 WebSocket:梳理前端实时通信的底层逻辑与完整实践
前端·websocket
一曲终散1 小时前
创建 SVG 图标预览页面:从零实现到解决 CORS 问题
前端
静默回滚2 小时前
iPhone照片电脑上打不开:HEIC解码从原理到WASM
前端
dsyyyyy11012 小时前
Vue 3 Watch 监视完全指南
前端·javascript·vue.js
航飞光电市场经理2 小时前
人员定位系统“全栈自研”技术解析:从射频前端到定位引擎的架构拆解
前端·架构
Apifox2 小时前
Apifox 9 月更新|CLI 能力升级、GitLab 私有化部署接入与产品体验优化
前端·后端·测试
deli0072 小时前
随机乱跳为什么能画出完美三角形:混沌游戏分形实验室
前端