我跟éšthis article使用了垂直å¯æ»‘动å¼å¡ç‰‡æ»‘å—。
这个问题分为两个部分。
1。我ä¸æ˜Žç™½åœ¨å‘下滑动时如何å转滑å—çš„æ–¹å‘?
以下是相关的密ç 笔-https://codepen.io/bmarcelino/pen/vRYPXV
æ›´æ–°å¡çš„相关功能
function updateUi() {
requestAnimationFrame(function(){
elTrans = 0;
var elZindex = 5;
var elScale = 1;
var elOpac = 1;
var elTransTop = items;
var elTransInc = elementsMargin;
for(i = currentPosition; i < (currentPosition + items); i++){
if(listElNodesObj[i]){
listElNodesObj[i].classList.add('stackedcards-bottom', 'stackedcards--animatable', 'stackedcards-origin-bottom');
listElNodesObj[i].style.transform ='scale(' + elScale + ') translateX(0) translateY(' + (elTrans - elTransInc) + 'px) translateZ(0)';
listElNodesObj[i].style.webkitTransform ='scale(' + elScale + ') translateX(0) translateY(' + (elTrans - elTransInc) + 'px) translateZ(0)';
listElNodesObj[i].style.opacity = elOpac;
listElNodesObj[i].style.display = 'block';
listElNodesObj[i].style.zIndex = elZindex;
elScale = elScale - 0.04;
elOpac = elOpac - (1 / items);
elZindex--;
}
}
});
};
我ä¸å¤ªç²¾é€šJava。
截至目å‰ï¼Œæ»‘å—在å‘åŽæ»‘动时åªèƒ½å‘一个方å‘移动-å‘å‰ç§»åŠ¨ã€‚我想了解å‘滑å—æ·»åŠ åŽé€€è¿åŠ¨çš„实现。
2。关于性能
æ¤å¤–,requestAnimationFrame
确实有助于在滑动时æä¾›æµç•…的体验。但是,在DOMä¸åº”è¯¥æœ‰å¤šå°‘å¼ å¡æœ‰é™åˆ¶ï¼Ÿæˆ‘将调用APIæœåŠ¡æ¥èŽ·å–å†…å®¹ï¼Œå› ä¸ºå®ƒå°†è¿”å›žåª’ä½“ï¼Œå› æ¤å°†opacity设置为0会以任何方å¼å‡å°‘内å˜ä½¿ç”¨å—?
ä½œè€…è®¤ä¸ºåˆ é™¤DOM会迫使æµè§ˆå™¨é‡æ–°ç»˜åˆ¶ï¼Œè¿™ä¼šä¸¥é‡å½±å“性能å—?但是,该虚拟列表ä¸æ˜¯å—?在这ç§æƒ…况下,性能/æˆæœ¬æ¯”是多少?
ç”案 0 :(得分:1)
è¿™ä¸ä¼šæ˜¯ä¸€ä¸ªå®Œæ•´çš„ç”案,但是由于没有其他人åšå‡ºå›žåº”,我将为您回ç”问题的第1部分æ供帮助。请注æ„,这åªæ˜¯ä¸€ä¸ªç¤ºä¾‹ï¼Œå¯ä»¥å¸®åŠ©æ‚¨äº†è§£å¦‚何使å¡å‘åŽé€€è€Œä¸æ˜¯å¯ç”¨äºŽç”Ÿäº§çš„解决方案。
è¦é‡æ–°è¿žæŽ¥â€œé¡¶éƒ¨â€æŒ‰é’®ä»¥å‘åŽç§»åŠ¨ï¼Œæ‚¨åªéœ€è¦è¿›è¡Œä»¥ä¸‹æ›´æ”¹ï¼š
onSwipeTop()
ä¸ï¼Œå°†currentPosition = currentPosition + 1;
更改为currentPosition = currentPosition - 1;
onSwipeTop()
ä¸å°†transformUi(0, -1000, 0, topObj);
更改为transformUi(0, 0, 0, topObj);
。这会éšè—å¡ç‰‡ä¸Šå‡åŠ¨ç”»ã€‚updateUi()
ä¸å°†i < (currentPosition + items)
更改为i <= (currentPosition + items)
。这修å¤äº†ä¸‰ä¸ªå¡ä¸åªæœ‰ä¸¤ä¸ªè¢«æ›´æ–°çš„错误。现在å°è¯•å‡ 次å•å‡»â€œå‘å·¦â€æˆ–“å³â€ï¼Œç„¶åŽå•å‡»â€œé¡¶éƒ¨â€ä¸¤æ¬¡ã€‚æ¯æ¬¡å•å‡»â€œé¡¶éƒ¨â€ï¼Œæ‚¨åº”è¯¥ä¼šçœ‹åˆ°ä¸€å¼ å¡ç‰‡å›žæ¥ã€‚
大概您想将新按钮设置为“底部â€ï¼Œè€Œä¸æ˜¯é‡æ–°å¸ƒçº¿â€œé¡¶éƒ¨â€ï¼Œå¹¶ä¸”您å¯èƒ½è¿˜å¸Œæœ›é™åˆ¶å¯¹currentPosition
çš„æ›´æ”¹ï¼Œå› æ¤æ‚¨ä¸èƒ½è¶…越第一个/最åŽä¸€å¼ å¡ï¼Œä½†è¿™è‡³å°‘应该å¯ä»¥å¸®åŠ©æ‚¨å…¥é—¨ã€‚
我希望这会有所帮助。
ç”案 1 :(得分:1)
以下内容是有关脚本工作方å¼çš„éžå¸¸ç®€çŸçš„解释,包括有关建议使脚本å转方å‘和“å–消刷å¡â€çš„建议。åå‘方法的çµæ„Ÿæ¥è‡ªRocky的出色回ç”-ä»–ç†åº”得到这个想法的充分肯定。
æ–‡æ¡£åŠ è½½åŽï¼Œè„šæœ¬å°†èŽ·å¾—所有å¯ç”¨å¡çš„列表。在您的示例ä¸ï¼Œå¡ç‰‡æ˜¯DOMä¸çš„硬编ç å…ƒç´ ï¼Œå¡ç‰‡åˆ—表listElNodesObj
æ˜¯è¿™äº›å…ƒç´ çš„åˆ—è¡¨ã€‚è¦è®°ä½è¿™ä¸€ç‚¹å¾ˆé‡è¦ï¼šå¡ç‰‡ä¸æ˜¯æŠ½è±¡çš„ï¼Œå®ƒä»¬ä»Žæ ¹æœ¬ä¸Šè®²æ˜¯é¡µé¢ä¸çš„å…ƒç´ ã€‚å½“æ‚¨å‘å¡ä¸æ·»åŠ 媒体和数æ®æ—¶ï¼Œå¿…é¡»å°†å…¶é™„åŠ åˆ°DOMä¸çš„å…ƒç´ ä¸Šï¼ˆä¾‹å¦‚ï¼Œå…·æœ‰æ•°æ®å±žæ€§ï¼‰ã€‚
该脚本获å–å为currentPosition
的当å‰å¡ç´¢å¼•ï¼›é¦–先,这是头牌。然åŽï¼Œå®ƒæ˜¾ç¤ºå½“å‰å¡åŠå…¶åŽçš„ä¸¤å¼ å¡ï¼ˆcurrentPosition + 1
å’ŒcurrentPosition + 2
)。
在输入时,该å¡å…·æœ‰é€‚当的动画效果,å¯ä»¥ä»Žå·¦ä¾§ï¼Œå³ä¾§æˆ–顶部飞出。当å‰çš„å¡ç´¢å¼•å°†å¢žåŠ 1,å†å¢žåŠ 1è¿›å…¥å †æ ˆã€‚æ˜¾ç¤ºæ–°çš„å½“å‰å¡åŠå…¶åŽçš„ä¸¤å¼ å¡ã€‚
ç›®å‰ï¼Œæ‰€æœ‰åŠ¨ä½œ-å‘左,å‘å³å’Œå‘上滑动-å…¨éƒ¨è¿›å…¥å †æ ˆã€‚è¦å转方å‘,您需è¦ä¾¦å¬æ–°åŠ¨ä½œï¼ˆæˆ–é‡æ–°ä½¿ç”¨å½“å‰åŠ¨ä½œï¼Œä¾‹å¦‚滑动顶部),并且在该动作上,当å‰å¡ç´¢å¼•ä¼šå‡å°‘1ã€‚æ·»åŠ å°äºŽé›¶çš„æ ¡éªŒã€‚ currentPosition = Math.max( 0, currentPosition - 1 );
Rocky回ç”了一个出色的解决方案。
现在,æ¤å®žçŽ°ä»ŽDOMä¸å·²ç»å˜åœ¨çš„所有å¡å¼€å§‹ã€‚您似乎想从åŽç«¯APIæ›´æ–°å¡å †æ ˆã€‚为æ¤ï¼Œæ‚¨éœ€è¦ä¸€ç§åœ¨åˆ·å¡æ—¶ä»Žä¸€ç«¯å¼¹å‡ºå¡å¹¶åœ¨å¦ä¸€ç«¯æ·»åŠ æ–°å¡çš„方法。如上所述,您的å¡ç‰‡åˆ—表与DOMç´§å¯†ç›¸å…³ï¼Œå› æ¤æ‚¨éœ€è¦å¯¹å…¶è¿›è¡ŒæŠ½è±¡ä¸€äº›ä»¥å®žçŽ°æ¤ç›®çš„。创建一个从APIå¡«å……çš„å…ƒç´ åˆ—è¡¨ï¼Œå¹¶ç”¨å®ƒå¡«å……åˆå§‹æ–‡æ¡£ï¼ˆè€Œä¸æ˜¯ç›¸åï¼‰ã€‚æ»‘åŠ¨æ—¶ï¼Œæ— è®ºå‘å‰è¿˜æ˜¯å‘åŽï¼Œè¯·ä»ŽåŽé€€ç«¯å¼¹å‡ºä¸€ä¸ªå…ƒç´ ,然åŽå°†ä»ŽAPIå¡«å……çš„æ–°å…ƒç´ æ·»åŠ åˆ°å‰è¿›ç«¯ã€‚有趣的是,列表大å°å’Œå½“å‰ä½ç½®å°†å§‹ç»ˆä¿æŒä¸å˜ã€‚
如果您当å‰çš„ä½ç½®å§‹ç»ˆæ˜¯æœ€é¡¶å±‚å¡ç‰‡çš„åŽé€€ä½ç½®ï¼Œå¹¶ä¸”å †æ ˆä¸çš„最åŽä¸€å¼ å¡ç‰‡æ¯”最åŽä¸€å¼ å¯è§çš„å¡ç‰‡å¤šä¸€ä¸ªï¼Œåˆ™æ‚¨å°†å§‹ç»ˆæœ‰ä¸€å¼ å¡ç‰‡å¯ä»¥è¿›è¡ŒåŠ¨ç”»æ˜¾ç¤ºã€‚
æ¤å¤„的术è¯ç¨ä½œæ¾„清:更改类似opacity
的内容会导致é‡æ–°ç»˜åˆ¶ï¼Œä»ŽDOMä¸åˆ é™¤å…ƒç´ ï¼ˆæ— è®ºæ˜¯è½¯åˆ é™¤è¿˜æ˜¯ç¡¬åˆ é™¤ï¼‰éƒ½ä¼šå¯¼è‡´é‡æŽ’。é‡ç»˜æ˜¯æ˜‚è´µçš„ï¼Œå› ä¸ºæµè§ˆå™¨å¿…须检查DOMä¸æ¯ä¸ªå…ƒç´ çš„å¯è§æ€§ã€‚由于必须é‡æ–°è®¡ç®—å¸ƒå±€ï¼Œå› æ¤å›žæµç„Šç”šè‡³æ›´åŠ 昂贵。å‚è§What's the difference between reflow and repaint?
有两ç§æ–¹æ³•å¯ä»¥é™åˆ¶DOMä¸çš„å¡æ•°ã€‚您å¯ä»¥è®¾ç½®display: none
,将其ä¿ç•™åœ¨å†…å˜å’ŒDOMä¸ï¼Œä½†é˜»æ¢æµè§ˆå™¨åœ¨é‡æŽ’或é‡æ–°ç»˜åˆ¶æ—¶è€ƒè™‘它。或者,您å¯ä»¥ä½¿ç”¨parent.appendChild(child)
æ·»åŠ å¡ï¼Œå¹¶ä½¿ç”¨parent.removeChild(child)
åˆ é™¤å¡ï¼Œä»¥ç¡®ä¿JavaScriptåœ¨åˆ é™¤åŽå°±ä¸å˜åœ¨å¯¹è¯¥å…ƒç´ 的引用,并且一旦垃圾收集器è¿è¡Œï¼Œè¯¥åˆ é™¤çš„å…ƒç´ å°†è¢«ç‰©ç†åœ°ä»Žå†…å˜ä¸åˆ 除。两者都会触å‘回æµã€‚带有opacity: 0
çš„å…ƒç´ å°†å®Œå…¨ä¿ç•™åœ¨DOMä¸ï¼Œä»¥è¿›è¡Œé‡æŽ’å’Œé‡ç»˜ã€‚
关于什么能æ供最佳性能:更改ä¸é€æ˜Žåº¦æˆ–从内å˜ä¸åˆ 除,这实际上å–决于您的实现。我å¯ä»¥ç»™ä½ 一些相关的指示。
内å˜é™åˆ¶â€œ 在DOMä¸åº”有多少å¡æœ‰é™åˆ¶ï¼Ÿâ€ç»å¯¹å¯ä»¥ï¼Œä½†è¿™å–决于您的数æ®ã€‚如果您的å¡æ€»æ•°å¾ˆå°‘,则确实å¯ä»¥ä¸€å¼€å§‹å°±å…¨éƒ¨åŠ 载,并用opacity: 0
或display: none
éšè—刷过的å¡ã€‚甚至å¯ä»¥æ”¹å–„动画的æµåŠ¨æ€§ï¼ˆè¯·å‚è§ä¸‹é¢æœ‰å…³åŠ¨ç”»å—计算的è¦ç‚¹ï¼‰ã€‚纯粹由于更高的内å˜ä½¿ç”¨è€Œå¯¼è‡´çš„æ€§èƒ½å·®å¼‚å‡ ä¹Žè‚¯å®šä¸ä¼šå¼•èµ·æ³¨æ„ï¼Œå› ä¸ºçŽ°ä»£æµè§ˆå™¨å…·æœ‰å¤§é‡å†…å˜ï¼Œå¹¶ä¸”会在需è¦é¡µé¢æ–‡ä»¶æˆ–交æ¢ä¹‹å‰å°†è„šæœ¬åœæ¢è¿è¡Œã€‚如果您确实会在内å˜ä¸æ‹¥æœ‰å¦‚æ¤å·¨å¤§çš„DOM以至于性能会明显下é™ï¼Œé‚£ä¹ˆæ‚¨çš„内容下载时间将是一个更大的问题。
然而,更é‡è¦çš„是,您æ£ç¡®åœ°é—®åˆ°åˆ é™¤æˆ–æ·»åŠ å…ƒç´ æ˜¯å¦æ˜¯è™šæ‹Ÿåˆ—表的全部内容。如果您永远ä¸ä¼šå†è®¿é—®å…ƒç´ ,为什么还è¦ä¿ç•™ä¸€ä¸ªå…ƒç´ 在内å˜ä¸ï¼Œæˆ–è€…ä¸ºä»€ä¹ˆåŠ è½½ä¸€ä¸ªè¿œè¿œè¶…å‡ºåˆ—è¡¨å¯èƒ½æ°¸è¿œæ— æ³•åˆ°è¾¾çš„å…ƒç´ ã€‚å®žé™…ä¸Šï¼Œæ‚¨å£°æ˜Žæ‚¨å°†è¦é€šè¿‡APIè®¿é—®å†…å®¹ï¼Œè¿™å¼ºçƒˆæš—ç¤ºæ‚¨å°†ä¸€æ¬¡è®¿é—®ä¸€å¼ å¡ä¸Šçš„内容。ç‰åˆ°æ‚¨æ‹¥æœ‰APIä¸çš„所有内容åŽï¼Œå¯èƒ½è¦èŠ±è´¹å¾ˆé•¿æ—¶é—´ã€‚您似乎已ç»çŸ¥é“,仅访问填写固定大å°åˆ—表所需的å¡ä¼šæ供更好的体验。 (如果è¦å转滑å—çš„æ–¹å‘,则应在内å˜ä¸è‡³å°‘ä¿ç•™ä¸€å¼ 已刷å¡ï¼Œè¿™æ ·åœ¨å‘åŽåˆ·å¡æ—¶ï¼Œæ‚¨ä¸ä¼šåœ¨ç‰å¾…下载内容时通过暂åœæˆ–å‘é€ç©ºå¡æ¥ç ´å动画)< / p>
动画阻æ¢è®¡ç®—,除了下载时间以外,display: none
å’Œopacity: 0
对于刷å¡æˆ–在列表ä¸è·ç¦»å¤ªè¿œçš„å¡çš„真æ£æ€§èƒ½ä¼˜åŠ¿åœ¨äºŽå®ƒä»¬çš„内容在DOMä¸å·²ç»å˜åœ¨ã€‚ (并且如上所述,opacity: 0
还有一个优点:它ä¸ä¼šè§¦å‘é‡æŽ’)。通过比较,从物ç†ä¸Šåœ¨DOMä¸æ·»åŠ å’Œåˆ é™¤å…ƒç´ éœ€è¦é¢å¤–的计算,å³åœ¨DOMæ ‘ä¸æ’å…¥æˆ–åˆ é™¤å¡èŠ‚点åŠå…¶æ‰€æœ‰å代。如果这是åŒæ¥å®Œæˆçš„,那么您将进行动画阻æ¢è®¡ç®—,从而在DOMæ ‘æ›´æ–°å®Œæˆä¹‹å‰æ‰èƒ½è¿›è¡Œæ»‘动动画。
但是,让我们ä¿æŒé€è§†ã€‚首先,从DOMæ ‘ä¸æ·»åŠ å’Œåˆ é™¤èŠ‚ç‚¹é€šå¸¸éžå¸¸å¿«ã€‚事实è¯æ˜Žï¼ŒinnerHTMLåœ¨æ·»åŠ åˆ°DOM时速度ç¨å¿«ï¼Œä½†æ˜¯åœ¨åˆ é™¤æ—¶åˆ™æ…¢å¾—å¤šï¼Œå› æ¤è¯·è°¨æ…Žé€‰æ‹©æ¯’è¯ã€‚但是,除éžæ‚¨è¦å‘å¡ä¸æ·»åŠ æ•°å或数百åƒå—节的数æ®ï¼Œå¦åˆ™æ“作将likely take less than a millisecond。其次,您声明将从APIä¸æ£€ç´¢åˆ—表的内容,这æ„味ç€å¼‚æ¥è¿žæŽ¥ã€‚å¦‚æžœåœ¨æž„é€ å¼‚æ¥å‡½æ•°æ—¶è¦å°å¿ƒï¼Œåˆ™å°†å†…å®¹æ·»åŠ åˆ°DOM的函数ä¸ä¸€å®šä¼šå¹²æ‰°åŠ¨ç”»ã€‚ (这并ä¸æ„味ç€JavaScript是多线程的;它是å•çº¿ç¨‹çš„,但结构良好的异æ¥ä»£ç æ„味ç€å‡½æ•°æ‰§è¡Œçš„顺åºæ— 关紧è¦ï¼‰ã€‚如果在没有将动画排入队列的情况下完æˆäº†æ·»åŠ 或移除的å¡ç‰‡çš„æ“作,则对性能的影å“都将å˜æˆshorter and less perceivable。
最åŽï¼Œæ¯ä¸ªDOMæ“ä½œéƒ½æ˜¯ä¸€ä¸ªæ–°çš„æ¸²æŸ“æ›´æ–°ï¼Œå› æ¤æ‚¨å¸Œæœ›è¿›è¡Œå°½å¯èƒ½å°‘çš„æ“ä½œã€‚å› æ¤ï¼Œæ‚¨å°†åœ¨å†…å˜ä¸åˆ›å»ºå½¼æ¤ç›¸å¯¹çš„å…ƒç´ ï¼Œå¹¶ä¸”ä»…åœ¨æœ€åŽå°†æœ€é«˜å…ƒç´ æ’å…¥DOM。å‚è§Fastest DOM insertion。如果您å¯ä»¥åœ¨è¯¥å¡ä¸åŒ…å«æ‰€æœ‰å¡æ•°æ®ï¼Œåˆ™æ¯æ¬¡æ»‘动仅需è¦ä¸¤æ¬¡DOMæ“作。这å–决于å¡æ‰€åŒ…å«çš„媒体,但是å¯ä»¥æƒ³è±¡ï¼Œæœ€å的情况是,将å¡æ·»åŠ å’Œç§»é™¤åˆ°å †æ ˆä¸çš„总时间仅需数å毫秒。
GPU 大多数渲染引擎都å¯ä»¥è®¿é—®GPU,该GPU在涉åŠå¤§é‡åƒç´ 的绘图和åˆæˆæ“作ä¸å¯ä»¥æ¯”CPU效率更高。默认情况下,渲染层ä¸ä½¿ç”¨GPU渲染。页é¢GPU Accelerated Compositing in Chrome指出,
 Â从ç†è®ºä¸Šè®²ï¼Œæ¯ä¸ªå•ç‹¬çš„RenderLayer都å¯ä»¥å°†å…¶è‡ªèº«ç»˜åˆ¶åˆ°å•ç‹¬çš„背衬表é¢ä¸ï¼ˆå³GPUå¯è®¿é—®çš„åˆæˆå±‚],实际上这å¯èƒ½åœ¨å†…å˜ï¼ˆå°¤å…¶æ˜¯VRAM)方é¢éžå¸¸æµªè´¹ã€‚
