Coder Social home page Coder Social logo

merri / react-lazy Goto Github PK

View Code? Open in Web Editor NEW
119.0 119.0 10.0 1.98 MB

Universal lazy loader components using IntersectionObserver for React

Home Page: https://merri.github.io/react-lazy/

License: MIT License

JavaScript 100.00%
lazy-load lazy-loading lazyload react react-component react-components reactjs

react-lazy's Introduction

Hello there! ๐Ÿ‘‹

Me + websites I work on = positive effects on all the metrics.

Free tip for great front-end!
If you can solve it without JavaScript, you should solve it without JavaScript.
Progressive enhancement is better than depending on JS.

I love Astro and any other new framework which ditches throwing client-side executed JavaScript at every problem.

The things I do tend to be ahead of the curve, sometimes by years. Which means I'm two things: a continuous learner and autistic.

Currently working on vr.fi, for example contributed a lot to the Junat kartalla service (live train tracker map).

Check my homepage for a blog on web development and lots of other cool stuff.


A lot of my stuff here on GitHub has now been outdated by the changing times. For example no more need for react-lazy since you can just do <img loading="lazy" />. What can we learn from this? JavaScript code for the front-end becomes outdated, but HTML and CSS keep on living. Maybe we should work more on just HTML and CSS, and less on JS since it is the short-lived solution until standards make things possible without JS.

react-lazy's People

Contributors

dependabot[bot] avatar merri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

react-lazy's Issues

Relies on react-dom/server

I have noticed that this lib relies on react-dom/server being used on client code

Here:

import { renderToStaticMarkup } from 'react-dom/server'

and here:

renderToStaticMarkup(React.createElement('noscript', null, children))

Which causes

    at propsWithNoScriptRender (@domain-group_fe-pa-listing-details_0.32.11_2.2.1_client.js:68415)
    at Lazy.render (@domain-group_fe-pa-listing-details_0.32.11_2.2.1_client.js:67848)
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (react.js:5941)
    at ReactCompositeComponentWrapper._renderValidatedComponent (react.js:5961)
    at ReactCompositeComponentWrapper.wrapper [as _renderValidatedComponent] (react.js:12353)
    at ReactCompositeComponentWrapper.mountComponent (react.js:5574)
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (react.js:12353)
    at Object.mountComponent (react.js:12978)
    at ReactCompositeComponentWrapper.mountComponent (react.js:5579)
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (react.js:12353)

on client code, react-dom/server as far as im aware should not be used on client code

Broken?

Tried the sample inside Create React App:

<Lazy
  component="a"
  href="/"
  className="image-link image-link--100px"
  ltIE9
>
  <img
    alt="My Lazy Loaded Image"
    className="image-link__image"
    src="my-lazy-loaded-image.png"
  />
</Lazy>

And was met with the following error:

React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

Node v6.11.0
React v15.6.1

Was excited to finally find a lazy-loader that works with horizontal scrolling, but alas. :'(

Fails when running webpack on Nextjs

I'm really loving react-lazy, thanks a lot for a great library! Unfortunately, I can't get it to work in production...

When running yarn build I get the following error on heroku and locally:

