web-dev-qa-db-fra.com

Construire du HTML profondément imbriqué avec vue-cli prend une éternité

J'ai constaté que le processus de construction de vue-cli (2.9.6, mais 3.0.0 beta * a le même problème) prend une éternité une fois que le code html du modèle est devenu relativement profond.

Par exemple, je viens d'ajouter quelques divs à App.vue qui sont pré-inclus:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div><div><div><div></div></div></div></div>
    <HelloWorld/>
  </div>
</template>

qui ne prend pas si longtemps.

Mais une fois que ça devient ça:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>
    <HelloWorld/>
  </div>
</template>

alors le processus de construction prend une éternité et je crois que le nid de cette profondeur n’est pas si rare.

Comment dois-je régler ce problème?

EDIT (Détails)

Il semble que le problème puisse être spécifique à l'environnement, voici donc les détails.

Ce problème peut être reproduit avec ces environnements au moins:

  • macOS High Sierra sur Mac mini (fin 2014)
  • Ubuntu 18.04 sur Dell XPS 13

et les versions node et npm sont:

node --version
# prints
v8.9.4
# and
npm version
# prints
{ npm: '6.1.0',
  ares: '1.10.1-DEV',
  cldr: '31.0.1',
  http_parser: '2.7.0',
  icu: '59.1',
  modules: '57',
  nghttp2: '1.25.0',
  node: '8.9.4',
  openssl: '1.0.2n',
  tz: '2017b',
  unicode: '9.0',
  uv: '1.15.0',
  v8: '6.1.534.50',
  zlib: '1.2.11' }

Avec ceux-ci, j'ai refait les essais suivants sur mon Mac:

npm uninstall -g vue-cli
npm install -g vue-cli
vue init webpack divnest
# then some Enter keys - everything is default
cd divnest

Ensuite, ouvrez App.vue et mettez plusieurs divs:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>
    <router-view/>
  </div>
</template>

(Depuis que j'ai utilisé les paramètres par défaut ici, <router-view/> est inclus contrairement au message original, mais ne devrait pas être le problème.)

Et enfin,

npm run dev

ce qui prend une éternité - spécifiquement, le processus s’arrête à ce point

 13% building modules 28/31 modules 3 active ...myname/Documents/divnest/src/App.vue

Dans le cas de

npm run build

, le processus s’arrête à ce stade:

> [email protected] build /Users/myname/Documents/divnest
> node build/build.js

Hash: 483ebabc54d5aed79fd7
Version: webpack 3.12.0
Time: 13742ms
                                                  Asset       Size  Chunks             Chunk Names
               static/js/vendor.7fed9fa7b7ba482410b7.js     112 kB       0  [emitted]  vendor
                  static/js/app.f1ebca7a6e0ec0b7ebdf.js      12 kB       1  [emitted]  app
             static/js/manifest.2ae2e69a05c33dfc65f8.js  857 bytes       2  [emitted]  manifest
    static/css/app.30790115300ab27614ce176899523b62.css  432 bytes       1  [emitted]  app
static/css/app.30790115300ab27614ce176899523b62.css.map  828 bytes          [emitted]  
           static/js/vendor.7fed9fa7b7ba482410b7.js.map     553 kB       0  [emitted]  vendor
              static/js/app.f1ebca7a6e0ec0b7ebdf.js.map    23.3 kB       1  [emitted]  app
         static/js/manifest.2ae2e69a05c33dfc65f8.js.map    4.97 kB       2  [emitted]  manifest
                                             index.html  509 bytes          [emitted]  

  Build complete.

  Tip: built files are meant to be served over an HTTP server.
  Opening index.html over file:// won't work.

 94% asset optimization 

et si je le laisse faire, ça prend ... 1155409ms !!!!

 DONE  Compiled successfully in 1155409ms                                                        13:35:34

 I  Your application is running here: http://localhost:8080

PLUS D'EDIT

Comme @ tony19 l'a fait remarquer, le plus probable est le suspect. Suivant les conseils, j'ai essayé quelques modèles avec Ubuntu 18.04 (pas Mac car Mac n’est pas là actuellement, désolé) et mes résultats sont les suivants:

  • vue-cli 2.9.6 + npm run dev - pendre
  • vue-cli 2.9.6 + npm run build - 6 sec (C'est tellement déroutant. Quel était le million de secondes ci-dessus!? Peut-être que réinstaller Vue-cli doit le changement?)
  • vue-cli 3.0.0-beta16 + vue serve - bloquer (contrairement au rapport de @ tony19)
  • vue-cli 3.0.0-beta16 + vue build - 5 secondes

ENCORE PLUS EDIT

Donc, il semble que cela soit définitivement causé par plus joli . https://github.com/prettier/prettier/issues/1250 Est le problème original qui a résolu ce problème et l'équipe de développement a pensé que https://github.com/prettier/prettier/pull/2259 l'a corrigé, mais le fait est qu'il ne pouvait pas gérer mon cas, comme le montre @ tony19 sur https: // github. com/prettier/prettier/issues/4672 . Tant pis.

"SOLUTION"

J'ai fini par faire ceci - suite au rapport de @ tony19, en changeant /node_modules/vue-loader/lib/template-compiler/index.js lignes 78:81

if (!isProduction) {
  code = prettier.format(code, { semi: false })
}

à

// if (!isProduction) {
//   code = prettier.format(code, { semi: false })
// }

ainsi le problème est résolu. Merci frontend, merci.

11
akai

Je peux reproduire le problème de performances comme vous l'avez décrit (macOS High Sierra 10.13.4, nœud 8.9.4 et 9.11.1). Le problème se produit également avec un projet vue-cli 3.x nouvellement créé.

Le blocage se produit réellement dans prettier, appelé depuis le compilateur de modèles de vue-loader . Les <div>s imbriqués sont convertis en JavaScript par vue-loader, et cela devient l'extrait suivant:

var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{"id":"app"}},[_c('img',{attrs:{"src":require("./assets/logo.png")}}),_vm._v(" "),_c('router-view'),_vm._v(" "),_vm._m(0)],1)}
var staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div')])])])])])])])])])])])])])])])])])])])])])])])])}]

