Show HN: An Almost Ideal React Image Component
github.com
github.com
(previously discussed: https://news.ycombinator.com/item?id=15696596)
- retina/3x support - support for styled components extend feature (if can be made a lightweight implementation) - maybe default max width of 100% on mobile? - optional ability to overlay an empty full size block so the image cant easily be right clicked and saved
> maybe default max width of 100% on mobile?
It is.
> optional ability to overlay an empty full size block so the image cant easily be right clicked and saved
Not sure what you mean, but as soon as image loaded it turns into good old image, so you can do right click
> Not sure what you mean, but as soon as image loaded it turns into good old image, so you can do right click
I believe he wants the opposite of that, putting a div over the image so it cannot be right clicked and saved.
Why can’t the image and DOM spec be upgraded to include lazy loading and touch to download? I can’t think of a use case where you wouldn’t want this.
React components like these are nice, but the real question is why doesn't your _browser_ already do this. Not "why doesn't the spec say what needs to happen", but why haven't Microsoft, Google, Mozilla, Opera, etc. implemented network-and-content-traversal-appropriate image handling? (one answer might be "because apparently users don't actually ask for it enough", but I honestly don't know).
You don't need standard behaviour, you just need _good_ behaviour. And if every browser does that differently, but it's appropriate to the network speed and processing capabilities, then as a dev the issue of "making sure images load appropriately" becomes as irrelevant as "making sure your webfont actually loads" has become in the modern browser landscape.
These fancy image placeholders seem more designed to save on CDN costs than to provide a good UX.
This may come off a bit negative, but I disagree that it provides a better UX. I don't know if I've grown jaded or cynical, or if we just have drastically different preferences. I think embedding a thumbnail with a link to the full-sized image is better; it's certainly simpler. In general, I don't think the tradeoffs are worthwhile.
Some thoughts:
* There is no mention of module size. That can have a big effect on your initial pageload. Of course, this depends a lot on the context in which you are using said module. It might still be sensible for certain kinds of galleries, perhaps less so for an application for which images are of secondary concern.
* The discussion on performance is too focused on mobile and having very few images on the screen at the same time. What about desktop? What if you plan on having more than two images on-screen at the same time? Doing a comparison with traditional img tags on a grid-view gallery with 100 images would be much more interesting.
* I think it would be genuinely interesting to see what the real-world experience would be if you took a popular website and dropped this in. I do not believe that it would often be an improvement. The two sites that come to mind are 4chan and Reddit.
> The discussion on performance is too focused on mobile
Because mobile users have a slower internet connection and worse CPUs.
What kind of performance are you talking about? If load performance, then this component uses well-established techniques (not invented by me), like lazy-loading (known since jQuery times), srcset (web standard), LQIP (used by Facebook, Medium), width, height (required for all blocks in AMP).
If you are talking about JS performance like frame rate or paint or "junk" on the scroll - I didn't measure it but didn't say it was the first target either.
Right now I'm using a homemade <ImgWithPlaceholder src={src} /> that displays a generic gray PNG on 404 or src null.
I'll definitely try your lib as a replacement. I'm excited about the out-of-the-box lazy loading and the LQIP (never heard before.)
I would LOVE an angular service that did this that I can re-use. If only I had the time to fork this and make it work... May need to explore this over the weekend.
Thanks for putting this together!
Consider the yak shaved. :)
I unconditionally hate all scroll-based lazy loading of images. Any other forms of lazy loading of images such as you outline in this post I will also hate, p≥0.96. And attempts to be clever like detecting high latency and working otherwise in such situations normally mess up what I want to happen.
I’ve written about these things before and I’ll doubtless write about it again; https://news.ycombinator.com/item?id=16518010 is the last time I wrote about it on HN and some discussion arose. (The previous time was on the SVG image placeholders article linked elsewhere in these comments.)
I am inspired by your grumbling to write a blog post entitled “Scroll-based lazy loading of images is always bad”. I won’t publish it for a while so I can treat the subject methodically (and I’m busy for the rest of today), but it will come.
Thanks for the imgur comparison; the wording I’ve used does fall down there; in my mind I had distinguished scroll-based lazy loading and scroll-based lazy loading of images. When talking about scroll-based lazy loading of images, I meant where you have content that contains images, rather than situations where the images are the content. (That is, I’m talking about lazy loading just the <img>, not lazy loading content in general.) There are definitely applications for which loading everything up-front is impossible (e.g. imgur infinite scrolling on mobile) or impractical (e.g. showing all the 10,000 messages in a mailbox in an email client that deliberately eschews pagination, like FastMail); in such situations, lazy loading is necessary and while it will often be annoying and imperfect there is and can be no better solution.
Where images are embedded in the content, however, I think that my position is still reasonable; there is an alternative: just load eagerly rather than lazily. Now articles and blog posts are the primary application I have in mind, and I can’t think of any other applications where my position would not hold—given the caveats of interpretation specified in the previous paragraph—but I’m willing to hear other suggestions.
As a rule, I’d much rather see nothing or a solid colour than a pixelated or blurred preview of the image; I find it and the transition surprisingly disconcerting. I mentioned this at https://news.ycombinator.com/item?id=16516126#16558042 and have heard others agree with me.
This component allows to retry image load (click on it).
It can be even more smart, like if network is good go ahead and download everything. Need to think about it
Even if I do have a connection and it all succeeds, if the image is not there when I scroll to it, the lazy loader has failed in its job. And that’s pretty much unavoidable in general content—people don’t always scroll smoothly through a page; I may jump down a page at a time, or skim through some headings looking at illustrations that haven’t loaded yet because they only figured I might be interested in them a bit under half a second ago, and latency is half a second plus probably another couple of tenths of a second of annoying fade-in transition. The possibilities are endless.
Come live in Australia for a bit and deliberately use sites from the US with scroll-based lazy-loading: I predict you will rapidly acquire a healthy dislike for the technique! :-)
But still, as a user I would consistently prefer a plain <img> to any fanciness.
The typical experience reading a medium blog is that I can spend a minute, or a full 15 minutes, digesting the opening paragraphs. With the page idle that whole time. Then I can scroll down to a big brown smear, and read the whole caption before the associated image finishes loading.
I totally understand these images don't need to load with the first round of content. But you know I'm going to scroll down. Just use a timer or something.
> I need React component to asynchronously load images, which will adapt based on network, which will allow a user to control, which image to load.
Plus, I don't get what's exciting about this. But I'm also not a react guy - and this does nothing to make me consider picking it up. Which, is counter to all the cool JS libraries i've pulled into projects over the years, which naturally induced a desire to learn more JS.
I guess if you're hyper focused on react or frontend js in general, this sort of stuff might be more appealing and relevant. but dear god I've got way more important/interesting things to do than spend a day getting images to render in the browser. Nor does this do anything to lower the barriers of entry for people with an idea and a desire to build something. Sometimes I wonder if that's a design intent.
anyway, sorry for the rant. Great job identifying/solving problems, but i don't get the appeal.
This library doesn't really have anything to do with React. Just because it is implemented in React doesn't mean that React needs this, over say Vue or Angular or VanillaJS or w/e "cool" library you like. In fact I would say the existence of libraries like this should make you want to adopt React over a library with less adoption.
I would also suggest you be more open to the idea that these kinds of things matter quite a bit when you are operating at scale. This type of library isn't really intended for the use case where spending time making optimizations isn't important or interesting.
> this does nothing to make me consider picking it up. Which, is counter to all the cool JS libraries i've pulled into projects over the years, which naturally induced a desire to learn more JS.
For shame. What this tells me is that you essentially don't care about your users. The notion of this being something only react/frontend developers care about is also quite off-base. Lets include all the "cool" JS libraries under the sun until the page is bloated, but definitely not the ones that try to make the site perform better... ? Yeah not a good attitude.
Perhaps if you imagine yourself on a metered connection, navigating to a page with a bunch of hires images, wouldn't you appreciate the work the developers put into making the site a better experience for you? That respect for the user is the appeal.
/meta
On this particular issue, I will go further than my parent and say this does not represent a significant step forward in the scheme of things. The problem being solved here is largely akin to a problem I had to solve 15+ years ago with Vanilla JS. It is positively nuts that we are celebrating a "fix" for it all of these years later, and that we are investing so much time on what should be routine by now.
Anyone who is genuinely excited about this should sincerely be asking themselves if it's a good thing that a lengthy post/fairly involved component for sanely displaying images in a browser is the state-of-the-art for Webdev in 2018.
Yes, I get it: browsers don't do x or y. So, yeah, let's add more libs, more frameworks, more shims, more specs...more, more, more. It's almost self-parody by now. Look at the average Webapp of any semi-significant complexity. It is such a hodge-podge of code, languages, technologies, build steps, etc. that it's a wonder any of it works.
I think it's time we all took a step back and ask, "what are we doing? Is this the right model? Is there a better way?"
> The problem being solved here is largely akin to a problem I had to solve 15+ years ago with Vanilla JS.
Of course these problems (multiple!) can be fixed with vanilla js. They all have been, separately, each in their own libraries and stackoverflow posts and custom vanilla code on every project in the past couple decades. The linked page does an excellent job of pointing out the libraries and SO posts it's utilizing to resolve these issues.
The purpose of the linked component is to pull in all these vanilla js fixes and tweaks at once, in a way they'll all work together. A drop-in component to utilize years worth of tweaks and fixes, so you don't have to worry about this crap anymore. Doesn't that kind of cover your complaint? We shouldn't have to deal with it anymore. Drop this in, and worry about something more interesting.
> I think it's time we all took a step back and ask, "what are we doing? Is this the right model? Is there a better way?"
I picked React long before most of my colleagues did, and I continue to feel it's one of the most useful libraries in quite some time for browser-based javascript development. Mostly because it allows for something like this very library - drop-in and move on to something better.
I was also a huge fan of jquery - not because I couldn't do what jquery was doing for me, but because I was tired of doing it repeatedly for different browsers and for each and every project. Same goes with prototype.js when it first came out, though I hated how it modified the underlying objects.
If I'm understanding your post correctly, I feel like these are all attempts to resolve the issues you're speaking toward. To allow us to stop dealing with cross-browser, cross-device, 2-cans and a string connection issues that, ideally, our browsers should be handling for us.
At least we don't have to rely on flash to replace missing browser functionality anymore (I say that as someone who absolutely loved ActionScript3).
Is it acceptable that this is the state of the art? That, 15-20+ years on, we are fixing the same problem and, further, that we are doing so by rolling a bunch of cruft into yet another framework? Is this really what we are shooting for?
>A drop-in component to...
>Drop this in, and worry about something more interesting
Drop it in after learning and adopting a fairly heavyweight framework that forces you to code to a completely different paradigm. Do we really think this is an acceptable solution for simply displaying images on a Web page? I think that's really telling WRT how far off the map we've wandered.
>Doesn't that kind of cover your complaint?
>I feel like these are all attempts to resolve the issues you're speaking toward.
I think React and others are really symptoms of the problem, which is an impedance mismatch between the static document model that underpins the platform on which we are now trying to build fully dynamic applications.
Rather than continuing to paper over browser deficiencies, there needs to be some collaboration between the webdev and browser communities to define more consistent behavior for common scenarios and a standard component/event based model of the type that has proven suitable for GUI-based applications. The Web standards of HTML, DOM, CSS, etc. should not be first-order constructs in this new model. That is, devs should not work in them directly and, to the extent that these standards are useful due to their currently-broad browser support, they should be generated by tooling. We should be laying out our UIs on canvases in our IDEs with flexible grid layouts, and hanging event handlers off of various events a la Swing.
We need to break the current DOM/old Web model that tells us React and others are good simply because they make the impedance mismatch slightly less painful and paper over some browser deficiencies.
I went on a weird tangent with my reply to this comment and just I'm just going to replace it with this. I generally agree with what you're saying as a means forward, but I also think React is a fantastic tool in the meantime.
What we have is, in fact, the state of the art for better or worse. We will get beyond this, but it clearly takes time.
It's not a big deal. Just correct the downvotes and ignore the vocal comments.
I identify with your point of view on this topic. But the way to correct the situation isn't to write a rebuttal here. The world only notices better solutions when they exist, so creating them is step one.
Thanks, but I've clearly not made my point! I am saying that we don't need to each run off and create more solutions as that's how we got here in the first place. That is, we can't solve the problem of too many "solutions" by creating more solutions.
So, I think step one is to step back, all take a breath (devs, browser-makers, etc.) and look at creating a reasonable, cohesive platform for proper Web-development, free of the legacy baggage of a static document-based foundation with reams of duct tape on top.
Lol... this is way easier said than done. The ironic thing is, this has been attempted several times. In fact I would argue this thinking led to the React ecosystem.
Substantially cutting down loading time for a page with 800 high-quality images while still being able to write components in a completely declarative manner.