为确ä¿ä½¿ç”¨GPU渲染ä¸é€æ˜Žåº¦å˜åŒ–之类的动画,您需è¦ä»¥éšå¼åˆæˆçš„æ–¹å¼è®¿é—®è¯¥åŠ¨ç”»ã€‚上é¢çš„页é¢æ供了如何执行æ¤æ“作的完整列表,但实际上,您将使用CSS动画æ¥æ›´æ”¹ä¸é€æ˜Žåº¦ï¼Œä»Žè€Œæ示æµè§ˆå™¨å°†å…ƒç´ æå‡ä¸ºåˆæˆå±‚。您æ供的当å‰ä»£ç 使用JavaScriptæ›´æ–°æ¯ä¸ªåŠ¨ç”»å¸§çš„ä¸é€æ˜Žåº¦ï¼Œå› æ¤ä¸é€æ˜Žåº¦æ›´æ”¹ä¸æ˜¯éšå¼åˆæˆçš„候选对象。 (您似乎对è¿åŠ¨åŠ¨ç”»ä½¿ç”¨äº†3Då˜æ¢ï¼Œè¯¥å˜æ¢è§¦å‘了éšå¼åˆæˆï¼Œå› æ¤å¯èƒ½å·²ç»å¯¹GPU进行了优化)。更改代ç 以使用CSS动画并ä¸æ˜¯ä¸€ä»¶å®¹æ˜“的事,但是很å¯èƒ½ä¼šæ高性能,特别是动画过程ä¸çš„帧频。当然,需è¦é’ˆå¯¹ç‰¹å®šâ€‹â€‹æƒ…况进行基准测试,以验è¯è¿™ä¸€ç‚¹ï¼Œæœ‰å…³https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/çš„æŸäº›GPU动画为何è¿è¡Œé€Ÿåº¦è¾ƒæ…¢çš„讨论,请å‚è§{{3}}。
总而言之,由于从虚拟列表ä¸åŠ¨æ€æ·»åŠ å’Œåˆ é™¤å…ƒç´ è€Œå¯¼è‡´çš„æ€§èƒ½æ高,虽然å¯èƒ½æ¯”å®Œå…¨åŠ è½½æ•´ä¸ªåˆ—è¡¨ç•¥é«˜ï¼Œä½†æ¯æ¬¡æ»‘动å¯èƒ½ä»…å¤šäº†å‡ æ¯«ç§’ã€‚ä½¿ç”¨å¼‚æ¥å®žçŽ°æ—¶ï¼ŒåŠ¨ç”»æœŸé—´çš„帧频ä¸åº”更改。通常,这很容易让æ¥ï¼Œå› 为å¯èƒ½ä¼šèŠ‚çœå¤§é‡çš„åˆå§‹ä¸‹è½½æ—¶é—´ï¼Œä½†å¿…须与特定实现的其他细节一起考虑。