前端 面试+笔试 知识复习

 

目录

1、FMP指标在中后台场景的意义,为什么不用LCP处理

用户体验指标:

加载性能指标

中后台场景的意义

2、从URL输入到浏览器发生的所有过程中,哪些可以进行性能优化

URL所有过程: 

可以进行性能优化的方面:

3、细谈 vue - component(组件) 

组件的定义和注册

组件的基础结构

组件间通信

子组件向父组件传递消息(Events)

插槽

具名称插槽

作用域插槽

生命周期钩子(Lifecycle Hooks)

高级特性

异步组件:可以按需加载组件,提升应用的性能。

4.vue里的一些插件可以怎么做

5.写实现一个request,可以在失败的时候重试,有interval和maxCount参数  : oc


1、FMP指标在中后台场景的意义,为什么不用LCP处理

Web前端最新优化指标:FP、FCP、FMP、LCP、TTI、CLS、FID、FPS等

用户体验指标:
  • TTI首次可交互时间,连续五秒内没有长任务和两个以上的 GET 请求时,那五秒前的最后一个长任务结束时间就是 TT 记录的时间

  • FID首次可交互时间,连续五秒内没有长任务和两个以上的 GET 请求时,那五秒前的最后一个长任务结束时间就是 TT 记录的时间

  • TBT阻塞总时间,记录在 FCP 和 TTI之间长任务的阻塞时间

  • FP首次绘制,页面第一次绘制元素的时候

  • FCP首次内容绘制,首次绘制文本、图片、非空白 Canvas 或 SVG的时间

  • LCP最大内容绘制,视窗内最大的元素绘制的时间

  • CLS累计位移偏移,记录了页面上非预期的位移波动CSDN9

加载性能指标
  • FMP(First Meaningful Paint),首次渲染有意义的内容的时间,“有意义”没有一个标准的定义,FMP的计算方法也很复杂。
    • 优点: FMP是一个早期的性能指标,可以快速反馈页面内容的初步加载情况。
    • 缺点: FMP的检测较为复杂,容易受广告和异步内容影响,因此不稳定且难以标准化。
  • LCP(largest contentful Paint),最大内容渲染时间。
    • 优点: LCP更稳定,容易测量,并且能更好地反映用户感知到的页面加载速度。
    • 缺点: 作为较晚期的指标,LCP可能不能及时反映页面初始加载的体验。
中后台场景的意义

在中后台(B2B、内部系统、管理后台等)场景中,FMP和LCP的使用意义和取舍需要根据实际需求来决定

  • 用户期望
    • 中后台用户:通常更注重功能性和数据加载速度,要求快速访问和操作,而不太关注页面的初步视觉加载
    • 前台用户:一般更关心页面的感知加载速度和初次内容展示。
  • 指标选择
    • FMP在中后台场景中的意义:尽管FMP在前台体验优化中较为常用,但在中后台场景中,用户可能更关注页面是否能尽快显示主要内容和进行操作。FMP能帮助开发者了解页面主要内容的首次呈现时间。
    • LCP在中后台场景中的意义:LCP能更好地反映页面的最终加载状态。如果页面包含较大图表或数据表,LCP能帮助评估这些元素的加载时间,确保用户能尽快看到完整的数据。
  • 为什么不使用LCP处理
    • 数据密集型应用:中后台系统通常包含大量的数据展示,初始内容(如表单、表格、仪表盘)较早展示给用户很重要,而不是等待所有内容加载完毕。
    • 交互优先:中后台用户往往需要快速的响应和操作,FMP提供了一个早期的内容展示时间点,可以优化初始交互体验。
    • LCP稳定性:尽管LCP更稳定,但对于数据量大、内容复杂的后台系统,LCP可能会推迟性能反馈时间,使得优化措施更难实施。

2、从URL输入到浏览器发生的所有过程中,哪些可以进行性能优化

