前端面试拼图-实践经验

摘要:最近,看了下慕课2周刷完n道面试题,记录并添加部分可参考的文档,如下...

1. H5页面如何进行首屏优化?

        路由懒加载

        适用于SPA(不适用MPA)

        本质就是路由拆分,有限保证首页加载

        服务端渲染SSR

        传统的前后端分离(SPA)渲染页面的过程复杂

        SSR渲染页面过程简单,所以性能好

        如果是纯H5页面,SSR是性能优化的终极方案

        APP预取

        如果H5在APP WebView中展示,可使用APP预取

        用户访问列表页时,APP预加载页面首屏内容

        用户进入H5页面,直接从APP中获取内容,瞬间展示首屏

        分页

        针对列表页

        默认值展示第一页内容

        上划加载更多

        图片懒加载lazyLoad

        针对详情页

        默认只展示文本内容,然后触发图片懒加载

        注意:提前设置图片尺寸,尽量只重绘不重排

        Hybrid

        提前将HTML JS CSS下载到APP内部

        在APP webview中使用file://协议加载页面文件

        再用Ajax获取内容并展示(也可结合APP预 取)

        总结:服务端SSR是H5的终极优化方案(但成本也高)

        移动端H5要结合APP能力去优化

        严格来说,hybrid不是H5,但这里回答也没有问题

        扩展:SSR

        SSR(Server-Side Rendering,服务器端渲染)是一种将页面内容在服务器端生成并直接返回给客户端的技术。相比于传统的客户端渲染(CSR,Client-Side Rendering),SSR 在首次加载页面时可以直接呈现出完整的 HTML 内容,而不需要等待 JavaScript 文件下载和执行完成后再进行页面渲染,从而提高了首屏加载速度搜索引擎优化(SEO)效果适用于内容密集型页面

        SSR是一门"古老"的技术,刚刚兴起Web1.0时,就是SSR技术:PHP ASP JSP等

Nuxt.js(Vue) 安装 - NuxtJS | Nuxt.js 中文网Nuxt.js 十分简单易用。一个简单的项目只需将 `nuxt` 添加为依赖组件即可。icon-default.png?t=N7T8https://www.nuxtjs.cn/guide/installation

Next.js(React) Next.jsNext.js 是一个轻量级的 React 服务端渲染应用框架。icon-default.png?t=N7T8https://nextjs.frontendx.cn/

2. 后端一次性返回10w条数据,你该如何渲染?

        后端返回10W条数据,本身技术方案设计不合理;

        JS可以处理10w条数据,但是渲染的DO会非常卡顿;

        自定义中间层

        自定义node.js中间层,获取并拆分这10W条数据

        前端对接node.js中间层(后端的问题优先考虑用后端的思维解决,中间件),而不是服务端

        成本比较高

        虚拟列表

        只渲染可视区域DOM

        其他区域不显示,只用<div>撑起高度

        随着浏览器滚动,创建和销毁DOM

        虚拟列表实现起来非常复杂(且效果不一定好,例如低配手机),可借用第三方lib,例如Vue-virtual-scroll-list、 React-virtualiszed

3. 前端常用的设计模式有哪些?并说明使用场景

        设计原则

        最重要的思想:开放封闭原则

        对扩展开放

        对修改封闭

        工厂模式

        用一个工厂那个函数,来创建实例,隐藏new

        如jQuery $函数,React 的createElement函数

class Foo{}
// 工厂模式
function factory(a, b, c) {// if elsereturn new Foo()
}
const f = factory(1, 2, 3)

        单例模式

        全局唯一的实例(无法生成第二个)

        如Vuex Redux的store ;如全局唯一的dialog modal

class SingleTon {private static instance: SingleTon | null = nullprivate constructor() {}public static getInstance():SingleTon {  // 静态方法,属于类不属于实例if (this.instance = null) {this.instance = new SingleTon()}return this.instance}fn1() {}fn2() {} //实例方法
}const s = SingleTon.getInsance()
s.fn1()
const s1 = SingleTon.getInsance()
**s===s1   //true**

扩展:JS是单线程的,创建单例很简单;

        Java是支持多线程的,创建单例要考虑锁死线程,否则多个线程同时创建,单例就重复了(多线程共享进程内存)

        代理模式

        使用者不能直接访问对象,而是访问一个代理层

