2022前端面试题!已获字节、拼多多等大厂offer(下)
上篇地址是https://www.nowcoder.com/discuss/834183
笔者在2021年末到2022年初面了阿里、百度、字节跳动、微软、拼多多、B站等大厂。这个下篇主要再和大家总结一下性能、前端新趋势、项目方面的面试题~
优化相关
优化相关主要分为两类:优化开发体验和项目性能优化
优化开发体验
- 加快打包速度
- 开发环境可以尝试esmodule的打包形式,可以使用vite或者esbuild-loader
- webpack的话可以使用cache-loader、happyPack、noParse等
- 完善devops流程
- 使用低代码平台构建管理平台页面
- 利用微前端的技术无关性,新项目使用新技术来构建
项目性能优化
工欲善其事,必先利其器,在讨论如何性能优化之前,先看一下如何收集关于性能的数据
- 打包产物的话,可以根据webpack-bundle-analyze之类的打包分析工具进行分析
- 网站的性能概要可以通过lighthouse查看
- 运行时一些关键时间的监控例如DNS查询耗时、白屏时间等可以使用Performance Api来计算
- 比较具体的性能卡点通过Chrome Performance火焰图分析
开始性能优化的前提是要熟知两道经典题目『事件循环机制』和『从浏览器输入地址到呈现出网页的过程』,事件循环机制可以让你知道为什么要对一些高计算任务进行分片、以及为什么分片是使用setTimeout而不是Promise,而浏览器输入地址更是一道非常全面的问题,牵扯到缓存、DNS、HTTP、重排重绘合成等方面,之后我们的具体性能优化也是会随着这个来讲(浏览器输入地址这道题写在了上篇,如果有需要可以进行阅读~)
事件循环
- js代码执行是单线程,浏览器有单独的事件触发线程来提供宏任务队列收集定时器、异步请求、浏览器事件中的callback
- 本身的script标签也是一个宏事件,在宏任务执行的过程中,Promise、queueMicrotask中的callback会加入到微任务队列中,在当前宏任务主流程执行完后执行所有微任务(微任务太多会使浏览器卡死)
- 执行requestAnimationFrame(在下次重绘之前调用)
- 如果有空闲的时间去执行requestIdleCallback
- 再从宏任务队列中取出下一个宏任务进行执行
性能优化决策
所以我们从事件循环角度来考虑:
- 耗时计算任务可以采取宏任务切片执行
- 控制一次宏任务中微任务的数量
- 动画可以写在requestAnimationFrame中
从浏览器输入地址到呈现出网页的过程
上面我们提到了这道题,渲染过程可以简单的归纳一下
检查缓存是否存在 => DNS域名解析 => http请求返回 => 浏览器解析资源下载资源 => 重排重绘合成
我们可以从这几个方面来考虑怎么做性能优化
缓存
在浏览器取回页面之前,会经历几个缓存check的步骤,分别是:
- Service Worker
- cache or disk
- 强缓存
- 协商缓存
这几个步骤前端能去掌握的只有Service Worker,在手机端可以考虑使用Service Worker缓存一些静态资源
DNS
- 统一域名
- 预获取(dns-prefetch)
- 让浏览器提前解析需要用到的域名,可以选用自动解析和手动解析两种方式
<!-- 开启DNS预获取 --> <meta http-equiv="x-dns-prefetch-control" content="on"> <!-- 设置DNS预获取的域名 --> <link rel="dns-prefetch" href="https://orderapi.phone580.com" />
- 预解析(preconnect)
浏览器要建立一个连接,需要经过DNS查找,TCP三次握手和TLS协商,这些过程需要相当的耗时,所以preconnect,就是一项使浏览器预先建立一个连接,等真正需要加载资源的时候能直接请求
HTTP
可以从Http2相对于Http1.1的升级上来讲性能优化点,和前端相关主要的是:
- 头部压缩
- 多路复用
- Server Push
下载资源
首屏请求的资源如果变小,有利于用户能先看到画面,可以有几个优化的点:
- 懒加载路由
- 善用CDN
- preload、prefetch等,在主页预先加载别的页面的资源
重排重绘合成
- 一旦dom数量上去重排的速度就会变慢,长列表可以用虚拟列表去做,控制dom节点数量
- css适当使用合成层渲染
最后还有一些方向策略
- SSR、SSG
- 骨架屏(手机端)
- wasm、web worker
性能优化基本上就是这些啦,在回答这个问题时有一条清晰的主脉络是最重要的,随着渲染的流程讲不容易乱
跨端
- React Native vs Flutter https://www.zhihu.com/question/384934444
- 小程序 https://zhuanlan.zhihu.com/p/59764741
微前端
- 什么是微前端
- 概念:将多个独立的应用组合成一个更大的整体,由主框架根据路由加载子应用,不同的子应用状态隔离
- 适用场景:尝试更新颖的技术栈、降低耦合
可能是你见过最完善的微前端解决方案 - 知乎 (zhihu.com)
- 微前端有哪几种实现方式
- package集成
- iframe
- 难以做路由、响应式页面
- 主要关系于子应用提供什么形式的资源做渲染入口
- JS entry集成
- single-spa
- 子应用将资源打成一个 entry script,打包产物可能体积庞大
- HTML entry集成
- qiankun
- 直接将子应用打出来 HTML 作为入口,主框架可以通过 fetch html 的方式获取子应用的静态资源,同时将 HTML document 作为子节点塞到主框架的容器中
- Web Component
- 每个子应用提供一个自定义元素供容器实体化
- Module Federation
- 多个独立开发,部署的模块
前端新趋势
- React 18
- Concurrent mode 深入剖析 React Concurrent - 知乎 (zhihu.com)
startTransaction与useDeferredValue,状态更新划分优先级,进一步优化用户响应- React Server Component,渲染放到服务端,解决大依赖和复杂组件在客户端渲染造成的卡顿
- 支持React.lazy的SSR架构,使用全新的
pipeToNodeWritableapi流式传输服务端渲染好的HTML,client端通过Suspence包裹进行选择性水合(hydration)
- pnpm (volt)
- 新的依赖管理工具,通过软连接的方式解决shadow dependency问题,极大程度提升性能
- 前端基建
- 通过ES Module的方式,避免打包,同时,通过使用执行效率更高的语言(go, rust),实现本地启动效率的极大提升(10倍+)
- vite
- esbuild
- 前端基建rust化: swc, rome
- 通过ES Module的方式,避免打包,同时,通过使用执行效率更高的语言(go, rust),实现本地启动效率的极大提升(10倍+)
- 低代码
- 拖拽式表单与数据结构生成,将研发从CRUD的重复劳动中解放出来
- Tailwind CSS
- 好用的原子类集合与设计系统集成,不再纠结类名
- JAMStack
- 云原生,serverless方式部署网站
- web3D: Babylon.js, Three.js
- 元宇宙时代,前端也需要3d
- Tauri
- 新的桌面端框架,使用操作系统webview进行界面渲染并使用rust与操作系统集成,不再需要打包Chromium和nodejs,大大减小应用体积
项目相关
在面试过程中,基本上所有的面试官都会让你选择一个项目来介绍,这个时候你可以自己选择一下,是介绍你搭建的项目还是最有技术难点的项目,当然两个都介绍也可以
关于项目面试中可以说是必问的问题:
- 所有项目中你印象最深刻的是哪一个?为什么
- 你在这个项目中遇到的最大的困难是什么,是怎么解决的?
- 从一个需求提出到上线的整个过程,有觉得不完善的地方吗,有没有去做改进呢?
像这种问题如果没有非常硬、非常好说的例子,我建议还是要准备一下~像以上的三个问题,我们来分析一下应该怎么回答
- 印象深刻的话可以是第一个负责的项目、也可以是之前没涉及过的领域,第一个带人的也可以,只要有理由就可以了
- 最大的困难的话可以有一些小小的艺术加工哈,比如实际在项目中碰到了什么问题,就算当时没有解决绕过了,也可以自己思考一下如果是现在的自己会怎么去做,有哪几种方案分别的优劣是什么,只要逻辑通顺没有破绽,这个就是你解决的问题啦
- 这个问题可以从两个方面来回答,一个是整体流程上,需求是否match人力,测试评审选在了什么时候开,上线后是否有数据反馈,另一个是从前端角度,线上监控有没有做好,埋点的数据是否真实可用
还有一些是比较软性的问题,像是【和同事如果意见不合,要怎么解决】,【如果一个需求觉得没有价值,会去做吗】之类的,只要展现自己的积极和沟通力就可以了!
笔者在掘金上还会持续更新在工作中实际遇到的技术问题和解决方案,欢迎有兴趣的同学关注,一起讨论,一起成长!
#前端面经##字节跳动##拼多多##面试题目#
查看11道真题和解析