remote:        > Using "webpack" config function defined in next.config.js.
remote: > Failed to build on /tmp/a57b28bb-81ed-4653-af81-be7a88dca87b
remote: { Error: ./~/react-lazy/dist/module/index.js
remote: Module not found: Error: Can't resolve 'react-dom/server' in '/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-lazy/dist/module'
remote: resolve 'react-dom/server' in '/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-lazy/dist/module'
remote:   Parsed request is a module
remote:   using description file: /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-lazy/package.json (relative path: ./dist/module)
remote:     Field 'browser' doesn't contain a valid alias configuration
remote:     aliased with mapping 'react-dom': '/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js' to '/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server'
remote:       using description file: /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-lazy/package.json (relative path: ./dist/module)
remote:         Field 'browser' doesn't contain a valid alias configuration
remote:       after using description file: /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-lazy/package.json (relative path: ./dist/module)
remote:         using description file: /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/package.json (relative path: ./dist/react-dom.min.js/server)
remote:           as directory
remote:             /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server doesn't exist
remote:           no extension
remote:             Field 'browser' doesn't contain a valid alias configuration
remote:             /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server doesn't exist
remote:           .js
remote:             Field 'browser' doesn't contain a valid alias configuration
remote:             /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server.js doesn't exist
remote:           .json
remote:             Field 'browser' doesn't contain a valid alias configuration
remote:             /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server.json doesn't exist
remote: [/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server]
remote: [/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server]
remote: [/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server.js]
remote: [/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server.json]
remote:  @ ./~/react-lazy/dist/module/index.js 18:14-41
remote:  @ ./components/ArticleContent.js
remote:  @ ./components/ArticlePage.js
remote:  @ ./pages/article.js?entry
remote:  @ multi ./pages/article.js?entry
remote:     at /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/next/dist/server/build/index.js:181:21
remote:     at /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/webpack/lib/Compiler.js:272:15
remote:     at Compiler.emitRecords (/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/webpack/lib/Compiler.js:367:37)
remote:     at /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/webpack/lib/Compiler.js:265:12
remote:     at /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/webpack/lib/Compiler.js:360:11
remote:     at next (/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/tapable/lib/Tapable.js:154:11)
remote:     at Compiler.compiler.plugin (/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/webpack/lib/performance/SizeLimitsPlugin.js:99:4)
remote:     at Compiler.applyPluginsAsyncSeries1 (/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/tapable/lib/Tapable.js:158:13)
remote:     at Compiler.afterEmit (/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/webpack/lib/Compiler.js:357:8)
remote:     at Compiler.<anonymous> (/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/webpack/lib/Compiler.js:352:14)
remote:   errors: [ './~/react-lazy/dist/module/index.js\nModule not found: Error: Can\'t resolve \'react-dom/server\' in \'/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-lazy/dist/module\'\nresolve \'react-dom/server\' in \'/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-lazy/dist/module\'\n  Parsed request is a module\n  using description file: /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-lazy/package.json (relative path: ./dist/module)\n    Field \'browser\' doesn\'t contain a valid alias configuration\n    aliased with mapping \'react-dom\': \'/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js\' to \'/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server\'\n      using description file: /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-lazy/package.json (relative path: ./dist/module)\n        Field \'browser\' doesn\'t contain a valid alias configuration\n
     after using description file: /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-lazy/package.json (relative path: ./dist/module)\n        using description file: /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/package.json (relative path: ./dist/react-dom.min.js/server)\n          as directory\n
       /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server doesn\'t exist\n          no extension\n            Field \'browser\' doesn\'t contain a valid alias configuration\n            /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server doesn\'t exist\n          .js\n            Field \'browser\' doesn\'t contain a valid alias configuration\n            /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server.js doesn\'t exist\n          .json\n            Field \'browser\' doesn\'t contain a valid alias configuration\n            /tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server.json doesn\'t exist\n[/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server]\n[/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server]\n[/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server.js]\n[/tmp/build_929ca650a0764bc17e7936cbf042fd03/node_modules/react-dom/dist/react-dom.min.js/server.json]\n @ ./~/react-lazy/dist/module/index.js 18:14-41\n @ ./components/ArticleContent.js\n @ ./components/ArticlePage.js\n @ ./pages/article.js?entry\n @ multi ./pages/article.js?entry' ],
remote:   warnings: [] }
remote: error Command failed with exit code 1.

package.json

{
  "dependencies": {
    "@mars/heroku-js-runtime-env": "^3.0.0",
    "express": "^4.15.3",
    "file-loader": "^0.11.1",
    "graphql-tag": "^2.1.0",
    "image-webpack-loader": "^3.3.1",
    "lru-cache": "^4.0.2",
    "next": "^2.4.0",
    "node-sass": "^4.5.3",
    "raw-loader": "^0.5.1",
    "react": "^15.5.4",
    "react-apollo": "^1.2.0",
    "react-dom": "^15.5.4",
    "react-dom-server": "^0.0.5",
    "react-lazy": "^0.2.1",
    "sass-loader": "^6.0.5",
    "verge": "^1.9.1"
  },
  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "node server.js",
    "heroku-postbuild": "npm rebuild node-sass && next build"
  }
}

Webpack

const path = require('path')
const glob = require('glob')

module.exports = {
  webpack: (config, { dev }) => {
    config.module.rules.push(
      {
        test: /\.(css|scss)/,
        loader: 'emit-file-loader',
        options: {
          name: 'dist/[path][name].[ext]'
        }
      }
    ,
      {
        test: /\.css$/,
        use: ['babel-loader', 'raw-loader']
      }
    ,
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        loaders: [
          'file-loader?hash=sha512&digest=hex&name=[hash].[ext]',
          'image-webpack-loader?bypassOnDebug&optimizationLevel=7&interlaced=false'
        ]
      }
    ,
      {
        test: /\.s(a|c)ss$/,
        use: ['babel-loader', 'raw-loader',
          { loader: 'sass-loader',
            options: {
              includePaths: ['scss', 'node_modules']
                .map((d) => path.join(__dirname, d))
                .map((g) => glob.sync(g))
                .reduce((a, c) => a.concat(c), [])
            }
          }
        ]
      }
    )
    return config
  }
}

Instantly Loading img tags That Are Within Hidden Containers

Recreation steps

Markup:

<div className='hidden'>
  <Lazy cushion={0} >
    <img className='impression-tracker'
      src={url} />
  </Lazy>
</div>

Create a <div> that has display: none on it in order to hide it.
Put an <img> wrapped in a <Lazy> component inside of this hidden div.

Results

The <img> tag's src is requested instantly no matter what, even if the <img> and container would be way outside of the viewport once display: block is given to the container. This means the <img> tag fails to lazily load, and is instead loaded on pageload.

