How to prevent Gatsby image from blurring a logo with every reload? - reactjs

I've read through the gatsby-image docs but can't figure out how to turn something off. By default, it seems gatsby-image loads a thumbnail of an image, then loads the image progressively. Basically a nice placeholder effect. But I find that my logo keeps blurring everytime I change pages. Here's my code:
<StaticQuery
query={graphql`
query {
file(relativePath: { eq: "appendto_logo.png" }) {
childImageSharp {
# Specify the image processing specifications right in the query.
# Makes it trivial to update as your page's design changes.
fixed(width: 150) {
...GatsbyImageSharpFixed
}
}
}
}
`}
render={data => <Img fixed={data.file.childImageSharp.fixed} />}
/>
Any thoughts? How to prevent that blurring effect? Or the thumbnail loading effect...

Switching to GatsbyImageSharpFixed_noBase64 solved it (instead of just ...GatsbyImageSharpFixed)

Update
critical is now deprecated in favor of loading:
- <Img critical fixed={ ... } />
+ <Img loading="eager" fixed={ ... } />
Also use _noBase64 sharp fragments to completely remove the blur effect, as #epsilon42's comment & Kyle's answer suggested.
And finally, to persist a component (navigation bar, etc.) between page load, you can wrap the pages in a layout with that component.
Original answer
I think you can pass in a critical prop to Gatsby Image, like this: <Img critical fixed={ ... }> It will always load the image immediately. You might want to add fadeIn in there as well:
Images marked as critical will start loading immediately as the DOM is parsed, but unless fadeIn is set to false, the transition from placeholder to final image will not occur until after the component is mounted.
Gatsby Image docs

To avoid the blurring effect you could just hide the placeholder using the placeholderStyle attribute:
<Img fixed={data.logoImage.childImageSharp.fixed} placeholderStyle={{ visibility: "hidden" }}/>

Related

Can I preload an image for a component before it gets used in nextjs

I'm close to deploying a project with NextJS, however I noticed that a lot of the images take quite a bit of time to appear on screen.
I've installed sharp and set the priority to true, but even then images appear pretty slowly.
There's one part of the application, where a specific component gets conditionally rendered. That component has a small illustration included (about 30-50kb depending on the type) and it only shows for 2 seconds, since it's a short confirmation for the user.
There's also another page, which has a bigger illustration on it (about 500kb), which I would love to preload, since it takes a good second to load, when the component gets rendered.
Basically what I'd like to do, is fetch the needed images/illustrations ahead of time, before they need to be used, so that they appear instantaneously for the user.
Is there a way to do this in NextJS? Also happy to move away from the Next/Image component and just use img tags to do this.
Not sure whether code helps in this case, but here is how I display the 500kb image:
<div className="result__illustration">
<Image
src={resultIllu}
alt=""
layout="responsive"
objectFit="contain"
priority={true}
/>
</div>
This is possible using new Image() and then adding an src attribute to it. I made a simple example to illustrate a memoized version of this behavior:
codesandbox
const PreloadedImage = preloadImage("https://via.placeholder.com/700x500");
export default function App() {
return (
<div className="App">
<PreloadedImage alt="Placeholder image" />
</div>
);
}
function preloadImage(src) {
const image = new Image();
image.src = src;
return function PreloadedImage(props) {
return <img {...props} src={src} />;
};
}

Add custom component after searchbar in #react-navigation/native-stack

I'm having the following design
Looking for a smart way to accomplish my mission using #react-navigation/native-stack
Requirements are the following:
Filters should be present after native search bar.
Screen title should automatically shrink/expand upon scroll. As it's done by default.
The problem is I don't see any proper place to put filters component to.
If I put it to content title animation doesn't work. It's always small because content's outer component should be a ScrollView or its ancestor like FlatList or SectionList. Nested ScrollView of the same direction are not supported too.
<View>
<FiltersComponent />
<SectionList ... />
</View>
If I put it like that title animation works, but filters go out of bounds on scroll.
<SectionList ListHeaderComponent={FiltersComponent} ... />
I tried even following, but title looks buggy, its both presentations (small and large) visible in the same time.
// set headerLargeTitle: true initially
<SectionList
onScroll={(e) => {
navigation.setOptions({ headerLargeTitle: e.nativeEvent.contentOffset.y === 0 });
}}
/>
Can anyone suggest something?

