Search code examples
google-chromevue.jshtml-datalist

Performance problems with Chrome and Datalist in Vue.js


I have a performance problem with datalist in vue.js with Google Chrome (latest version : 83.0.4103.97). I have to say i started to learn Vue.js few month ago so i m still a noob. With Firefox everything is ok, the datalist and filtering works instantly. With Chrome everything is slow... I type in the input field, the letters appear very slowly (or all at once) and i have to wait a lot of seconds for the filter applies. After this i have to click multiple times on the element to fill the field. Here are videos of both browsers behavior and parts of my code.

Firefox : https://streamable.com/vj4rbb

Chrome : https://streamable.com/2sikq5

Component code :

<b-input-group size="sm" v-if="menuEditState">
  <b-form-input
    :list="`mealDish${meal.id}`"
    :id="`input${meal.id}`"
    placeholder="Selectionner un plat"
    v-model="name"
    :class="{'is-invalid': $v.name.$anyError}"
  />
  <datalist :id="`mealDish${meal.id}`">
    <option v-for="dish in activeDishesByType" :value="`${dish.name} (${dish.humanType})`" :data-value="dish.id"></option>
  </datalist>
  
  <b-input-group-append>
    <b-button variant="primary" @click="onClick" :disabled="loading">
      <i :class="loading ? 'fa fa-spin fa-circle-notch' : 'fa fa-plus'" />
    </b-button>
  </b-input-group-append>
</b-input-group>

And script

  computed: {
...mapGetters({
  activeDishesByType: 'activeDishesByType',
}),

The getter is based on a Vuex state sort in a getter (I have the same behavior if i use the state without the getter sorting).

I know there is a performance monitor in chrome dev tools and i try to find something which could help me fixing this but i dont know where to search in all theses informations.

Thanks for your help.

Romain.


Solution

  • Ok so i finally find what element was causing so much performances issues in Chrome. Its the value in the datalist options... So i managed to use only data-* and text in the datalist. Please dont hesitate to improve this or add comments.

    No more "value" on the data-list :

     <b-input-group size="sm">
      <b-form-input
        :list="`mealDish${meal.id}`"
        :id="`input${meal.id}`"
        placeholder="Selectionner un plat"
        v-model="name"
      />
      <datalist :id="`mealDish${meal.id}`">
        <option v-for="dish in activeDishesByType" :data-value="dish.id">{{
          `${dish.name} (${dish.humanType})`
        }}</option>
      </datalist>
      
      <b-input-group-append>
        <b-button variant="primary" @click="onClick" :disabled="loading">
          <i :class="loading ? 'fa fa-spin fa-circle-notch' : 'fa fa-plus'" />
        </b-button>
      </b-input-group-append>
    </b-input-group>
    

    And the search in the datalist options for bringing back my data-value :

      // Get the selected/typed value
      const shownVal = document.getElementById(`input${this.meal.id}`).value;
      const datalist = document.querySelector(`#mealDish${this.meal.id}`);
      // Find the option in the list and get the data-value (id)
      let dishId = null;
      for (var i = 0; i < datalist.options.length; i++) {
        if (datalist.options[i].text === shownVal) {
          dishId = datalist.options[i].dataset.value;
          break;
        }
      }