URL所有过程: 
  1. DNS解析:当用户在浏览器中输入一个URL时,浏览器首先会进行DNS解析,将URL中的域名解析成对应的IP地址。
  2. TCP连接:当DNS解析完成后,浏览器会与服务器建立TCP连接。
  3. HTTP请求:浏览器通过TCP连接向服务器发送HTTP请求,请求服务器返回相应的页面内容。
  4. 服务器响应:服务器收到HTTP请求后,会处理请求并返回响应内容,包括HTML代码、CSS样式、JavaScript脚本等。
  5. 浏览器解析:浏览器收到服务器响应后,会解析HTML代码、CSS样式和JavaScript脚本,并将它们转换为可视化的页面。
  6. 页面呈现:当浏览器解析完成后,页面就会呈现给用户。
  • 用户在浏览器地址栏输入URL回车
  • 输入后 --> 网络进程,网络收到URL请求后查看是否缓存了该资源
    • 缓存了该资源:返回给浏览器
    • 未缓存该资源:网络进程向服务器发起HTTP请求(网络请求)以请求资源
      • DNS解析:将域名解析成IP地址
      • 如果请求协议是HTTPS,那么还需建立TLS连接
      • 利用IP地址和服务器建立TCP链接,浏览器与服务器进行三次挥手
      • 浏览器构建请求头信息,并将其发送给服务器
      • 服务器处理请求并放回HTTP报文给网络
      • 处理状态码
    • 缓存分为:强缓存协商缓存
  • 断开连接:TCP四挥手
  • 浏览器进程检查当前的URL是否和之前打开的渲染进程根域名是否相同,如果相同,则复用原来的进程,如果不同,则开启新的渲染进程。
可以进行性能优化的方面:
  • DNS解析:
    • DSN预解析:使用
      <link rel="dns-prefetch" href="//example.com">
      
      标签提前解析DNS。
    • 使用快速DNS服务:选择响应速度快且稳定的DNS服务提供商。
    • 内容分发网络(CDN):使用CDN可以显著减少DNS解析时间。
      • CDN:它采取了 分布式网络 缓存结构(即国际上流行的web cache技术),通过在现有的Internet中增加一层新的网络架构,将网站的 内容发布 到最接近用户的cache服务器内,通过 DNS负载均衡 的技术,判断用户来源就近访问cache服务器取得所需的内容,解决Internet 网络拥塞 状况,提高用户访问网站的响应速度,如同提供了多个分布在各地的加速器,以达到快速、可冗余的为多个网站加速的目的。
  • 优化关键资源:关键资源是指那些对页面加载速度影响最大的资源,通常包括HTML、CSS、JavaScript脚本、图像和视频等。
    • 使用CDN:CDN可以将关键资源缓存到全球各地的服务器上,从而加快资源的加载速度。
    • 延迟加载非关键资源:对于那些对页面加载速度影响较小的资源,可以采用延迟加载策略,在页面加载完成后再加载这些资源。
    • 合并关键资源:将多个关键资源合并成一个文件可以减少HTTP请求的数量,从而加快加载速度。
    • 压缩关键资源:通过压缩关键资源可以减少它们的体积,从而加快加载速度。常用的压缩工具包括Gzip、Brotli等。
  • 减少重绘和重排:重绘是指浏览器重新绘制页面内容,而重排是指浏览器重新计算元素的位置和大小。重绘和重排都会对页面的加载速度造成影响。为了减少重绘和重排,可以采取以下策略。
    • 避免使用不必要的动画和过渡效果
    • 避免频繁更改元素的属性
    • 使用flexbox和grid布局
    • 优化CSS选择器
  • 优化CSS和JavaScript:CSS和JavaScript脚本也是影响页面加载速度的重要因素。为了优化CSS和JavaScript。
    • 使用CSS预处理器:CSS预处理器可以帮助我们编写更简洁、更易维护的CSS代码。
    • 使用JavaScript模块化工具:JavaScript模块化工具可以帮助我们将JavaScript代码分解成更小的模块,从而加快加载速度。
    • 压缩CSS和JavaScript:通过压缩CSS和JavaScript代码可以减少它们的体积,从而加快加载速度。

