Как предварительно выбрать изображение, используя встроенный механизм Vue

У меня есть приложение с 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';
        }
      })
    ]
  }
}

Это только удается испортить окончательный index.html, оставив его без скриптов и стилей сборки внутри.

Если я уберу эту строку:

      new HtmlWebpackPlugin(),

Сайт по-прежнему загружается, но изображения не загружаются заранее. Это так же, как если бы я никогда ничего не делал в файле vue.config.js.

Как мне правильно его настроить?


Редактировать: В компонентах Vue я использую require() для загрузки изображений, то есть они проходят через Webpack. Например:

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

Изменить: мне удалось предварительно выбрать изображения, как Рой 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>

Однако это не ответ на мой настоящий вопрос - он не использует подсказки ресурсов через теги <link>. Это также требует больше усилий, и я считаю, что это плохая практика.

Ответ 1

Поскольку плагин уже включен в VueJS, я думаю, что вы должны изменить его с помощью chainWebpack.

В соответствии с документацией к плагину предварительной загрузки веб-пакета, вы также должны установить опцию включения в значение "allAssets".

В Webpack очень распространено использование загрузчиков, таких как загрузчик файлов, для создания ресурсов для определенных типов, таких как шрифты или изображения. Если вы также хотите предварительно загрузить эти файлы, вы можете использовать include со значением 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
        })
    }
}

Со свежей установкой Vue-cli я получил следующий HTML

<!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> <title>vue-preload-images</title>
    <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><strong>We're sorry but vue-preload-images doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript>
    <div id=app></div>
    <script src=/js/chunk-vendors.3d4cd4b5.js> </script> <script src=/js/app.30d3ed79.js> </script> </body> </html>

Я надеюсь, что это будет работать для вас.

Ответ 2

Решение 1.

Когда пользователь нажимает кнопку, вы визуализируете свое изображение в невидимом состоянии.

При load изображения вы выполняете переход плавно.

Если загрузка изображения, как правило, занимает более 2 секунд, рассмотреть возможность предоставления пользователю визуальную подсказку кнопку нажмите записанную и прочее вот - вот произойдет.

Это было бы технически правильным решением.


Решение 2.

Альтернатива, широко используемая в производственных средах (и не имеющая никакого отношения к Vue per se), заключается в загрузке миниатюр изображений на странице (например, в 10 раз меньше, размер которых в ~ 100 раз меньше, т.е.). Это может быть неочевидно, но они очень хорошо заменяют большие, хотя переход еще продолжается - вы также можете поэкспериментировать с CSS-фильтром blur.

Миниатюра и большое изображение должны быть полностью перекрыты в одном и том же переходном родительском элементе, а большой - снизу. При событии load большой версии, уменьшите изображение, вызывая эффект фокусировки: едва заметный эффект.
Довольно забавным преимуществом этого метода является то, что, если вы оставляете большие пальцы сверху (с opacity: 0), всякий раз, когда кто-то пытается загрузить изображение, он щелкает правой кнопкой мыши по большому пальцу и не понимает, почему он загружает его с такой низкой скоростью. Рез.

Все почти одинаково (с точки зрения анимации) с добавлением эффекта фокусировки на изображение, когда оно действительно загружается.

Не СУХОЙ, но эффективный. Выглядит профессионально, кажется, что все загружается мгновенно и гладко. В целом, он преобразует гораздо больше, чем другие "правильные" решения. Именно поэтому он часто используется на веб - сайтах, где производительность страницы важна.


Когда имеешь дело с визуальными эффектами, быть идеальным - это выглядеть идеально (и в UX чувствовать/казаться идеальным).
Древние греки согнули свои колонны, чтобы они смотрели прямо, если смотреть снизу.