面试题答案
一键面试优化动画性能
- 使用
requestAnimationFrame
:在Svelte中,可以利用生命周期函数onMount
来注册动画更新函数,通过requestAnimationFrame
控制动画帧,减少不必要的重绘。<script> let cardHeight = 100; let isExpanded = false; function expandCard() { isExpanded = true; function updateHeight() { if (isExpanded) { cardHeight += 10; if (cardHeight < 200) { requestAnimationFrame(updateHeight); } } } requestAnimationFrame(updateHeight); } function collapseCard() { isExpanded = false; function updateHeight() { if (!isExpanded) { cardHeight -= 10; if (cardHeight > 100) { requestAnimationFrame(updateHeight); } } } requestAnimationFrame(updateHeight); } </script> <div style="height: {cardHeight}px" on:mouseenter={expandCard} on:mouseleave={collapseCard}> <!-- Card content --> </div>
- 硬件加速:通过
will-change
属性提示浏览器提前准备动画,利用GPU加速。<style> .card { will-change: transform; } </style> <div class="card" style="transform: {isExpanded? 'scale(1.1)' : 'scale(1)'}"> <!-- Card content --> </div>
优化事件交互性能
- 事件委托:对于列表中的多个卡片,可以将点击事件委托到父元素上,减少事件处理器的数量。
<script> const cards = [ { id: 1, content: 'Card 1' }, { id: 2, content: 'Card 2' } ]; function handleClick(event) { const cardId = event.target.dataset.cardId; // 根据cardId执行不同逻辑 } </script> <div on:click={handleClick}> {#each cards as card} <div data-card-id={card.id}> {card.content} </div> {/each} </div>
- 防抖与节流:对于频繁触发的事件,如窗口滚动或鼠标移动,可以使用防抖或节流来限制事件触发频率。
- 防抖:在Svelte中可以通过
setTimeout
实现防抖。
<script> let debounceTimer; function handleScroll() { clearTimeout(debounceTimer); debounceTimer = setTimeout(() => { // 执行滚动相关逻辑 }, 300); } </script> <div bind:this={window} on:scroll={handleScroll}> <!-- Page content --> </div>
- 节流:可以通过记录上次触发时间来实现节流。
<script> let lastTriggerTime = 0; const throttleInterval = 300; function handleScroll() { const now = new Date().getTime(); if (now - lastTriggerTime >= throttleInterval) { lastTriggerTime = now; // 执行滚动相关逻辑 } } </script> <div bind:this={window} on:scroll={handleScroll}> <!-- Page content --> </div>
- 防抖:在Svelte中可以通过
减少内存占用
- 及时清理:在组件销毁时,清理定时器、事件监听器等。
<script> let intervalId; onMount(() => { intervalId = setInterval(() => { // 执行定时任务 }, 1000); }); onDestroy(() => { clearInterval(intervalId); }); </script>
- 复用对象:避免在频繁触发的函数中创建新对象。例如,在动画更新函数中,尽量复用已有的变量和对象,而不是每次都创建新的。
<script> let position = { x: 0, y: 0 }; function updatePosition() { // 复用position对象更新位置 position.x += 10; position.y += 10; } </script>