3、细谈 vue - component(组件) 

        在Vue.js中,组件(component)是构建用户界面的基本单位。组件可以看作是独立的、可重用的界面元素,能够包含逻辑、模板和样式。Vue组件通过组合形成一个完整的应用,增强了代码的可维护性和可重用性。以下是Vue组件的详细解析。

  • 组件的定义和注册
    • 全局注册组件:全局注册的组件可以在任何Vue实例的模板中使用。
    • // 定义一个名为 my-component 的组件
      Vue.component('my-component', {
        template: '<div>A custom component!</div>'
      });
      
      // 创建一个根实例
      new Vue({
        el: '#app'
      });

    • 局部注册主键:局部注册的组件仅在当前的Vue实例或组件中可用。
    • var ChildComponent = {
        template: '<div>A custom component!</div>'
      };
      
      new Vue({
        el: '#app',
        components: {
          'my-component': ChildComponent
        }
      });
  • 组件的基础结构
    •  模板(templa):描述组件的HTML结构
    • 脚本(script):包含组件的数据、方法、生命周期钩子等逻辑
    • 样式(style):定义组件的css
    • <template>
        <div>
          <h1>{{ message }}</h1>
        </div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            message: 'Hello, Vue Component!'
          };
        }
      };
      </script>
      
      <style scoped>
      h1 {
        color: blue;
      }
      </style>
      
  • 组件间通信
    • 父组件向子组件传递数据(Props)        
    • <!-- ParentComponent.vue 父组件 -->
      <template>
        <div>
          <child-component :message="parentMessage"></child-component>
        </div>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          'child-component': ChildComponent
        },
        data() {
          return {
            parentMessage: 'Hello from Parent'
          };
        }
      };
      </script>
    • <!-- ChildComponent.vue 子组件 -->
      <template>
        <div>
          <!-- 子组件通过模板语法进行绚烂 -->
          <p>{{ message }}</p>
        </div>
      </template>
      
      <script>
      export default {
          <!-- 子组件通过props接收父组件传递过来的数据 -->
        props: ['message']
      };
      </script>
    • 子组件向父组件传递消息(Events
    • <!-- ParentComponent.vue -->
      <template>
        <div>
          <child-component @my-event="handleEvent"></child-component>
        </div>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          'child-component': ChildComponent
        },
        methods: {
          handleEvent(data) {
            console.log(data);
          }
        }
      };
      </script>
    • <!-- ChildComponent.vue -->
      <template>
        <div>
          <button @click="sendMessage">Send Message</button>
        </div>
      </template>
      
      <script>
      export default {
        methods: {
          sendMessage() {
            this.$emit('my-event', 'Hello from Child');
          }
        }
      };
      </script>
  • 插槽
    • 插槽用于在子组件中嵌入父组件的内容。Vue提供了默认插槽、具名插槽和作用域插槽。
    • 默认插槽
    • <!-- ParentComponent.vue -->
      <template>
        <div>
          <child-component>
            <p>This is some slot content</p>
          </child-component>
        </div>
      </template>
    • <!-- ChildComponent.vue -->
      <template>
        <div>
          <slot></slot>
        </div>
      </template>
    • 具名称插槽
    • <!-- ParentComponent.vue -->
      <template>
        <div>
          <child-component>
            <template v-slot:header>
              <h1>Header Content</h1>
            </template>
            <template v-slot:footer>
              <p>Footer Content</p>
            </template>
          </child-component>
        </div>
      </template>
    • <!-- ChildComponent.vue -->
      <template>
        <div>
          <slot name="header"></slot>
          <slot></slot>
          <slot name="footer"></slot>
        </div>
      </template>
    • 作用域插槽
    • <!-- ParentComponent.vue -->
      <template>
        <div>
          <child-component>
            <template v-slot:default="slotProps">
              <p>{{ slotProps.text }}</p>
            </template>
          </child-component>
        </div>
      </template>
    • <!-- ChildComponent.vue -->
      <template>
        <div>
          <slot :text="message"></slot>
        </div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            message: 'Hello from Child'
          };
        }
      };
      </script>
  • 生命周期钩子(Lifecycle Hooks)
    • 组件的生命周期钩子是指在组件的创建、挂载、更新和销毁过程中会被自动调用的函数。常用的生命周期钩子有:
      • created: 组件实例创建完成后调用。
      • mounted: 组件挂载到DOM后调用。
      • updated: 组件更新后调用。
      • destroyed: 组件销毁后调用。
    • export default {
        created() {
          console.log('Component created');
        },
        mounted() {
          console.log('Component mounted');
        },
        updated() {
          console.log('Component updated');
        },
        destroyed() {
          console.log('Component destroyed');
        }
      };
      
  • 高级特性
    • 动态组件:Vue允许动态地切换组件,可以使用<component>标签。
    • <template>
        <div>
          <component :is="currentComponent"></component>
          <button @click="switchComponent">Switch Component</button>
        </div>
      </template>
      
      <script>
      import ComponentA from './ComponentA.vue';
      import ComponentB from './ComponentB.vue';
      
      export default {
        data() {
          return {
            currentComponent: 'ComponentA'
          };
        },
        components: {
          ComponentA,
          ComponentB
        },
        methods: {
          switchComponent() {
            this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA';
          }
        }
      };
      </script>
      
    • 异步组件:可以按需加载组件,提升应用的性能。
    • export default {
        components: {
          'my-async-component': () => import('./MyAsyncComponent.vue')
        }
      };
      