Info

I'm not sure if this is unexpected behavior, but I'd assume so.

Warning react 16.0

Warning: Prop dangerouslySetInnerHTML did not match.

Server:
<noscript>&lt;img src=\"my_url_picture\" /&gt;</noscript>
Client:
<noscript><img src=\"my_url_picture\"></noscript>

Unable to get images to load

Hey @Merri, sorry for a generic subject line but I've been unable to get react-lazy to function with my setup. Essentially, when the page loads, the images are not loaded. If I resize the window, or call checkElementsInViewport (in componentDidMount), then the images load but unfortunately, all of the images load (as opposed to only those in viewport) :/

Here is my code:

<div className = {styles.imageGroup} >
  <Lazy onLoad = {this.handleWrapperLoad}>
   {this.renderImages()}
  </Lazy>
</div>
.imageGroup {
	border: 1px solid purple;
	min-height: 600px;
	width: 100%;
	display: flex;
	flex-wrap: wrap;
}

/* imageWrapper is just container for each image */
@media screen and (min-width: 600px) {
  .imageWrapper {
    width: calc(50% - 2rem);
  }
}

@media screen and (min-width: 1000px) {
  .imageWrapper {
    width: calc(33.3333% - 2rem);
  }
}

Here is what the component looks like in Devtools:
screen shot 2017-07-22 at 3 15 34 pm


I also tried using proto-img branch but ran into the following JS errors:
screen shot 2017-07-22 at 3 05 26 pm


I imagine I am doing something simple wrong, so any tips are much appreciated :)

React 15.5: Deprecation warnings for React.createClass and React.PropTypes

Since react 15.5.0 deprecation warnings are showing in the console for this package:

Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.

Warning: Lazy: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.

Image not showing on Chrome v75

Hi, I am having a weird behaviour after this Chrome update, in which some of the images continue to be wrapped in a <noscript> and neither onViewport and onLoad gets called. That is not happening at all with older Chrome versions or different browsers.

Since the code was working fine before this update and that nothing changed on our end and this specific version is the problem, I didn't really know what to share here code-wise.

I'd like to know if you had any issues recently and/or if you have any idea of what could have happened.

ltIE9 prop

First of all - thanks for your work on the lib
I like it and it seems its the only one that works for all my use cases ๐ŸŽ‰

One thing i did notice is that you have an ltIE9 prop - is this needed?
React no longer supports ie8 so not sure why this library needs to support it (unnecessary code)

Im happy to throw up a PR for it if you agree

Too many images are loading

It works but not based on the viewport. It renders way more images than it should and I am not sure why. I am loading a grid of images and it seems to load like 20 or so before they start to load based on viewport. Here is the component that I am using it with

displayArtWorks = () => { return this.props.works.map( work => <Grid.Column key={work.id} mobile={8} tablet={4} computer={4}> <Transition visible={this.state.visible} animation='fade' duration={1000}> <Link to={${this.props.path}/${work.id}} rel="noopener noreferrer"> <Lazy> <Image alt={work.title} src={work.src} fluid /> </Lazy> </Link> </Transition> </Grid.Column> ) }

Any ideas on how to get around that would be great. Thanks.

Unable to load images inside a scrolling div

Hey @Merri, I was trying to use react-lazy but its not working.

The issue is regarding images inside a scrolling div.

The images inside a scrolling div which are in view-port gets loaded with the page load, but if I scroll the div the rest of the images coming to view-port are not getting loaded until the main scroll of the page is scrolled.

Hope you understand the issue, and your response regarding the same is highly appreciated.

Doesn't fall back if image fails to load

I can briefly see my imgWrapperComponent being rendered, but if an image src URL doesn't return an image, imgWrapperComponent is removed and never shown again.

There needs to be a fallback function.

Noscript

Can we disable noscript ? Because there is a conflict with another component that I use

Google bot compatibility

Hi @Merri, Thank you for putting out this library! I noticed that you use the noscript solution to make content crawlable. Another popular library LazySizes uses the logic described in this link - aFarkas/lazysizes#215 (comment)

Wondering your thoughts on the two solutions, and if it would make sense to switch?

Thank you!

lazy load not working for hidden tabs

I have 3 tabs. and the second tab has list of cards, now when I click on the second tab then I am not able to see a card with images unless I scroll.

I debug code and found that viewport plugin is giving me trouble.

I saw one method in your document.

import { checkElementsInViewport } from 'react-lazy'

// now you're being a very lazy dev...
setInterval(checkElementsInViewport, 250)

But I don't know how it works.

Do I need to call checkElementsInViewport when I click on 2 tab?

v0.3.0 fails if ltIE9 attribute is missing

Finally got around to pushing this release to npm only to find out that there appears to be a bug when using the main code path. Don't know where the issue is just yet, but right now <Lazy ltIE9> works but without ltIE9 it does not.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.