tencent.jquery.pix.component 1.0.91-beta1 → 1.0.91-beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/change.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # 更新日志
2
2
 
3
+ ### 1.0.91-beta2
4
+
5
+ - list组件优化滚动事件处理和DOM引用缓存,提升性能
6
+
3
7
  ### 1.0.91-beta1
4
8
 
5
9
  - 瀑布流组件V2版本的滑动流畅度升级
@@ -55,13 +55,25 @@ List.prototype.init = function () {
55
55
  </div>
56
56
  `);
57
57
 
58
- // 绑定滚动事件(节流处理)
58
+ // 【优化】缓存 DOM 引用,避免每次滚动都执行 jQuery 查询
59
+ this.$container = $container;
60
+ this.$scrollWrapper = $container.find('.virtual-list-scroll');
61
+ this.$viewport = $container.find('.virtual-list-viewport');
62
+ // 【优化】缓存容器高度,固定高度容器无需每次重新计算(避免触发 reflow)
63
+ this._viewportHeight = $container.height();
64
+
65
+ // 【优化】绑定滚动事件(真正的 rAF 节流:一帧内只执行一次 updateVisibleItems)
66
+ this._rafPending = false;
59
67
  $container.off().on('scroll', function () {
60
68
  self.scrollTop = $(this).scrollTop();
61
69
 
62
- window.requestAnimationFrame(() => {
63
- self.updateVisibleItems();
64
- });
70
+ if (!self._rafPending) {
71
+ self._rafPending = true;
72
+ window.requestAnimationFrame(() => {
73
+ self._rafPending = false;
74
+ self.updateVisibleItems();
75
+ });
76
+ }
65
77
 
66
78
  if (options.onscroll && options.onscroll.constructor === Function) {
67
79
  options.onscroll(this, self.scrollTop);
@@ -78,12 +90,12 @@ List.prototype.init = function () {
78
90
  List.prototype.updateVisibleItems = function (force = false) {
79
91
  const self = this;
80
92
  const options = this.options;
81
- const $container = $(options.container);
82
93
 
83
94
  let startIndex = 0; // 起始索引
84
95
  let endIndex = 0; // 结束索引
85
96
 
86
- const viewportHeight = $container.height();
97
+ // 【优化】使用缓存的容器高度,避免每次滚动触发布局计算
98
+ const viewportHeight = this._viewportHeight;
87
99
  // 计算当前可见项范围(含缓冲区)
88
100
  startIndex = Math.max(0, Math.floor(self.scrollTop / options.itemHeight) - options.buffer);
89
101
  endIndex = Math.min(
@@ -91,8 +103,8 @@ List.prototype.updateVisibleItems = function (force = false) {
91
103
  Math.ceil((self.scrollTop + viewportHeight) / options.itemHeight) + options.buffer
92
104
  );
93
105
 
94
- // 生成当前可见项的 DOM
95
- const $viewport = $container.find('.virtual-list-viewport');
106
+ // 【优化】使用缓存的 $viewport 引用
107
+ const $viewport = this.$viewport;
96
108
 
97
109
  /**方案1 */
98
110
  const newActiveNodes = new Map();
@@ -128,7 +140,8 @@ List.prototype.updateVisibleItems = function (force = false) {
128
140
  );
129
141
  $viewport.append($node);
130
142
  } else {
131
- $node = $(this.nodePool.pop())
143
+ // 【优化】nodePool 中已经是 jQuery 对象,无需再次 $() 包装
144
+ $node = this.nodePool.pop();
132
145
  $node.css('transform', `translateY(${top}px)`).attr('data-index', i);
133
146
  self.updateRenderUI($node, options.data[i], i);
134
147
  }
@@ -142,67 +155,15 @@ List.prototype.updateVisibleItems = function (force = false) {
142
155
  this.nodePool.push($node);
143
156
  });
144
157
  this.activeNodes = newActiveNodes;
145
-
146
- /**方案2 */
147
- // const $existingChildren = $viewport.children(); // 获取现有 DOM 元素集合
148
- // const usedIndices = new Set(); // 记录当前需要保留的索引
149
-
150
- // // 步骤 1:更新或保留现有元素
151
- // if ($existingChildren.length > 0) {
152
- // for (let j = 0; j < $existingChildren.length; j++) {
153
- // const $el = $($existingChildren[j]);
154
- // const oldIndex = parseInt($el.data('data-index'));
155
- // if (oldIndex >= startIndex && oldIndex <= endIndex) {
156
- // // 仍在可视范围内 → 更新位置和内容
157
- // const newTop = oldIndex * options.itemHeight;
158
- // $el.css('top', `${newTop}px`);
159
- // usedIndices.add(oldIndex);
160
- // } else {
161
- // // 移出可视范围 → 从 DOM 中删除
162
- // $el.remove();
163
- // }
164
- // }
165
- // }
166
-
167
- // // 步骤 2:补充新增元素
168
- // for (let i = startIndex; i <= endIndex; i++) {
169
- // if (!usedIndices.has(i)) {
170
- // // 需要新增的元素
171
- // const top = i * options.itemHeight;
172
- // const $element = $(
173
- // `<div class="virtual-item"
174
- // style="position: absolute; top: ${top}px; height: ${options.itemHeight}px"
175
- // data-index="${i}">
176
- // ${options.renderItem(options.data[i], i)}
177
- // </div>`
178
- // );
179
- // // 插入到正确位置(按索引顺序)
180
- // let inserted = false;
181
- // for (let j = 0; j < $existingChildren.length; j++) {
182
- // const $el = $($existingChildren[j]);
183
- // const currentIndex = parseInt($el.data('data-index'));
184
- // if (currentIndex > i) {
185
- // $element.insertBefore($el);
186
- // inserted = true;
187
- // break;
188
- // }
189
- // }
190
-
191
- // if (!inserted) {
192
- // $viewport.append($element);
193
- // }
194
- // }
195
- // }
196
-
197
158
  }
198
159
 
199
160
  // 外部更新数据方法
200
161
  List.prototype.updateData = function (newData) {
201
162
  const options = this.options;
202
163
  options.data = newData;
203
- const totalHeight = options.data.length * options.itemHeight
204
- // 重新计算高度
205
- $(this.options.container).children().height(`${totalHeight}px`);
164
+ const totalHeight = options.data.length * options.itemHeight;
165
+ // 【优化】使用缓存的 DOM 引用,避免重新创建 jQuery 对象
166
+ this.$scrollWrapper.height(`${totalHeight}px`);
206
167
  this.updateVisibleItems(true); // 强制更新渲染
207
168
  };
208
169
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tencent.jquery.pix.component",
3
- "version": "1.0.91-beta1",
3
+ "version": "1.0.91-beta2",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "files": [