programing

Vue 사후 대응형 콘텐츠를 신속하게 업데이트하려면 어떻게 해야 합니까?

firstcheck 2022. 7. 23. 11:27
반응형

Vue 사후 대응형 콘텐츠를 신속하게 업데이트하려면 어떻게 해야 합니까?

Vue가 반응성 콘텐츠 업데이트 속도가 느리다는 문제가 있습니다.

사용자가 목록에서 항목을 선택했으면 합니다.항목을 선택하면 해당 항목이 표시되어야 합니다.테스트를 위해 선택한 항목 주위에 테두리를 설정하기만 하면 됩니다.문제는 여러 항목이 있는 경우 선택한 항목에 대한 클래스를 업데이트(갱신)하는 데 Vue가 매우 오래 걸린다는 것입니다.

즉, 다음과 같은 단순 반응형 저장소가 있습니다.

export default new Vuex.Store({
  state: {
    selections: []
  },
  mutations: {
    set_selections (state, sel) {
      state.selections = sel;
    }
  }
})

저는 이 스토어를 컴포넌트에 전달하고, 컴포넌트는 많은 아이템을 포함하는 간단한 목록을 작성합니다.

<p v-for="item in items">
    <span v-bind:class="{ 'is-selected': isSelected(item) }" v-on:click="onSelect(item)">
        {{ item.name }}
    </span>
</p>

따라서 각 항목에는 Vuex 스토어 상태에서 추가/삭제하는 고유 ID가 있습니다.선택사항은 다음과 같습니다.

onSelect: function(item, event){
    let itemId = item._id;
    let sel = this.selections;
    if (sel.indexOf(itemId) !== -1) {
        var index = sel.indexOf(itemId);
        sel.splice(index, 1);
    } else {
        sel.push(itemId);
    }
    this.$store.commit("set_selections", sel);
},

어디에,

selections: function() {
    return this.$store.state.selections;
}

는 현재 선택 항목을 가져오는 계산 속성입니다.

항목이 선택되었는지 확인하고 "is-selected" 클래스를 DOM 요소에 추가하는 방법은 다음과 같습니다.

isSelected: function(item){
    let itemId = item._id;
    let sel = this.selections;
    if (sel.indexOf(itemId) !== -1) {
        return true;
    }
    return false;
},

문제 목록에 항목이 많으면 반응하는 내용이 매우 느립니다.클릭을 하면 500밀리초에서 1초 정도 걸립니다.(여러 가지 아이템이 있습니다)혹시 제가 뭘 잘못하고 있는 건 아닐까요?를 사용하여 루프하기 때문에v-for는 Vue를 다시 해야 한다는 것을 있습니다.isSelected시간이 걸릴 수 있는 모든 항목에 대한 방법을 제공합니다.

물론 onClick 이벤트에서 직접 클래스를 추가/삭제할 수 있지만 Vue 사용의 모든 포인트를 놓치게 됩니다.이 문제에 어떻게 대처하시겠습니까?

수천 개의 컴포넌트/아이템에서 이 작업을 수행하면 선택 어레이를 반복하는 데 비용이 많이 들기 때문에 목록 업데이트가 느릴 수 있습니다.

, 되어 있습니다.key바인딩은 속도도 향상시킬 수 있습니다(속도 차이는 테스트되지 않음).

그러나 내 데모에서 가장 좋은 결과는 선택 객체를 만들고 그냥 속성을 확인한 후입니다.selected.

이렇게 하는 게 것 같아요.selected계산 속성으로 확인합니다. 더 빠릅니다.

계산된 속성의 경우 1000개 항목 목록이 있는 항목을 선택하는 데 약 200ms가 소요됩니다.선택 방법으로는 최대 450ms가 소요됩니다.왜 그렇게 느린지 정확히 알 수 없습니다.

이벤트 59 - / RAM /입니다.스크린샷 200ms

지금으로서는 이게 가장 빠른 버전이에요.선택 내용을 표시하기 위해 0.5초에서 1초까지 시작하였습니다.

아래나 이 바이올린을 봐주세요.

const listItem = {
	props: ['item'],
	template: `
  	<li :class="{ 'is-selected': selected }" @click="$emit('selected', item)">
        {{ item.name }}
    </li>
  `,
  computed: {
  	...Vuex.mapState(['selections']),
    selected () {
    	// 200ms time to mark item for click with 1000 list items - clicked Test 326
    	return this.selections[this.item.id] !== undefined; // object property check is fast
    }
  },
  methods: {
  	selected () {
    	// 450ms to mark selection
    	//console.log('selected', this.selections, !!this.selections[this.item.id]);
      // slightly slower than computed property
    	return this.selections[this.item.id] !== undefined; // object property check is fast
    	// array --> slow because another iteration for each component required
    	//this.selections.indexOf(this.item) !== -1
    }
  }
};

const list = {
	props: ['items'],
	template: `
  	<ul>
    	<list-item 
      	v-for="item in items" 
        :item="item" 
        @selected="select"
        :key="item.id"></list-item>
  	</ul>
  `,
  components: {
  	listItem
  },
  methods: {
  	select(item) {
    	this.$store.commit('set_selection', item)
    }
  }
};

const store = new Vuex.Store({
	state: {
    selections: []
  },
  mutations: {
    set_selection (state, item) {
      //state.selections = sel;
      console.log('clicked', item, state.selections[item.id]);
      
      if (state.selections[item.id]) {
      	// in object --> remove from selection
      	//let  {[item.id]: deleted, ...newState} = state;
        state.selections[item.id] = undefined;
      }
      else {
      	// not in object --> add item
      	state.selections = {
        	...state.selections,
        	[item.id]: item
        }
      }
      // console.log(state.selections, !!state.selections[item.id]);
      
      /*
      --> array approach is slow
      if (state.selections.indexOf(item) === -1) 
      {
      	// not in list --> push to list
      	state.selections.push(item);
      }
      else {
      	// in list --> remove selection
      	state.selections.pop(item);
      }*/
    }
  }
})

function createItems(count) {
	let items = [];
  for(let i=0; i< count; i++) {
  	items.push({
    	id: i,
      name: 'Test ' + i
    });
  }
  return items;
}

new Vue({
	el: '#app',
  store,
  data () {
  	let items = createItems(1000);
  	return {
    	items
    };
  },
  components: {
  	list
  }
})
.is-selected {
   background-color: red;
   border: 1px solid red;
}

ul {
  list-style-type: none;
}
li {
  cursor: pointer;
}

li:hover {
  border: 1px solid gray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.js"></script>
<div id="app">
  <list :items="items"></list>
</div>

언급URL : https://stackoverflow.com/questions/45038822/how-to-make-vue-reactive-content-update-quickly

반응형