hilongjw / vue-lazyload

A Vue.js plugin for lazyload your Image or Component in your application.
http://hilongjw.github.io/vue-lazyload/
MIT License
7.98k stars 865 forks source link

v1.3.0Bug求证:v-lazy会加载超出可视区域内的图片? #372

Open yilingsj opened 5 years ago

yilingsj commented 5 years ago

------------------更新:20190628 23:14 我对比了下v1.2.6和v1.3.0版本的区别,发现把v1.2.6版本中的key: "checkInView", 这一段内容复制到v1.3.0版本中即可解决问题。如图: 修改v1.3.0中代码部分如图 为此,我录制了一个视频,链接地址: 视频演示v1.3.0版本bug重现 视频有点长,可以分段看,主要有以下三段: 00:25s,使用v1.3.0版本,页面在加载时会加载所有图片,此时bug重现了; 01:22s,改用v1.2.6版本,此时页面首次加载只有4张图片,一个loading.gif和3张图片,符合预期要求; 04:20s,开始修改v1.3.0版本,修改后实现了预期效果

------------------以下为旧内容 不知道是不是写法不对,我写了一个简单的页面,页面默认只会显示3个li,当然,我给li有最小高度230px,以确保页面的可视区域只有这3个li。换句话说:页面的可视区域图片数量为3个。如图: li最小高度占位页面 但是,当我使用v-lazy加载图片后,刷新页面会导致加载所有的图片,请求中可以看到一下子加载了20+张,这并不是我想要的,请问如何修改参数? 如图: 关掉注释后图片会全部加载 vue-lazyload会加载所有图片

yilingsj commented 5 years ago

补充一下: 改用vue-lazyload-img后实现预期效果 最终我想要这种效果,页面只加载可视区域图片,滚动时再加载下面的图片

stylergergely commented 5 years ago

