前端性能优化与调试技巧 | 青训营笔记

118 阅读4分钟

前端代码性能优化是提升用户体验、降低资源消耗以及提高网站或应用整体效率的关键环节。以下将从多个方面深入探讨前端代码性能优化的相关内容:

浏览器渲染流程:

在解决如何优化前端页面性能之前需要先了解浏览器是如何对页面进行渲染的。浏览器的渲染流程大致分为以下几个步骤:

  1. 解析HTML:使用html解析器将html页面转换为浏览器能够识别的DOM树。
  2. 解析CSS:使用预解析线程将CSS解析为CSSOM树,样式节点与DOM树一一对应。
  3. 构建渲染树:将DOM树和CSSOM树结合,生成渲染树。
  4. 布局(重排或回流):计算渲染树中每个元素的几何位置。
  5. 绘制(重绘):将渲染树的内容绘制到屏幕上,为节点添加背景颜色,一个个的绘制图层。

可以在浏览器的调试者工具中查看页面的渲染流程,在“性能”模块中点击左上角的录制进行当前页面渲染流程的录制,对于每个资源的请求和页面的渲染流程都有很详细的显示。

image.png

一、减少重绘和重排

  1. 合并DOM操作:频繁地修改 DOM 元素的样式或结构会多次触发重排和重绘,所以要尽量将多个相关操作合并为一次。例如:不要逐个修改元素样式,而是通过修改style属性的对象形式或者使用classList来合并操作。比如:
const element = document.getElementById('myElement'); 
element.style.cssText = 'width: 100px; height: 100px; background-color: red;';
// 或者使用classList添加类名来应用样式(前提是提前定义好相关的CSS类)
element.classList.add('new-style');
  1. 离线操作DOM:使用文档片段documentFragment或者display:none将元素从页面中脱离出来进行操作,操作完成后再添加回页面,这样可以减少重排次数。例如批量添加列表项:
const fragment = document.createDocumentFragment(); 
for (let i = 0; i < 10; i++) { 
const li = document.createElement('li'); 
li.textContent = `Item ${i}`; 
fragment.appendChild(li); 
} 
const list = document.getElementById('myList'); 
list.appendChild(fragment);
  1. 避免频繁读取计算样式:每次通过getComputedStyle()等方法获取元素的计算样式时,浏览器可能需要重新计算样式,进而触发重排。如果需要多次使用样式值,可以先获取并保存起来,避免多次查询。例如:
const element = document.getElementById('myElement'); 
const computedStyle = window.getComputedStyle(element); 
const width = computedStyle.width; 
const height = computedStyle.height; 
// 后面使用width和height变量,而不是多次调用getComputedStyle

二、使用节流(Throttle)和防抖(Debounce)技术

  • 节流(Throttle)技术

    • 概念:节流的目的是限制函数在一定时间内只能被调用一次,就像水龙头控制水流一样,每隔一段时间才允许流出一点水(函数执行)。比如在页面滚动时,可能有一个函数用于获取滚动位置并做一些计算,但滚动过程中触发频率很高,如果不做限制,函数会被频繁调用,消耗性能。节流可以确保该函数在一定时间间隔内(比如每 200 毫秒)最多执行一次。
    • 代码实现
     function throttle(func, delay) {
         let timer = null;
         return function() {
             if (!timer) {
                 func.apply(this, arguments);
                 timer = setTimeout(() => {
                     timer = null;
                 }, delay);
             }
         };
     }
    
     const handleScroll = () => {
         console.log('执行滚动相关操作');
     };
    
     window.addEventListener('scroll', throttle(handleScroll, 200));
    
  • 防抖

    • 概念:防抖是指在事件被触发后,等待一段时间(比如 300 毫秒),如果这段时间内该事件没有再次被触发,才执行对应的函数;如果在等待期间又触发了该事件,那么就重新计时等待。例如在搜索框输入时,通常会有一个函数用于发送请求获取搜索结果,为了避免每次输入一个字符就发一次请求,可以使用防抖,等用户停止输入一小段时间后再真正执行请求函数。
    • 代码实现
    function debounce(func, delay) {
        let timer = null;
        return function() {
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(() => {
                func.apply(this, arguments);
                timer = null;
            }, delay);
        };
    }
    
    const handleInput = () => {
        console.log('执行搜索相关操作');
    };
    
    const inputElement = document.getElementById('searchInput');
    inputElement.addEventListener('input', debounce(handleInput, 300));
    

总结

前端性能优化任务复杂且重要,涵盖多方面技术与策略,开发者要依具体应用场景和需求合理选用。借助性能监测工具可跟踪并改进网页性能,保障用户体验流畅。了解并避开常见优化误区能更有效提升性能,且在技术不断变化下,前端性能优化始终是开发工作中影响用户体验与业务成功的关键部分。