我喜欢盖茨比提供的所有优化功能,但是我希望对何时提取图像有更多的控制权。我该如何实现?
作为一个例子,考虑一个典型的博客:很多页面,很多文本,很少图片。
Gatsby中的默认行为是,当您滚动到带有占位符并进行过渡的图像时,图像会被懒加载(请转到任何Medium博客以查看其外观)。我不喜欢这样如果我在30秒钟前加载页面,那么已经有足够的时间向我发送图像了。没必要给我看一张模糊的照片,现在我应该有了真实的图像。
如何更改此行为?我在docs中发现的唯一内容是,我可以将图像标记为关键图像,以便它们立即开始加载。将我的所有图像标记为关键图像将是不好的,原因有两个:首先,它会减慢初始的“ First Meanfulful Paint”,因为浪费一部分带宽来加载页面下方的图像。其次,当预取到其他页面的链接时,再次浪费带宽下载大型图像。
在我的情况下,期望的行为是先加载页面的关键资源,然后再加载页面的非关键资源。在预取链接时,不应加载非关键资源。
编辑:在Cyril和Derek的帮助下,我现在可以在超时的情况下获取图像。现在我有一个奇怪的问题:
https://epic-haibt-d9fc0a.netlify.com/
对于随时间获取的图像,好像“占位符”和“实际图像”的含义被翻转了。来源here的相关部分。
答案 0 :(得分:2)
您可以扩展现有的React类并修改其行为。我深入研究了gatsby-image的来源,看起来道具isVisible
负责加载图像。
可以确定地说,一旦文档完全装入,“ First Meanfulful Paint”就完成了吗?如果是这样,我认为我们可以使用window.onload
作为触发来加载图像。
您可以像这样扩展现有的类:
import Image from 'gatsby-image'
class ImageDelay extends Image {
componentDidMount() {
// call the parent class' componentDidMount method
// to preserve existing behavior
super.componentDidMount();
window.onload = () => {
this.setState({
isVisible: true
})
}
}
}
export default ImageDelay
然后将其用作普通的Image组件:
import ImageDelay from '../components/ImageDelay'
// somewhere on your page
<ImageDelay fluid={heroFluid} />
您还可以使用setTimeout
而不是window.onload
添加延迟。如果用户在一定时间内没有滚动到图像,则会为其加载图像。
答案 1 :(得分:2)
由于基类构造函数具有一个props
参数,因此添加构造函数会出错。
使用参数调用基本构造函数将解决此错误
constructor(props) {
super(props);
this.loadPictures = this.loadPictures.bind(this);
}
由于gatsby使用服务器端渲染 window
或document
时应谨慎使用。请参阅:https://www.gatsbyjs.org/docs/debugging-html-builds/和https://github.com/gatsbyjs/gatsby/issues/5835。您应该先检查window
或document
对象是否存在,然后再取消订阅该事件,以避免内存泄漏。
class PictureDelay extends Picture {
constructor(props) {
super(props);
this.loadPictures = this.loadPictures.bind(this);
}
loadPictures() {
console.log("Loading pictures...");
this.setState({ isVisible: true });
}
componentDidMount() {
super.componentDidMount();
if (typeof window !== "undefined") {
window.addEventListener("load", this.loadPictures);
// window.setTimeout(this.loadPictures, 1000);
}
}
componentWillUnmount() {
super.componentWillUnmount();
if (typeof window !== "undefined") {
window.removeEventListener("load", this.loadPictures);
}
}
}
使用gatsby链接时,不会重新加载页面。为了提高性能, Gatsby 使用内部机制来更新页面,并且在页面更新后不会触发window.load
事件,也不会触发任何事件。
参见#2906 - gatsby-link determine when loading is complete和#3415 - formalize API for hooking into page load lifecycle...
此外,不能保证inheritance is generally avoided in React
application和依靠内部行为(isLoaded
状态)在将来的版本中也可以使用。基于这些原因,我认为最好使用critical
属性或创建自己的gatsby-image
实现。
class PictureDelay extends React.Component {
render() {
return <Picture critical={true} {...this.props} />;
}
}