关于javascript:如何使用Vue的内置机制预取图像

How to prefetch an image using Vue's built-in mechanism

我有一个使用Vue CLI的应用程序。应用加载后,当用户单击按钮时,会出现一堆带有过渡效果的图像。问题在于,当用户单击按钮时,相应的图像才开始加载,这意味着直到那时为止,大多数动画都已完成。这使体验变得非常不稳定,因为在过渡期间图像突然弹出,从而取代了其他元素。我想在网站加载时预取它们。

此答案建议使用Image类。但是,根据Vue CLI文档,Vue内部使用了自己的插件preload-webpack-plugin,显然可以对其进行配置。

我尝试对其进行配置,以使其预加载图像:

vue.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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';
        }
      })
    ]
  }
}

这只能设法弄乱最终的index.html,使其内部没有构建脚本和样式。

如果我删除此行:

1
      new HtmlWebpackPlugin(),

该站点仍在加载,但未预取图像。就像我从未在vue.config.js文件中什么都没做一样。

如何正确设置?

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

1
<img :src="require('../assets/img/' + img)" draggable="false">

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

PreloadImages.vue在我的主要组件中:

1
2
3
4
5
6
7
<template>
 
    <img :src="require('../assets/img/foo.png')">
    <img :src="require('../assets/img/bar.png')">
    <img :src="require('../assets/img/baz.png')">
 
</template>

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


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

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

It is very common in Webpack to use loaders such as file-loader to
generate assets for specific types, such as fonts or images. If you
wish to preload these files as well, you can use include with value
allAssets

因此配置将如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 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
        })
    }
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang=en>

<head>
    <meta charset=utf-8>
    <meta http-equiv=X-UA-Compatible content="IE=edge">
    <meta name=viewport content="width=device-width,initial-scale=1">
    <link rel=icon href=/favicon.ico> vue-preload-images
    <link href=/css/app.0b9b292a.css rel=preload as=style>
    <!-- Here is the logo image -->
    <link href=/img/logo.82b9c7a5.png rel=preload as=image>
    <link href=/js/app.30d3ed79.js rel=preload as=script>
    <link href=/js/chunk-vendors.3d4cd4b5.js rel=preload as=script>
    <link href=/css/app.0b9b292a.css rel=stylesheet>
</head>

<body><noscript>We're sorry but vue-preload-images doesn't work properly without JavaScript enabled. Please enable it to continue.</noscript>
   
    <script src=/js/chunk-vendors.3d4cd4b5.js>  <script src=/js/app.30d3ed79.js>  </body> </html>

我希望它对您有用。


解决方案1.

当用户单击按钮时,将以不可见的状态渲染图像。

在图像的load事件上,您可以顺利执行过渡。

如果加载图像通常需要2秒钟以上的时间,请考虑为用户提供直观的线索,记录下单击按钮的行为,并且事情即将发生。

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

解决方案2.

在生产环境中广泛使用的替代方法(与Vue本身无关)是在页面中加载图像的缩略图(缩小10倍-缩小约100倍) ,是区域)。可能并不明显,但是当过渡正在进行时,它们可以很好地替代大型-您可能还想对它们使用CSS blur过滤器进行试验。

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

所有内容(就动画而言)几乎相同,但在实际加载时在图像上增加了聚焦效果。

不是DRY,而是有效的。看起来很专业,一切似乎都能立即流畅地加载。总体而言,与其他"正确"解决方案相比,它的转换方式更多。这就是为什么它通常在网页性能很重要的网站上使用的原因。

在处理视觉效果时,完美就是看起来完美(在UX中,感觉/看起来很完美)。
古希腊人弯曲他们的柱子,所以从下面看时它们看上去很直。