        在代理层可以监听get set 做很多事情,如ES6的Proxy 实现Vue3的响应式

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写

ES6 入门教程icon-default.png?t=N7T8https://es6.ruanyifeng.com/#docs/proxy

        观察者模式(Observer Pattern)

        当一个对象的改变需要同时改变其他对象,并且不知道有多少对象需要改变时,可以使用观察者模式。例如,在事件监听、数据订阅等场景下可以使用观察者模式

// 一个主题,一个观察者,主题变化后触发观察者执行
btn.addEventListener('click', () => {...})

        发布订阅模式(Publish-Subscribe Pattern)

        主要用于解耦组件之间的通信,实现松耦合的架构。在事件总线、消息队列、数据订阅等场景广泛使用,例如事件总线在非父子组件之间传递数据或触发特定操作

// 绑定
event.on('event-key', () => {//事件1
})
event.on('event-key', () => {//事件2
})
// 触发执行
event.emit('event-key')

        装饰器模式

        是一种结构型设计模式,它允许向一个对象动态地添加新的功能,同时又不改变其结构。

        原功能不变,增加一些新功能(AOP面向切面编程),例如 Node.js 框架Nest.js

        ES和TypeScript的Decorator语法

        @testable就是一个类装饰器。它修改了MyTestableClass这个类的行为,为它加上了静态属性isTestable。testable函数的参数target是MyTestableClass类本身。

@testable
class MyTestableClass {// ...
}function testable(target) {target.isTestable = true;
}MyTestableClass.isTestable // true

        扩展:观察者模式和发布订阅模式的区别?

        观察者模式:Subject和Observer直接关联,没有中间媒介,如addEventListener绑定事件

        发布订阅模式:Publisher和Observer是松散耦合的,需要中间媒Event channel,如EventBus;发布者不直接与订阅者通信,而是将消息发布到消息代理,然后由代理负责将消息传递给所有订阅者

4. 实际工作中,做过那些Vue的优化?

        v-if 和v-show

        v-if 是条件渲染指令, 条件改变时会彻底销毁和创建组件,最初渲染消耗较小;

        v-show使用CSS display 属性来控制元素的显示与隐藏,切换性能开销较小,适用于频繁切换场景;

        大部分时候使用v-if更好,不要过度优化

        v-for使用key,且避免同时和v-if同时使用

        严格意义已经不能算优化项了,v-for不是key会报警;

        v-for的优先级比v-if高(vue2),因为这样会导致每次渲染都进行条件判断,影响性能;Vue3中优先级相反,建议使用计算属性替代实现兼容。

<ul><!--而且,key不要用index--><li v-for="(id,name) in list" :key="id">{{name}}</li>
</ul>

        使用computed缓存