4.vue里的一些插件可以怎么做

5.写实现一个request,可以在失败的时候重试,有interval和maxCount参数  : oc

/**
 * 带重试功能的请求函数
 * @param {string} url - 请求的URL
 * @param {object} options - fetch请求的选项对象
 * @param {number} interval - 每次重试之间的间隔时间(毫秒)
 * @param {number} maxCount - 最大重试次数
 * @returns {Promise<Response>} - 返回一个Promise,解析为fetch的Response对象
 */
async function requestWithRetry(url, options, interval, maxCount) {
    let attempts = 0; // 记录已尝试的次数

    // 当尝试次数小于最大重试次数时,继续尝试
    while (attempts < maxCount) {
        try {
            // 尝试发送请求
            const response = await fetch(url, options);

            // 如果响应状态不是ok,抛出错误
            if (!response.ok) {
                throw new Error(`Request failed with status ${response.status}`);
            }

            // 请求成功,返回响应结果
            return response;
        } catch (error) {
            attempts++; // 增加尝试次数
            console.log(`Attempt ${attempts} failed: ${error.message}`); // 打印错误信息

            // 如果达到最大重试次数,抛出错误
            if (attempts >= maxCount) {
                throw new Error(`Max retries reached: ${error.message}`);
            }

            // 等待一段时间再重试
            await new Promise(resolve => setTimeout(resolve, interval));
        }
    }
}

// 使用示例
const url = 'https://jsonplaceholder.typicode.com/posts'; // 请求的URL
const options = {
    method: 'GET', // 请求方法为GET
    headers: {
        'Content-Type': 'application/json' // 请求头,指定内容类型为JSON
    }
};
const interval = 1000; // 每次重试间隔1秒(1000毫秒)
const maxCount = 3; // 最多重试3次

// 调用带重试功能的请求函数
requestWithRetry(url, options, interval, maxCount)
    .then(response => response.json()) // 解析响应结果为JSON
    .then(data => console.log(data)) // 打印请求成功后的数据
    .catch(error => console.error(error)); // 捕获并打印错误信息
  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值