Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server-side pre-rendered images stuck at opacity: 0 #4

Closed
austinpray opened this issue Sep 18, 2015 · 11 comments
Closed

Server-side pre-rendered images stuck at opacity: 0 #4

austinpray opened this issue Sep 18, 2015 · 11 comments

Comments

@austinpray
Copy link

When using the react-redux-universal-hot-example repo as a starting point (https://github.com/erikras/react-redux-universal-hot-example/tree/4705688b879f853ede08e3872bc083cc84227824)

My component:

<Image className="thumbnail" src="https://i.imgur.com/l50kGUz.png" />

The HTML that comes through in the view source:

<img class="thumbnail" src="https://images.unsplash.com/photo-1439003511744-2a0490ea0a88?q=80&amp;fm=jpg&amp;s=4dd5809698048edf8b82eedb82ca8cec" style="transition:opacity 1s;opacity:0;" data-reactid=".mzv5v08jcw.2.0.0.0">

Notice how the opacity is frozen at 0.

How to reproduce:

  1. Clone that example repo down
  2. npm i --save legit-image
  3. Spam Image tags on the homepage or whatever page
  4. npm start

Race condition with server-side rendering?

@zackify
Copy link
Member

zackify commented Sep 18, 2015

Well it's stuck at opacity 0 because when it is initially rendered the opacity is supposed to be 0. I'm assuming you didn't mount the component on the client side after server rendering? I'm trying to think of a way to make this work correctly when you only want to server render...

@zackify
Copy link
Member

zackify commented Sep 18, 2015

The only fix I can think of is that you have to include the component client side, and if server rendering pass a prop, something like server={true} so that it will just return a regular image tag if it's server rendered

@austinpray
Copy link
Author

I'll see if I can come back with a solution after looking at your code. Haven't peeped it yet.

@zackify
Copy link
Member

zackify commented Sep 18, 2015

It's really simple, I completely see the problem, just unsure of the easiest way to fix it.

@constb
Copy link

constb commented Oct 8, 2015

@zackify how about rendering it with data-src, loading image client side with new Image and then setting src and triggering transition? I think the root cause of this problem is that with server-rendered img tag image gets loaded before component is mounted and thus it doesn't receive load event.

@constb
Copy link

constb commented Oct 8, 2015

@zackify also this way it would be easy to implement #3

@constb
Copy link

constb commented Oct 8, 2015

@zackify actually, now that I thought about it, maybe you don't need src or data-src on initial render. After all you aren't exposing image url to any outside code. You can manually preload image and then set src only when it's already in the browser cache.

@zackify
Copy link
Member

zackify commented Oct 8, 2015

@constb so what would be the real fix for this?

@constb
Copy link

constb commented Oct 9, 2015

ah, I see the ambiguity here. by new Image() I meant new window.Image() of course. It has its own onload and onerror, and setting src on it triggers request without affecting the DOM. After it's loaded you just set DOM's img.src to the loaded Image's src and start the transition. Changing props.src should work the same way.

@zackify
Copy link
Member

zackify commented Apr 13, 2016

@austinpray @constb sorry about it being 6 months later... I think I came up with an easy solution. If window is undefined, it will return opacity: 1. Even if you have React mount client side, you probably want images to show before it renders there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants