GatsbyJS优化何时获取图像



我喜欢Gatsby提供的所有优化,但我希望在提取图像时对有更多的控制。我怎样才能做到这一点?

举个例子,想想一个典型的博客:很多页面,很多文本,很少图片。

Gatsby中的默认行为是,当您滚动到图像时,图像会延迟加载,并带有占位符和过渡(转到任何Medium博客查看其外观)。我不喜欢这样。如果我在30秒前加载页面,那么已经有足够的时间向我发送图像了。没必要给我看一张模糊的照片,我现在应该有真实的照片了。

如何改变这种行为我在文档中发现的唯一一件事是,我可以将我的图像标记为关键图像,以便它们立即开始加载。将我的所有图像标记为关键图像会很糟糕,原因有二:首先,它会减慢最初的"第一次有意义的绘制",因为加载页面下方的图像会浪费部分带宽。其次,当预取到其他页面的链接时,下载大版本的图像会再次浪费带宽。

在我的情况下,所需的行为是首先加载页面的关键资源,然后加载页面的非关键资源。预取链接时,不应加载非关键资源。


编辑:在Cyril和Derek的帮助下,我现在可以在超时的情况下获取图像了。现在我有一个奇怪的问题:

https://epic-haibt-d9fc0a.netlify.com/

就好像"占位符"one_answers"实际图像"的含义被翻转为超时获取的图像。此处为来源的相关部分。

您可以扩展现有的React类&修改其行为。我挖掘了盖茨比图像的来源,看起来道具isVisible负责加载图像。

一旦文件完全加载,就可以安全地说"第一次有意义的绘画"完成了吗?如果是这样的话,我认为我们可以使用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

然后将其用作普通图像组件:

import ImageDelay from '../components/ImageDelay'
// somewhere on your page
<ImageDelay fluid={heroFluid} />

您也可以使用setTimeout而不是window.onload添加延迟。如果用户在一定时间内没有滚动到图像中,就会为他们加载图像。

添加构造函数时出错,因为基类构造函数有props参数。

使用参数调用基构造函数将修复此错误

constructor(props) {
super(props);
this.loadPictures = this.loadPictures.bind(this);
}

由于gatsby使用服务器端渲染windowdocument,因此应谨慎使用。请参阅:https://www.gatsbyjs.org/docs/debugging-html-builds/和https://github.com/gatsbyjs/gatsby/issues/5835.您应该先检查windowdocument对象是否存在,然后取消订阅事件,以避免内存泄漏。

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使用内部机制来更新页面,并且不会触发window.load事件,并且在页面更新时也不会触发任何事件。请参阅#2906-gatsby-link确定加载何时完成,以及#3415-形式化API以挂钩到页面加载生命周期。。。

此外,在React应用程序中通常避免继承,并且依赖内部行为(isLoaded状态)不能保证在未来版本中工作。出于这些原因,我认为最好使用critical属性或创建自己的gatsby-image实现。

class PictureDelay extends React.Component {
render() {
return <Picture critical={true} {...this.props} />;
}
}

最新更新