面试场景题:性能的检测

前言

嘿嘿,好久没写文章了,最近在上班当牛马,一有时间就来更新一下面试题了。

题目描述

有一个页面,有8个元素, 做了flex 布局,请计算性能指标的渲染总时间和第一个元素的渲染完时间.

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="flex-item">item 1</div>
        <div class="flex-item">item 2</div>
        <div class="flex-item">item 3</div>
        <div class="flex-item">item 4</div>
        <div class="flex-item">item 5</div>
        <div class="flex-item">item 6</div>
        <div class="flex-item">item 7</div>
        <div class="flex-item">item 8</div>

    </div>
    <script src="./script.js"></script>
</body>
</html>
css 复制代码
body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
    background-color: #f4f4f4;
}

.container {
    display: flex;
    flex-wrap: wrap; /* 允许换行 */
    justify-content: space-between; /* 元素之间均匀分布 */
}

.flex-item {
    background-color: #4CAF50; /* 绿色背景 */
    color: white; /* 白色文字 */
    padding: 20px;
    margin: 10px;
    flex: 1 1 calc(25% - 20px); /* 每个元素占容器的25%宽度,减去边距 */
    box-sizing: border-box; /* 包含内边距和边框在内的宽度计算 */
    text-align: center; /* 文字居中 */
}

解题:

考察

该题考察的是你是否知道页面的渲染步骤:

1. 构建DOM树

当浏览器接收到HTML文档时,它会开始解析这个文档,并构建一个DOM(Document Object Model)树。DOM树是网页上所有元素的一个层次结构表示。每个HTML标签都会被转换为DOM树中的一个节点。

2. 加载外部资源

在构建DOM树的同时,浏览器还会下载页面中引用的所有外部资源,如CSS文件、JavaScript文件、图片等。这些资源可能会影响页面的最终布局和样式。

3. 构建CSSOM树

同时,浏览器也会解析所有的CSS规则,无论是内联的、包含在<style>标签内的还是从外部CSS文件加载的,并根据这些规则构建CSS对象模型(CSSOM)。CSSOM与DOM一起决定了每个元素最终的样式。

4. 创建Render树

浏览器接下来会将DOM树和CSSOM树合并,生成一个Render树(也称为渲染树或框树)。Render树只包含需要显示在页面上的节点及其计算后的样式信息。例如,那些设置为display: none;的元素不会出现在Render树中。

5. 布局阶段(Layout)

一旦Render树创建完成,浏览器就会进行布局处理,即确定每个节点在屏幕上的精确位置和大小。这一步骤被称为"重排"或"回流"。在这个阶段,浏览器会考虑各种因素,如视口尺寸、父容器尺寸等。

6. 绘制(Paint)

在布局之后,浏览器会进入绘制阶段,将Render树中的每个节点转换成屏幕上的实际像素。这包括文本、颜色、边框、阴影和其他视觉效果的绘制。此过程可能分为多个层来优化性能。

7. 合成(Composite)

最后,如果页面使用了合成技术(比如使用了CSS 3D变换或某些动画),不同的层会被组合在一起形成最终的图像。现代浏览器通常会在GPU上执行这一操作以提高效率。

代码:

js 复制代码
function measureRenderTime() {
    const startTime = performance.now(); // 计算开始时间
  
    window.addEventListener('load', () => {
      const loadEndTime = performance.now();
      console.log(`页面渲染总时间: ${loadEndTime - startTime}ms`);
    });
  
    const allItems = document.querySelectorAll('.flex-item');
    const firstElement = allItems[0]; // 第一个元素
    const eightElement = allItems[7]; // 第八个元素(假设至少有8个)
  
    function checkElement(element, label) {
      if (!element) return; // 如果元素不存在,则返回
      if (element.offsetWidth > 0 && element.offsetHeight > 0) { // 元素已经渲染了
        const endTime = performance.now(); // 计算结束时间
        const renderTime = endTime - startTime; // 计算渲染时间
        console.log(`${label}元素渲染完成时间: ${renderTime}ms`); // 打印渲染时间
      } else {
        requestAnimationFrame(() => checkElement(element, label)); // 使用requestAnimationFrame代替setInterval
      }
    }
  
    checkElement(firstElement, '第一个');
    checkElement(eightElement, '第八个');
  }
  
  // 确保DOM完全加载后再执行
  document.addEventListener('DOMContentLoaded', measureRenderTime);

解析:

  1. performance.now() : 一个高精度的时间测量方法,用来获取当前时间戳。通过比较不同时间点的值,可以精确地计算出某段代码或某个过程的执行时间。

  2. window.addEventListener('load', ...) : 监听window对象的load事件,确保在页面上所有的资源(包括图片、样式表等)都已加载完毕时触发。这里用于计算整个页面从开始加载到完全加载完成所需的时间。

  3. document.querySelectorAll('.flex-item') : 选择页面中所有带有.flex-item类的元素,以便进一步检查它们的渲染状态。

  4. checkElement函数

  • 递归检查给定元素是否已被赋予非零的宽度和高度。如果条件满足,则认为该元素已经完成了基本的布局过程,并记录下此时与startTime之间的时间差。

  • 使用requestAnimationFrame来优化递归调用,这样可以确保只有在浏览器准备重绘时才进行检查,提高效率并减少CPU占用。

  1. document.addEventListener('DOMContentLoaded', measureRenderTime) : 确保measureRenderTime函数只在DOM完全加载之后执行。这保证了在尝试访问任何DOM元素之前,这些元素确实已经存在于文档中。
相关推荐
—Qeyser8 分钟前
用 Deepseek 写的uniapp血型遗传查询工具
前端·javascript·ai·chatgpt·uni-app·deepseek
codingandsleeping9 分钟前
HTTP1.0、1.1、2.0 的区别
前端·网络协议·http
小满blue11 分钟前
uniapp实现目录树效果,异步加载数据
前端·uni-app
喜樂的CC2 小时前
[react]Next.js之自适应布局和高清屏幕适配解决方案
javascript·react.js·postcss
天天扭码2 小时前
零基础 | 入门前端必备技巧——使用 DOM 操作插入 HTML 元素
前端·javascript·dom
软件测试曦曦2 小时前
16:00开始面试,16:08就出来了,问的问题有点变态。。。
自动化测试·软件测试·功能测试·程序人生·面试·职场和发展
咖啡虫2 小时前
css中的3d使用:深入理解 CSS Perspective 与 Transform-Style
前端·css·3d
烛阴3 小时前
手把手教你搭建 Express 日志系统,告别线上事故!
javascript·后端·express
拉不动的猪3 小时前
设计模式之------策略模式
前端·javascript·面试
旭久3 小时前
react+Tesseract.js实现前端拍照获取/选择文件等文字识别OCR
前端·javascript·react.js