        使用computed属性缓存计算属性,避免重复计算

export default {data() {return {msgList: [...] // 消息列表}},computed: {// 未读消息列表unreadCount() {return this.msglist.filter(m => m.read === false).length}}
}

        keep-alive缓存组件

        缓存大型列表或者表格,频繁切换的组件,如tabs;

        不要乱用,缓存太多会占用内存,且不好debug

        异步组件

        针对体积较大的组件,如编辑器、复杂表格、复杂表单等

        拆包,需要时异步加载,不需要则不加载

        减少主包体积,首页加载会更快

// 使用Vue.js中的defineAsyncComponent方法来实现异步组件加载
import {defineAsyncComponent} from 'vue'export default {name: 'AsyncComponent',  // 定义了一个名为AsyncComponent的组件/*** 通过components属性注册了一个名为 Child 的子组件,并使用defineAsyncComponent方法来定义异步加载这个子组件* 在defineAsyncComponent方法传入了一个函数,在需要渲染这个异步组件时被调用;使用动态import的方式来异步加载 './Child.vue' 组件,Webpack 会将这个异步加载的组件作为一个单独的chunk进行打包,这个chunk 的名称被指定为'async-child'。*/components: {Child: defineAsyncComponent(() => import(**/* webpackChunkeName: "async-child"*/** './Child.vue'))}
}

        路由懒加载

        项目比较大,拆分路由,保证首页先加载

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'const routes = [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About',// 通过动态import异步加载的About组件,并使用Webpack进行代码分割成名为"about"的chunkcomponent: () => import(/* webpackChunkeName: "about"*/  '../views/About.vue')}
]const router = createRouter({history: createWebHistory(),routes
})export default router

        服务端渲染SSR

        可使用Nuxt.js, 但按需优化,使用SSR的成本比较高

        扩展: 使用Vue遇到那些坑?

        内存泄漏

        全局变量,全局事件,全局定时器和自定义事件等绑定后未销毁

        Vue2响应式的缺陷(Vue3不再有)

        data新增属性用Vue.set

        data删除属性用Vue.delete

        无法直接修改数据arr[index] = value

        路由切换时scroll到顶部

        SPA的通病,不仅仅是Vue

        如列表页、滚动到第二屏,点击进入详情页,再返回列表页(此时组件重新渲染)就scroll到顶部

        解决方案:在列表页缓存数据和scrollTop的值;当再次返回列表页时,渲染组件,执行scrollTo(scrollTop的值)

        终极方案:MPA + APP webView

5. 实际工作中,对React做过的优化?(没实际用过)

        模拟v-show

        循环使用key

        Fragment减少层级

        JSX不要定义函数

        构造函数bind this

        使用shouldComponentUpdate

        使用shouldComponentUpdata判断组件是否要更新

        或者使用React.PureComponent

        函数组件使用React.memo

        Hooks缓存数据和函数

        useMemo useCallBack

        异步组件

import React, { Suspense } from 'react';const AsyncComponent = React.lazy(/* webpackChunkName: 'AsyncComponent'*/() => import('./AsyncComponent')
);function App() {return (<div><h1>My React App</h1><Suspense fallback={<div>Loading...</div>}><AsyncComponent /></Suspense></div>);
}export default App;

        路由懒加载

import React, { lazy, Suspense } from 'react';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';const Home = lazy(() => import('./Home'));
const List = React.lazy(() => import(/* webpackChunkName: 'List'*/ './List'));const = App() => {return (<Router><Suspense fallback={<div>Loading...</div>}><Switch><Route exact path="/" component={Home}/><Route path="./list" component={List}/></Switch></Suspense></Router>);
}

        SSR - Next.js

        扩展: 使用React遇到过那些坑?

        自定义组件的名称首字母大写

{/* 原生HTML组件*/}
<input/>{/* 自定义组件 */}
<Input/>

        JS关键字冲突

{/* for 改成 htmlFor, class要改成className*/}
<label htmlFor="input-name" className="xxx">姓名 <input id="input-name"/>
</label>

        JSX数据类型

        setState是异步更新的

const curNum = this.state.num
this.setState({num: curNum + 1}, () => {console.log('newNum', this.state.num) // 正确
})
console.log('newNum', this.state.num) // 错误,直接打印值尚未变化

6. 如果H5很慢,该如何排查性能问题?

        前端性能指标

        First Paint(FP):指浏览器从响应用户输入网址地址到浏览器开始显示内容的时间。

        First Contentful Paint(FCP):指浏览器从响应用户输入网址地址到页面首次绘制文本、图片、非白色的 canvas 或 SVG 的时间。

        First Meaningful Paint(FMP):以前是测量用户加载体验的主要指标,但已被 Largest Contentful Paint 取代。

        DomContentLoaded(DCL):DOM完全加载及解析事件触发

        Largest Contentful Paint( LCP):指可视区“内容”最大的可见元素开始出现在屏幕上的时间点。

        Load(L): Load 页面加载完成

        使用Chrome devTools可以监控上述指标识别那部分执行的慢:

        Performance可产看上述指标,并有网页快照(最好使用无痕模式避免缓存的影响)

        Network可以查看各资源的加载时间(开启Show overview)

        使用Lighthouse分析性能指标:

        lighthouse是非常流行的第三方性能评测工具

        支持移动端和PC端,可生成如下测试报告和优化建议

## lighthouse 安装
C:\Users\zhchen>**npm i lighthouse -g**
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'lighthouse@11.7.0',
npm WARN EBADENGINE   required: { node: '>=18.16' },
npm WARN EBADENGINE   current: { node: 'v18.14.2', npm: '8.19.1' }
npm WARN EBADENGINE }added 163 packages, and audited 164 packages in 7m12 packages are looking for fundingrun `npm fund` for detailsfound 0 vulnerabilities
## lighthouse 测试网页地址 --view表示查看测试报告  --preset=desktop
C:\Users\zhchen>**lighthouse https://www.imooc.com/ --view --preset=desktop使用PC端访问(默认移动端)**
? We're constantly trying to improve Lighthouse and its reliability.Learn more: https://github.com/GoogleChrome/lighthouse/blob/main/docs/error-reporting.mdMay we anonymously report runtime exceptions to improve the tool over time?We'll remember your choice, but you can also use the flag --[no-]enable-error-reporting (y/N) » falseLH:CLI:warn No response to error logging preference, errors will not be reported. +0m

