我正在使用最新的
create-react-app
配置,并在不同路线之间切换时遇到问题。
我所有的
SVG
都包含在精灵文件中。从逻辑上讲,sprite.svg文件应该在首页加载时缓存。
但是,每次更改路线(使用
react-router
4)都会加载此文件,从而导致闪烁。内容会立即更改,但图像加载会出现 1 秒的延迟。
与通过 png
中的 import
包含的 jsx
相同。
从控制台中看不到,相同的文件会一遍又一遍地下载。
现场演示位于 http://cabin.surge.sh/(即尝试在标题部分的定价/关于页面之间进行更改)
更新:
我包含 SVG 图像的方式 - 是愚蠢的组件
<SvgIcon name="checkmark" />
import React, { Component } from 'react';
import sprite from '../images/sprite.svg';
export default class SvgIcon extends Component {
render(){
const { name } = this.props;
return(
<svg className={"ico ico-" + name}>
<use xlinkHref={sprite + "#ico-" + name}></use>
</svg>
)
}
}
PNG 图像
<img src={require(`../images/${authorImage}.png`)} srcSet={require(`../images/${authorImage}@2x.png`) + ' 2x'} alt=""/>
如果问题是图像没有提前获取并导致页面更改时闪烁,请尝试使用
componentDidMount() {
const sprite = "../images/sprite.svg";
const prefetchLink = document.createElement("link");
prefetchLink.href = sprite;
prefetchLink.rel = "prefetch";
prefetchLink.as = "image";
document.body.appendChild(prefetchLink);
}
这将提示浏览器在后台(空闲时间)获取稍后可能需要的资源,并将它们存储在浏览器的缓存中。页面加载完成后,它会开始下载其他资源,如果用户单击预取的链接,它将立即加载内容。
对于功能版本:
//custom hook to preload image
const usePreload = (url) => {
const [loaded, setLoaded] = React.useState(false);
const onLoad = React.useCallback(() => {
setLoaded(true);
}, []);
React.useEffect(() => {
const prefetchLink = document.createElement('link');
prefetchLink.href = url;
prefetchLink.rel = 'prefetch';
prefetchLink.as = 'image';
prefetchLink.addEventListener('load', onLoad);
document.body.appendChild(prefetchLink);
//clean up
return () => document.body.removeChild(prefetchLink);
}, [onLoad, url]);
return loaded;
};
export default function SvgIcon({ name }) {
const url = sprite + '#ico-' + name;
const loaded = usePreload(url);
return (
loaded && ( //only render if image is loaded
<svg className={'ico ico-' + name}>
<use xlinkHref={url}></use>
</svg>
)
);
}
请注意,如果您进行服务器端渲染,您不希望此代码在服务器上执行,因为服务器上没有
document
。