如何使用Vue的内置机制预取图像

Hri*_*dov 14 javascript vue.js vuejs2 vue-cli

我有一个使用Vue CLI的应用程序.当应用加载时,我有一堆图像,当用户点击按钮时会出现转换.问题在于,当用户单击按钮时,相应的图像才开始加载,这意味着大部分动画在此之前完成.这使得体验非常不稳定,因为图像在过渡期间突然弹出,取代了其他元素.我想在网站加载时预取它们.

这个答案建议使用该Image课程.但是,根据Vue CLI文档,Vue内部使用自己的插件preload-webpack-plugin,显然可以配置它.

我尝试配置它以便预加载图像:

vue.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin');

module.exports = {
  configureWebpack: {
    plugins: [
      new HtmlWebpackPlugin(),
      new PreloadWebpackPlugin({
        rel: 'prefetch',
        as (entry) {
          if (/\.css$/.test(entry)) return 'style';
          if (/\.woff$/.test(entry)) return 'font';
          if (/\.png$/.test(entry)) return 'image';
          return 'script';
        }
      })
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

这只会搞砸最后一个index.html,留下它没有内置的构建脚本和样式.

如果我删除此行:

      new HtmlWebpackPlugin(),
Run Code Online (Sandbox Code Playgroud)

该网站仍然加载但图像不是预取的.这就像我从未在vue.config.js文件中做过任何事情一样.

如何正确设置?


编辑:在Vue组件中,我require()用来加载图像,这意味着它们通过Webpack.例如:

<img :src="require('../assets/img/' + img)" draggable="false">
Run Code Online (Sandbox Code Playgroud)

编辑:我能够像Roy J在评论中建议的那样预取图像:

PreloadImages.vue 在我的主要组成部分:

<template>
  <div style="display: none;">
    <img :src="require('../assets/img/foo.png')">
    <img :src="require('../assets/img/bar.png')">
    <img :src="require('../assets/img/baz.png')">
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)

但是,这不是我实际问题的答案 - 它不会通过<link>标签使用资源提示.它还需要更多的努力,我相信这是一个不好的做法.

lbi*_*eau 5

由于该插件已包含在 VueJS 中,我认为您必须使用chainWebpack对其进行修改。

根据预加载 webpack 插件文档,您还应该将include选项设置为“allAssets”值。

在 Webpack 中使用文件加载器等加载器来生成特定类型的资源(例如字体或图像)是很常见的。如果您也希望预加载这些文件,您可以使用包含值 allAssets

所以配置将是这样的:

// vue.config.js
module.exports = {
    chainWebpack: config => {
        config.plugin('preload').tap(options => {
            options[0].as = (entry) => {
                if (/\.css$/.test(entry)) return 'style';
                if (/\.woff$/.test(entry)) return 'font';
                if (/\.png$/.test(entry)) return 'image';
                return 'script';
              }
            options[0].include = 'allAssets'
            // options[0].fileWhitelist: [/\.files/, /\.to/, /\.include/]
            // options[0].fileBlacklist: [/\.files/, /\.to/, /\.exclude/]
            return options
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

通过全新的 Vue-cli 安装,我生成了以下 HTML

// vue.config.js
module.exports = {
    chainWebpack: config => {
        config.plugin('preload').tap(options => {
            options[0].as = (entry) => {
                if (/\.css$/.test(entry)) return 'style';
                if (/\.woff$/.test(entry)) return 'font';
                if (/\.png$/.test(entry)) return 'image';
                return 'script';
              }
            options[0].include = 'allAssets'
            // options[0].fileWhitelist: [/\.files/, /\.to/, /\.include/]
            // options[0].fileBlacklist: [/\.files/, /\.to/, /\.exclude/]
            return options
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望它对你有用。


And*_*hiu 1

解决方案1。

当用户单击按钮时,您将图像呈现为不可见状态。

在图像load事件中,您可以顺利地执行转换。

如果图像的加载通常需要超过 2 秒,请考虑向用户提供视觉线索:按钮单击已被记录并且事情即将发生。

这将是技术上正确的解决方案。


解决方案2

另一种在生产环境中广泛使用的替代方案(与 Vue 本身无关)是在页面中加载图像的缩略图(例如小 10 倍 - 大小约小 100 倍,是区域) )。这可能并不明显,但它们是大型过滤器的非常好的替代品,而过渡正在进行中 - 您可能还想在它们上尝试使用 CSSblur过滤器。

缩略图和大图像必须在同一个过渡父级中完美重叠,大图像位于下方。如果load是大版本,则淡出缩略图,从而产生聚焦效果:微妙的引人注目。
这种方法的一个相当有趣的好处是,如果您将拇指放在顶部(带有opacity: 0),那么每当有人尝试下载图像时,他们都会右键单击拇指,并且很难理解为什么他们要以如此低的分辨率下载图像。

一切都几乎相同(就动画而言),只是在实际加载时在图像上添加了焦点效果。

不干燥,但高效。看起来很专业,一切似乎都可以立即顺利加载。总的来说,它比其他“正确”的解决方案转换得更多。这就是为什么它通常用于页面性能重要的网站。


在处理视觉效果时,完美就是看起来完美(在用户体验中,就是感觉/看起来完美)。
古希腊人弯曲了他们的柱子,这样从下面看时它们看起来是笔直的。