        lighthouse生成国内访问github的报告:

        识别问题:哪里慢?加载慢 OR渲染慢

        加载慢的优化方法

        优化服务端硬件配置,使用CDN

        路由懒加载,大组件异步加载—减少主包体积

        优化HTTP缓存

        渲染慢的优化方法

        优化服务端接口(如Ajax获取数据慢)

        继续分析,优化前端组件内部的逻辑(参考Vue React优化)

        服务端渲染SSR

        总结,排查性能问题的步骤:

        分析性能指标,找到慢的原因;

        对症下药,解决问题

        持续跟进,持续优化

7. 工作中遇到过那些项目难点,是如何解决的?

        描述问题:背景+现象+造成的影响

        问题如何被解决:分析+解决

        自己的成长:学到了什么 + 以后如何避免

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/282650.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

命令提示符——CMD基础操作介绍

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

LIN通信开发流程,GENy导入LDF文件、使用GENy生成代码

一、使用GENy导入LDF文件&#xff0c;生成LIN代码 Micro是微控器Cpu&#xff0c;Mcs的12代 Derivativ是此微控器的衍生版&#xff0c;选择适合自己的选项。没有的话&#xff0c;我就是默认第一个MCS12X。 Compile没得选&#xff0c;默认。 填写Channel名&#xff0c;选择LDF文…

Android 开发 地图 polygon 显示信息

问题 Android 开发 地图 polygon 显示信息 详细问题 笔者进行Android项目开发&#xff0c;接入高德地图绘制区域后&#xff0c;需要在指定区域&#xff08;位置&#xff09;内显示文本信息&#xff0c;如何实现 实现效果 解决方案 代码 import com.amap.api.maps.model.T…

基于springboot的反诈宣传平台

技术&#xff1a;springbootmysqlvue 一、系统背景 反欺诈平台可以对公交信息进行集中管理&#xff0c;可以真正避免传统管理的缺陷。反欺诈平台是一款运用软件开发技术设计实现的应用系统&#xff0c;在信息处理上可以达到快速的目的&#xff0c;不管是针对数据添加&#xff…

NacosException: http error, code=403、NacosimeException——报错解决方法【Nacos2.x】

1、NacosException报错内容为&#xff1a; NacosException: http error, code403,msguser not found!,dataIdapplication-dev.yml,groupDEFAULT_GROUP,tenant连不上是因为成功开启鉴权后&#xff0c;所使用的Spring Cloud服务被拦截&#xff0c;需要在配置中添加Nacos用户名和…

诺视科技完成亿元Pre-A2轮融资,加速Micro-LED微显示芯片商业化落地

近日&#xff0c;Micro-LED微显示芯片研发商诺视科技&#xff08;苏州&#xff09;有限公司&#xff08;以下简称“诺视科技”&#xff09;宣布完成亿元Pre-A2轮融资&#xff0c;本轮融资由力合资本领投&#xff0c;老股东盛景嘉成、汕韩基金以及九合创投持续加码&#xff0c;这…

Echarts中手柄样式更改

代码&#xff1a; dataZoom: [{start: 0,end: 100,left: 100,bottom: 0,right: 140,backgroundColor: yellow,borderRadius: 15,borderColor: green,dataBackground: {lineStyle: {width: 0},areaStyle: {color: black,opacity: 1,}},selectedDataBackground: {lineStyle: {wi…

校企合作,助力人才培养——黄冈师范学院-唯众 “实习实训基地”揭牌仪式顺利举行

3月20日上午&#xff0c;黄冈师范学院计算机学院院长何中林、教务处实习科科长雷汝琳以及计算机学院实验室主任肖飞一行三人&#xff0c;莅临唯众进行参观交流。唯众总经理冉柏权、销售总监舒敏以及董事长助理代西凯进行了热情接待。双方就如何更好地结合企业需求与学院教育资源…

flink1.18.0报错 an implicit exists from scala.Int => java.lang.Integer, but

完整报错 type mismatch;found : Int(100)required: Object Note: an implicit exists from scala.Int > java.lang.Integer, but methods inherited from Object are rendered ambiguous. This is to avoid a blanket implicit which would convert any scala.Int to a…

阿里云2核服务器多少钱一年?

阿里云2核2G服务器配置优惠价格61元一年和99元一年&#xff0c;61元是轻量应用服务器2核2G3M带宽、50G高效云盘&#xff1b;99元服务器是ECS云服务器经济型e实例ecs.e-c1m1.large&#xff0c;2核2G、3M固定带宽、40G ESSD entry系统盘&#xff0c;阿里云活动链接 aliyunfuwuqi.…

使用vscode调试代码

Step1&#xff1a;在系统中安装gdb 在Ubuntu系统下安装gdb&#xff1a; apt-get update apt-get install gdb 在CentOS系统下安装gdb&#xff1a; yum install gdb Step2&#xff1a;编译生成Debug版本的可执行程序 假设源文件名称为test.cpp&#xff0c;使用g编译器&#…

Airtest-Selenium实操小课:爬取新榜数据

1. 前言 最近看到群里很多小伙伴都在用Airtest-Selenium做一些web自动化的尝试&#xff0c;正好趁此机会&#xff0c;我们也出几个关于web自动化的实操小课&#xff0c;仅供大家参考~ 今天跟大家分享的是一个非常简单的爬取网页信息的小练习&#xff0c;在百度找到新榜网页&a…

【二】【单片机】有关独立按键的实验

自定义延时函数Delay 分别用Delay.c文件存储Delay函数。用Delay.h声明Delay函数。每次将这两个文件复制到工程中&#xff0c;直接使用。 //Delay.c void Delay(unsigned int xms) //11.0592MHz {while(xms--){unsigned char i, j;i 2;j 199;do{while (--j);}…

SinoDB数据库运行分析

SinoDB数据库运行主要从数据库互斥资源等待、数据库写类型、备份文件有效性、Chunk状态等15个方向进行分析&#xff0c;具体说明如下&#xff1a; 一、数据库互斥资源等待 检查项目 数据库互斥资源等待 检查命令 onstat -g con |head -20 说明 onstat -g con 查看目前数据处…

常用的6个的ChatGPT网站,国内可用!

GPTGod &#x1f310; 链接&#xff1a; GPTGod &#x1f3f7;️ 标签&#xff1a; GPT-4 免费体验 支持API 支持绘图 付费选项 &#x1f4dd; 简介&#xff1a;GPTGod 是一个功能全面的平台&#xff0c;提供GPT-4的强大功能&#xff0c;包括API接入和绘图支持。用户可以选择免…

QT信号和槽机制connect用法

信号与槽机制是绝对不可或缺且常用的&#xff0c;其中的参数一般都会比较简单&#xff0c;bool、int、QString之类的&#xff0c;但当我们想要传递相对比较复杂的参数&#xff0c;例如QVector<int>、QList<QString>&#xff0c;以及一些我们自定义的结构体时&#…

在服务器上训练faster-rcnn模型(pycharm和Termius)

本文主要介绍使用服务器训练模型的两种方式&#xff1a;pycharm&#xff08;可视化界面友好&#xff09;and终端&#xff0c;本人用的是macos系统&#xff0c;可能pycharm某些入口的位置不一样&#xff0c;本教程代码以faster-rcnn为例 准备工作&#xff1a; 1.知道自己所用服…

故障诊断 | 一文解决,RBF径向基神经网络的故障诊断(Matlab)

文章目录 效果一览文章概述专栏介绍模型描述源码设计参考资料效果一览 文章概述

Trait与生命周期

原文链接&#xff1a;(*∇&#xff40;*) 咦,又好了~ Rust – xiaocr_bloghttp://www.xiaocr.fun/index.php/2024/03/18/trait%E4%B8%8E%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/ 目录 Trait 定义trait 默认实现 trait作为参数 Trait Bound语法 通过指定多个 trait bound …

大数据面试题 —— Zookeeper

目录 ZooKeeper 的定义ZooKeeper 的特点ZooKeeper 的应用场景你觉得Zookeeper比较重要的功能ZooKeeper 的选举机制 ***zookeeper主节点故障&#xff0c;如何重新选举&#xff1f;ZooKeeper 的监听原理 ***zookeeper集群的节点数为什么建议奇数台 ***ZooKeeper 的部署方式有哪几…