Tim*_*rts 5 javascript dom caching reactjs
假设我有一个url列表,如下所示:
[ '/images/1', '/images/2', ... ]
我想预取n那些,以便在图像之间转换更快.我现在正在做的componentWillMount是以下内容:
componentWillMount() {
const { props } = this;
const { prefetchLimit = 1, document = dummyDocument, imgNodes } = props;
const { images } = document;
const toPrefecth = take(prefetchLimit, images);
const merged = zip(toPrefecth, imgNodes);
merged.forEach(([url, node]) => {
node.src = url;
});
}
Run Code Online (Sandbox Code Playgroud)
用imgNodes像这样被定义:
imgNodes: times(_ => new window.Image(), props.prefetchLimit),
并且times,zip和take来自何处ramda.
现在当我使用那些内部的url反应时:
<img src={url} />
无论网址在何处使用,它都会根据Etag和Expire标签访问浏览器缓存.n每当我们点击n - 1视图内部时,我也计划使用它来预取下一个图像,imgNodes并以相同的方式重复使用.
我的问题是:
这甚至是一个有效的想法,给出100多个将使用这个想法的组件,但一次只能看到1个?
这样做会遇到内存问题吗?我假设imgNodes在卸载组件时将收集垃圾.
我们正在使用,redux所以我可以将这些图像保存在商店中,但这似乎是我正在处理缓存而不是利用浏览器的自然缓存.
这个想法有多糟糕?
您无需在所有组件中执行此操作.一旦下载了图像,它就会被浏览器缓存,并且可以在所有组件中访问,因此您只能在高级组件中的某个位置执行此操作.
我不知道你试图通过缓存图像创建什么样的UX,但是,你的代码只会启动下载图像,但不知道图像是否正在下载,是否已成功下载甚至失败.因此,例如,您想要显示一个按钮来更改图像或仅在下载图像时将类添加到组件(为了使图像平滑),您当前的代码可能会让您失望.
您可能希望使用Promises解决此问题.
// create an utility function somewhere
const checkImage = path =>
new Promise(resolve => {
const img = new Image()
img.onload = () => resolve(path)
img.onerror = () => reject()
img.src = path
})
...
// then in your component
class YourComponent extends Component {
this.state = { imagesLoaded: false }
componentDidMount = () =>
Promise.all(
R.take(limit, imgUrls).map(checkImage)
).then(() => this.setState(() => ({ imagesLoaded: true })),
() => console.error('could not load images'))
render = () =>
this.state.imagesLoaded
? <BeautifulComponent />
: <Skeleton />
}
Run Code Online (Sandbox Code Playgroud)
关于内存消耗 - 我认为不会发生任何不好的事情.浏览器通常会限制并行xhr请求的数量,因此您将无法创建巨大的堆使用峰值来崩溃任何内容,因为未使用的图像将被垃圾收集(但仍保留在浏览器缓存中).
Redux商店是存储应用程序状态的地方,而不是应用程序资产,但无论如何,您将无法存储任何实际图像.
| 归档时间: |
|
| 查看次数: |
9767 次 |
| 最近记录: |