无需Javascript将外部SVG雪碧图加载注入DOM的实现方案咨询
方案1:服务端直接内嵌SVG雪碧图(最优性能)
这是完全匹配需求的最高效方案,无需发起任何额外独立请求,SVG内容随主HTML文档一同加载,完全处于关键渲染路径内。
操作方法:服务端渲染页面时,直接读取sprites.svg的文件内容,插入到<body>标签最开头,外层套一个隐藏容器即可:
<body> <div style="display:none"> <!-- 直接插入sprites.svg的全部内容 --> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <symbol viewBox="0 0 60 60" id="icon1">...</symbol> <symbol viewBox="0 0 60 60" id="icon2">...</symbol> <symbol viewBox="0 0 60 60" id="icon3">...</symbol> </svg> </div> <!-- 其他页面内容 --> </body>
你原本使用的<use xlink:href="#icon1"></use>语法完全不需要修改,兼容性也最好。
方案2:直接跨文档引用外部SVG雪碧图
如果无法修改服务端渲染逻辑,可以直接修改use标签的引用路径,不需要把SVG注入到当前DOM,也无需额外发起Ajax请求:
<svg> <use xlink:href="/images/sprites.svg#icon1"></use> </svg>
同域下所有现代浏览器都支持该用法,浏览器会自动请求sprites.svg文件,加载完成后自动渲染所有引用了该文件的图标。
如果要进一步优化加载速度,可以在<head>中添加预加载声明,让浏览器提前开始加载雪碧图资源:
<link rel="preload" href="/images/sprites.svg" as="image" type="image/svg+xml">
方案3:预加载+提前注入DOM(兼容原有用法)
如果你不想修改现有图标引用代码,可以把原本的Ajax加载逻辑提前到DOM解析初期执行,配合预加载使用,速度也会远高于原有方案:
- 在
<head>中添加和方案2一致的预加载声明 - 把原本的注入代码放到
<head>中,监听DOMContentLoaded事件立即执行,不需要等待其他非关键资源加载完成
补充说明之前<object>、<embed>方案无效的原因:这两个标签加载的SVG资源处于独立的文档上下文,和当前主文档DOM完全隔离,主文档内的use标签无法访问到另一个上下文内的symbol ID,因此无法正常渲染图标。
内容的提问来源于stack exchange,提问作者Pingolin
相关产品推荐
相关产品推荐

