긴 요소 목록에서 작은 변경 하나에 대해 렌더링 시간을 단축할 수 있는 방법이 있습니까?
아래에 링크되어 있는 예시는 div의 그리드(1,000 x 20)의 매우 큰 목록을 나타내고 있으며, 하나의 div를 클릭하면 해당 요소만 강조 표시됩니다.단, VueJs의 리렌더링에 따른 오버헤드가 큰 것 같습니다.클릭 시 지연이 발생합니다.
<div class="row" v-for="row in rows">
<div v-for="column in row.columns" :class="{red: isHighlighted(row,column)}" @click.prevent="setHighlighted({row: row.id, column: column.id})">
<div>Value: {{column['value']}}</div>
</div>
</div>
물론 모든 업데이트에 대해 평가가 필요한 작업을 수행하지 않음으로써 속도를 높일 수 있습니다.고객님의 경우class
설정은 매번 모든 상자에 대해 함수를 호출해야 합니다.row
또는column
변화들.
추가했습니다.style
컬럼의 구성원으로서 강조 표시 시 각 셀이 변화를 알아차릴 것을 요구하는 대신 직접 찾을 수 있도록highlighted
하지만 그래도 지연은 해소되지 않았습니다.
이 일을 잠시 연구한 후, 나는 추측하건데:class
함수 호출이 아니더라도 업데이트 때마다 설정이 다시 확인되었습니다.이전의 솔루션에서는 클래스 설정을 명시적으로 처리했기 때문에:class
문제. 이 솔루션은 셀마다 컴포넌트를 사용하므로 컴포넌트는 자신의 소품이 변경될 때만 재평가되므로 재계산을 피할 수 있습니다.
const store = new Vuex.Store({
state: {
rows: [],
rowCount: 2000,
highlighted: {
row: null,
column: null
}
},
getters: {
rows(state) {
return state.rows;
},
rowCount(state) {
return state.rowCount;
},
highlighted(state) {
return state.highlighted;
}
},
mutations: {
setRows(state, rows) {
state.rows = rows;
},
setHighlighted(state, highlighted) {
state.highlighted = highlighted;
}
}
});
new Vue({
el: "#app",
store,
data() {
return {
highlightedEntry: null,
highlightedEl: null
};
},
created() {
this.setRows(
Array.from(Array(this.rowCount).keys()).map(i => {
return {
id: i,
columns: Array.from(Array(parseInt(20)).keys()).map(j => {
return {
id: j,
value: Math.random().toPrecision(4),
isHighlighted: false
};
})
};
})
);
},
computed: {
...Vuex.mapGetters(["rows", "rowCount", "highlighted"])
},
components: {
aCell: {
props: ['rowId', 'column'],
template: '<div :class="{red: column.isHighlighted}" @click="highlight">Value: {{column.value}}</div>',
computed: {
style() {
return this.column.style;
}
},
methods: {
highlight() {
this.$emit('highlight', this.rowId, this.column);
}
}
}
},
methods: {
...Vuex.mapMutations(["setRows", "setHighlighted"]),
highlight(rowId, column) {
if (this.highlightedEntry) {
this.highlightedEntry.isHighlighted = false;
}
this.highlightedEntry = column;
column.isHighlighted = true;
this.setHighlighted({
row: rowId,
column: column.id
});
}
}
});
.row {
display: flex;
justify-content: space-between;
}
.row>* {
border: 1px solid black;
}
.red {
background-color: red;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.js"></script>
<div id="app">
<div>
Cells: {{rowCount * 20}}
</div>
<div class="row" v-for="row in rows" :key="row.id">
<div v-for="column in row.columns">
<a-cell :row-id="row.id" :column="column" @highlight="highlight"></a-cell>
</div>
</div>
</div>
각 항목이 다음과 같은 고유한 속성을 갖는 경우id
, 그것을 에 전달합니다.:key="item.id"
:
<div v-for="column in row.columns" :key="column.id" ...
Vue는 v-for로 렌더링된 요소 목록을 업데이트할 때 기본적으로 "임플레이스 패치" 전략을 사용합니다.데이터 항목의 순서가 변경된 경우 항목의 순서와 일치하도록 DOM 요소를 이동하는 대신 Vue는 각 요소에 패치를 적용하여 특정 인덱스에서 렌더링해야 하는 내용을 반영하도록 합니다.이는 Vue 1.x의 track-by="$index" 동작과 유사합니다.
이 기본 모드는 효율적이지만 목록 렌더 출력이 하위 구성요소 상태 또는 임시 DOM 상태(예: 양식 입력 값)에 의존하지 않는 경우에만 적합합니다.
Vue가 각 노드의 ID를 추적하여 기존 요소를 재사용하고 재정렬할 수 있도록 힌트를 제공하려면 각 항목에 고유한 키 특성을 제공해야 합니다.키의 이상적인 값은 각 항목의 고유 ID입니다.이 특수 특성은 1.x의 추적 기준과 대략 동일하지만 특성처럼 작동하므로 v-bind를 사용하여 동적 값에 바인딩해야 합니다(여기 줄임말 사용).
<div v-for="item in items" :key="item.id">
<!-- content -->
</div>
반복되는 DOM 컨텐츠가 단순하거나 성능 향상을 위해 기본 동작을 의도적으로 사용하는 경우가 아니라면 가능하면 v-for와 함께 키를 제공하는 것이 좋습니다.
Vue는 노드를 식별하는 일반적인 메커니즘이기 때문에 이 키는 v-for와 특별히 연결되지 않은 다른 용도로도 사용됩니다(가이드 뒷부분 참조).
언급URL : https://stackoverflow.com/questions/49438530/is-there-any-way-to-speed-up-rendering-time-for-one-small-change-in-a-long-list
'programing' 카테고리의 다른 글
vue-multicelect에 대한 쓰기 단위 테스트 (0) | 2022.06.22 |
---|---|
ArrayList에 값이 있는지 확인합니다. (0) | 2022.06.22 |
Vue는 vue 1에서 vue 2로의 이행을 필터링합니다. (0) | 2022.06.22 |
Vue Js 단락이 -> OK로 표시되지만 체크박스가 작동하지 않음 (0) | 2022.06.22 |
vue.js 2 앱에서 커스텀 데코레이터를 글로벌하게 사용하려면 어떻게 해야 합니까? (0) | 2022.06.22 |