I can only guess that the previous commenter has the same issue, but we see a similar problem in our app with the following packages:

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build:production": "vue-cli-service build --mode production && mv dist/index.html dist/entry.html && rsync -a dist/ ../public",
    "lint": "vue-cli-service lint",
    "test:unit": "vue-cli-service test:unit",
    "test:e2e": "vue-cli-service test:e2e",
    "svg": "vsvg -s ./src/assets/icons -t ./src/components/icons"
  },
  "dependencies": {
    "animate.css": "^3.7.0",
    "axios": "^0.18.0",
    "axios-mock-adapter": "^1.15.0",
    "brotli-webpack-plugin": "^1.1.0",
    "buefy": "^0.6.7",
    "compression-webpack-plugin": "^2.0.0",
    "html-format": "^1.0.1",
    "jquery": "^3.3.1",
    "md5": "^2.2.1",
    "minireset.css": "0.0.3",
    "mobile-detect": "^1.4.3",
    "moment": "^2.22.2",
    "numeral": "^2.0.6",
    "portal-vue": "^1.5.1",
    "query-string": "^6.2.0",
    "rails-ujs": "^5.2.1",
    "v-tooltip": "^2.0.0-rc.33",
    "vue": "^2.5.17",
    "vue-carousel": "^0.16.0-rc1",
    "vue-head": "^2.1.0",
    "vue-js-modal": "^1.3.26",
    "vue-lazyload": "^1.2.6",
    "vue-mq": "^0.2.1",
    "vue-progressbar": "^0.7.5",
    "vue-read-more": "^1.1.1",
    "vue-router": "^3.0.1",
    "vue-svg-loader": "^0.10.0",
    "vue-svgicon": "^3.2.0",
    "vue-zoom": "^1.1.0",
    "vuex": "^3.0.1",
    "webpack-manifest-plugin": "^2.0.4"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.0.1",
    "@vue/cli-plugin-e2e-nightwatch": "^3.0.1",
    "@vue/cli-plugin-eslint": "^3.0.1",
    "@vue/cli-plugin-unit-mocha": "^3.0.1",
    "@vue/cli-service": "^3.0.1",
    "@vue/eslint-config-prettier": "^3.0.1",
    "@vue/test-utils": "^1.0.0-beta.20",
    "chai": "^4.1.2",
    "node-sass": "^4.9.0",
    "sass-loader": "^7.0.1",
    "vue-template-compiler": "^2.5.17",
    "webpack-modernizr-loader": "^5.0.0"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "@vue/prettier"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

So basically we have a page full of images having v-lazy attributes in a template, something like this:

            <div class="box-slider__content-inner-image-wrapper">
              <div class="box-slider__content-image">
                <img class="box-slider__content-img" v-lazy="top.popular_articles_daily[0].thumbnail" :key="top.popular_articles_daily[0].thumbnail" alt="IMAGE">
              </div>
              <div class="box-slider__content-warpper">
                <div class="box-slider__content-warpper-look">
                  {{ top.popular_articles_daily[0].type }}
                </div>
                <p class="box-slider__content-warpper-text">
                  {{ top.popular_articles_daily[0].title }}
                </p>
                <p class="box-slider__content-warpper-date">
                  {{ top.popular_articles_daily[0].release_time | date_split_by_dot }}
                </p>
              </div>
              <global-navigation-default-touch :isTransparent="true"></global-navigation-default-touch>
            </div>
          </div>

But not matter what configuration I use the images are loaded eagerly!

I tried using:

Vue.use(VueLazyload, {
  preLoad: 0.3
});

and

Vue.use(VueLazyload, {
  observer: true,
  observerOptions: {
    // If the image gets within 50px in the Y axis, start the download.
    rootMargin: '50px 0px',
    threshold: 0.01
  }
});

to no avail.

I suspect (and this is pure speculation) the latest Chrome update basically broke the plugin and rendered it pointless. I started seeing this error on the 3rd line of the code below:

undefined:1 GET http://localhost/undefined 404 (Not Found)
Image (async) |   |  
-- | -- | --
  | loadImageAsync | @ | vue-lazyload.esm.js?caf9:524
  | (anonymous) | @ | vue-lazyload.esm.js?caf9:802
  | (anonymous) | @ | vue-lazyload.esm.js?caf9:764
  | image.onload | @ | vue-lazyload.esm.js?caf9:527
  | load (async) |   |  
  | loadImageAsync | @ | vue-lazyload.esm.js?caf9:526
  | renderLoading | @ | vue-lazyload.esm.js?caf9:760
  | load | @ | vue-lazyload.esm.js?caf9:796
  | (anonymous) | @ | vue-lazyload.esm.js?caf9:1296
  | _lazyLoadHandler | @ | vue-lazyload.esm.js?caf9:1290
  | runCallback | @ | vue-lazyload.esm.js?caf9:476
  | (anonymous) | @ | vue-lazyload.esm.js?caf9:479
  | (anonymous) | @ | vue-lazyload.esm.js?caf9:1048
  | (anonymous) | @ | vue.runtime.esm.js?2b0e:1833
  | flushCallbacks | @ | vue.runtime.esm.js?2b0e:1754
  | Promise.then (async) |   |  
  | microTimerFunc | @ | vue.runtime.esm.js?2b0e:1802
  | nextTick | @ | vue.runtime.esm.js?2b0e:1846
  | add | @ | vue-lazyload.esm.js?caf9:1013
  | (anonymous) | @ | vue-lazyload.esm.js?caf9:1547
  | update | @ | vue-lazyload.esm.js?caf9:1546
  | LazyContainer | @ | vue-lazyload.esm.js?caf9:1531
  | bind | @ | vue-lazyload.esm.js?caf9:1486
  | callHook$1 | @ | vue.runtime.esm.js?2b0e:6289
  | _update | @ | vue.runtime.esm.js?2b0e:6211
  | updateDirectives | @ | vue.runtime.esm.js?2b0e:6192
  | invokeCreateHooks | @ | vue.runtime.esm.js?2b0e:5694
  | createElm | @ | vue.runtime.esm.js?2b0e:5582
  | patch | @ | vue.runtime.esm.js?2b0e:6087
  | Vue._update | @ | vue.runtime.esm.js?2b0e:2656
  | updateComponent | @ | vue.runtime.esm.js?2b0e:2784
  | get | @ | vue.runtime.esm.js?2b0e:3138
  | Watcher | @ | vue.runtime.esm.js?2b0e:3127
  | mountComponent | @ | vue.runtime.esm.js?2b0e:2791
  | Vue.$mount | @ | vue.runtime.esm.js?2b0e:7995
  | init | @ | vue.runtime.esm.js?2b0e:4133
  | createComponent | @ | vue.runtime.esm.js?2b0e:5604
  | createElm | @ | vue.runtime.esm.js?2b0e:5551
  | patch | @ | vue.runtime.esm.js?2b0e:6126
  | Vue._update | @ | vue.runtime.esm.js?2b0e:2656
  | updateComponent | @ | vue.runtime.esm.js?2b0e:2784
  | get | @ | vue.runtime.esm.js?2b0e:3138
  | Watcher | @ | vue.runtime.esm.js?2b0e:3127
  | mountComponent | @ | vue.runtime.esm.js?2b0e:2791
  | Vue.$mount | @ | vue.runtime.esm.js?2b0e:7995
  | (anonymous) | @ | main.js?56d7:63
var loadImageAsync = function loadImageAsync(item, resolve, reject) {
  var image = new Image();
  image.src = item.src;

  image.onload = function () {
    resolve({
      naturalHeight: image.naturalHeight,
      naturalWidth: image.naturalWidth,
      src: image.src
    });
  };

  image.onerror = function (e) {
    reject(e);
  };
};