vue-loader passe cette longue chaîne à prettier, ce qui prend environ 159 secondes à traiter. La cause du bogue est les appels de fonction profondément imbriqués qui créent les divs J'ai signalé ce bogue dans prettier ( Issue 4672 ).

En attendant, je vous recommande de refactoriser votre code HTML pour éviter une imbrication profonde. Si vous devez vous en tenir à l'ancien modèle, vous pouvez résoudre le problème en créant en mode de production, car vue-loader ignore prettier pour les versions de production:

NODE_ENV=production npm run dev
12
tony19

Je n'ai pas de problème particulier avec vos 25 <div> imbriqués: (exemple ci-dessous avec le compilateur runtime Vue, afin que vous puissiez facilement le tester directement dans votre navigateur)

new Vue({
  el: '#app',
  template: '#app-template',
});
#app div {
  border: 1px solid grey;
  padding: 1px;
}
<script src="https://unpkg.com/vue@2"></script>

<div id="app">
</div>

<template id="app-template">
<div id="app">
  <div>
    <div>
      <div>
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>
                      <div>
                        <div>
                          <div>
                            <div>
                              <div>
                                <div>
                                  <div>
                                    <div>
                                      <div>
                                        <div>
                                          <div>
                                            <div>
                                              <div>
                                                <div>
                                                  <div>25 nested <code>&lt;div&gt;</code>'s</div>
                                                </div>
                                              </div>
                                            </div>
                                          </div>
                                        </div>
                                      </div>
                                    </div>
                                  </div>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  </div>
</template>

Voici une démonstration avec un projet Vue CLI sur CodeSandbox, probablement plus proche de votre exemple: https://codesandbox.io/s/v3knpl447l

(c.-à-d. qu'il précompile les modèles, le processus de construction a donc lieu sur le serveur CodeSandbox)

0
ghybs

J'ai eu des problèmes similaires avec vue-cli 3.1.1 (TypeScript + SCSS) et Bootstrap (qui nécessite par défaut une imbrication). Exemple de structure:

<template>
    <div class="container">
        <div class="row">
            <div class="col-12">
                <div class="card-deck">
                    <div class="card">
                        <div class="card-body">
                            <div class="accordion">
                                <div class="card">
                                    <div class="card-header">
                                        ...
                                    </div>
                                    <div class="collapse">
                                        <div class="card-body">
                                            <div class="row">
                                                <div class="col-12 form-group">
                                                    <label>...</label>
                                                    <div class="dropdown">
                                                        <button class="custom-select" type="button" data-toggle="dropdown">{{someValue}}</button>
                                                        <div class="dropdown-menu">
                                                            <a class="dropdown-item" href="#" :data-key="somekey1" @click="onClickMethod">value1</a>
                                                            <a class="dropdown-item" href="#" :data-key="somekey2" @click="onClickMethod">value2</a>
                                                            ...

besoin de ~ 12 secondes pour compiler plus de 400 lignes de code (template + TypeScript + SCSS). Après avoir enlevé:

:data-key="somekey1" @click="onClickMethod"
:data-key="somekey2" @click="onClickMethod"

le code avait besoin de 5-6 secondes pour compiler. Après avoir déplacé le code vers le composant personnalisé (et du code TypeScript du composant Vue vers le fichier Helper.ts):

<template>
    <div class="container">
        <div class="row">
            <div class="col-12">
                <div class="card-deck">
                    <div class="card">
                        <div class="card-body">
                            <div class="accordion">
                                <div class="card">
                                    <div class="card-header">
                                        ...
                                    </div>
                                    <div class="collapse">
                                        <div class="card-body">
                                            <SubComponent/>

il faut environ 700 ms pour compiler (un composant principal et deux sous-composants supplémentaires, chaque fichier ayant moins de 100 lignes de code + Helper.ts ayant exactement 97 lignes de code).

Donc si vous souffrez de mauvaises performances npm run serve, essayez d’abord les sous-composants, je n’ai pas remarqué beaucoup de différence dans le temps de compilation en appelant npm run build, donc je suppose (peut-être à tort) que ce problème est également causé par le prettificateur de code activé pour serve mais désactivé pour build (TSLint n'est pas appelé lors d'une action de sauvegarde, il n'affecte donc pas npm run serve dans mon cas).

0
dominik