React <video/> flickers and restarts on parent rerender

I am trying to use a video in a component, but whenever a parent is rerendered (unavoidable in this situation, due to a lot of complex functionality) the video tag flashes/flickers and restarts. I have tried using useMemo and seperating into a seperate component and implementing React.memo(), shouldComponentUpdate(), and extending PureComponent (although i recognize its not recommended to use these to reliably prevent a rerender in the docs). I am thinking it some problem with the functionality of the html video player or something right now because i tried logging on the components rerender and am seeing the behaviour without any log to the console. In this visual example you can see on the top the component with this behaviour, and on the bottom another component (That has almost the same code) with a gif that uses image instead of video
let url = "url here"
const renderVideo = useMemo(
() => (
<video
src={url}
controls
muted={true}
autoPlay
height="100%"
width="100%"
style={{
borderRadius: "0.25rem",
}}
/>
),
[url, keepScale, fit]
);
return (
<Widget
{...props}
editorContent={<EditorContent />}
>
{renderVideo}
</Widget>
);
that should be the relevent code. This component is pretty simple, complex functionality is implemented in the Widget component you can see

Gatsby Image inside Flickity carousel

I am creating a gatsby website that uses the flickity-react-component to display a slider with product images. I believe that I should use the gatsby image to make it load faster, but when I try it, the Image does not display (it is 0x0 pixels).
This is the code I am trying to run:
const ThirdPage = ({ data }) => {
...
function Carousel() {
return (
<Flickity
className={'carousel'} // default ''
elementType={'div'} // default 'div'
options={flickityOptions} // takes flickity options {}
disableImagesLoaded={false} // default false
reloadOnUpdate // default false
static // default false
>
<Img fluid={data.imgPrincipal.childImageSharp.fluid} alt="Mulher a lavar o cabelo com o chuveiro ecológico" />
<img src="https://placeimg.com/640/480/nature" />
<img src="https://placeimg.com/640/480/nature" />
<img src="https://placeimg.com/640/480/architecture" />
</Flickity>
);
}
The "Img" is the one using the gatsby image, the others are what I had before.
This is the result
I don't get an error when running this, I believe this might be because gatsby-image creates a div.
Can someone help me make this work? I am a beginner, so if it's something very advanced, I would appreciate an alternative ... Thank you.
Indeed, gatsby-image is not only a simple image. It creates a wrapper with a few nested div HTML structure inside to make the blur effect and the rest of the improvements.
Take a look at gatsby-image docs:
Note: gatsby-image is not a drop-in replacement for <img />. It’s
optimized for fixed width/height images and images that stretch the
full-width of a container. Some ways you can use <img /> won’t work
with gatsby-image.
It may not work with all sliders.
I've used it with other sliders that accept a nested structure inside, not only a single <img> tag such as Swiper or Slick.

scrollIntoView doesn't scroll to bottom when there is an image/file in the container

I have a react app that has a commenting section. Users can comment pdfs, images, excel & csv files. When a user opens up a project I want the container with comments to scroll to the very bottom. The functionality works perfectly if the comments are only text. However, when someone adds any sort of file in, it will no longer scroll all the way to the bottom. It only scroll about 3/4 and the more files added, the less it scrolls.
This is where its called:
componentDidUpdate() {
this.scrollToBottom()
}
scrollToBottom(){
this.el.scrollIntoView({ behavior: 'smooth' })
}
This is whats in my render:
<div className="comments-container-parent">
{this.props.projectComments.map((comment) => {
return <ProjectComment editCommentText={this.props.editCommentText} commentId={comment.id} deleteComment={this.props.deleteComment} comment={comment} projectData={this.props.projectData} />
})}
<div style={{ float:"left", clear:"both" }} ref={el => { this.el = el }}></div>
</div>
How can I get the scroll to work properly when files are involved?
I ran into this recently and the solution was to make sure that there is a container (div or whatever) with a fixed height set. Setting the height dynamically or based on some logic in a useEffect hook doesn't work. The height of the images must be set from the start so that when the list renders, the height of the list doesn't change.

Resources