第三十四课:动态内容与渲染性能
学习目标
在本课中,你将学习:
- 如何动态更新页面元素的内容。
- 理解浏览器的重绘(Repaint)和回流(Reflow)。
- 学习基本的性能优化策略,以提高页面的渲染性能。
学习内容
1. 动态更新元素的内容
在Web开发中,经常需要根据用户的交互或其他事件动态地更新页面内容。textContent
和innerHTML
是实现这一目标的两个常用属性。
textContent
提供了获取或设置元素内所有子节点的文本内容的方式。
代码示例:
<div id="greeting">你好,世界!</div>
<script>
var greetingDiv = document.getElementById('greeting');
// 获取文本内容
console.log(greetingDiv.textContent); // 输出:"你好,世界!"
// 设置文本内容
greetingDiv.textContent = '你好,宇宙!';
</script>
innerHTML
则可以获取或设置元素内的HTML内容。
代码示例:
<div id="content">原始内容</div>
<script>
var contentDiv = document.getElementById('content');
// 获取HTML内容
console.log(contentDiv.innerHTML); // 输出:"原始内容"
// 设置HTML内容
contentDiv.innerHTML = '<strong>更新后的内容</strong>';
</script>
2. 重绘(Repaint)和回流(Reflow)
- 重绘: 当元素的样式改变,但没有改变布局时,浏览器会重绘该元素。
- 回流: 当元素的尺寸或位置改变,浏览器需要重新计算元素的几何属性,这通常会导致回流。回流比重绘成本更高。
重要概念:
- 回流必定会发生重绘,重绘不一定会引起回流。
- 浏览器会尽量批量处理重绘和回流操作,但某些操作会强制立即执行,如访问
offsetWidth
。
3. 性能优化策略
- 使用CSS样式类:尽可能通过切换元素的类来改变样式,而不是直接操作样式属性。
- 批量DOM操作:使用
DocumentFragment
或者离线DOM结构进行批量操作,然后一次性将其添加到文档中。 - 减少回流:减少对导致回流的属性的访问,合并多次DOM和样式修改。
代码示例:
// 性能不佳的回流示例
var list = document.getElementById('myList');
for (var i = 0; i < 10; i++) {
var li = document.createElement('li');
li.textContent = 'Item ' + (i + 1);
list.appendChild(li);
// 每次循环都可能引起回流
}
// 性能优化后的代码
var fragment = document.createDocumentFragment();
for (var i = 0; i < 10; i++) {
var li = document.createElement('li');
li.textContent = 'Item ' + (i + 1);
fragment.appendChild(li);
}
list.appendChild(fragment); // 一次性回流
课后练习
- 创建一个简单的待办事项列表,并实现一个功能,允许用户输入待办事项,点击按钮后,将其动态添加到列表中。
- 尝试优化该功能,确保动态添加待办事项时,页面的渲染性能尽可能高效。
练习解析:
练习1:
<input type="text" id="todoInput" placeholder="添加待办事项">
<button id="addTodoBtn">添加</button>
<ul id="todoList"></ul>
<script>
document.getElementById('addTodoBtn').addEventListener('click', function() {
var input = document.getElementById('todoInput');
var newTodo = input.value.trim();
if (newTodo) {
var li = document.createElement('li');
li.textContent = newTodo;
document.getElementById('todoList').appendChild(li);
input.value = ''; // 清空输入框
}
});
</script>
练习2 (性能优化版):
<!-- 前面的HTML代码保持不变 -->
<script>
document.getElementById('addTodoBtn').addEventListener('click', function() {
var input = document.getElementById('todoInput');
var newTodo = input.value.trim();
if (newTodo) {
var fragment = document.createDocumentFragment();
var li = document.createElement('li');
li.textContent = newTodo;
fragment.appendChild(li);
document.getElementById('todoList').appendChild(fragment);
input.value = ''; // 清空输入框
}
});
</script>
通过这些练习,你将能够理解如何动态更新内容以及如何提升渲染性能,这对于创建流畅的用户体验至关重要。