[关闭]
@gyyin 2022-07-30T16:21:35.000000Z 字数 4278 阅读 210

总结

面试


最重要的是复习这几块的内容:

  1. React
  2. HTTP
  3. Node
  4. 算法
  5. Vue
  6. 错误上报和监控

React

生命周期

Hooks

fiber

fiber 是 react16 新的架构,支持优先级调度,和以前的区别主要在于,以前的是栈递归,边做 diff 边更新,会导致页面长时间无响应。
fiber 是一个链表结构,通过 return、child、siblings 这些来连接起整个虚拟 DOM。每个虚拟 DOM 节点会创建一个 fibe。
第一次渲染的时候,会先创建一个空的 RootFiber 节点,基于这个 RootFiber 节点开始创建一个 WorkInProgress 树,WIP 树会根据虚拟 DOM 自顶向下创建 Fiber 结构,最终创建了一个 Fiber 树,这个时候会标记 effectTag。这个阶段一般是协调。
这一阶段是可以被打断的,如果当前桢剩余时间不足了,那么就不会继续了,等下一桢有足够时间后继续做递归。
协调里面也有两个阶段,一个是『递』,这是一个深度优先遍历,会一直往下找到叶子节点为止,然后开始『归』,寻找兄弟节点,一直找到其叶子节点,如果没有兄弟节点了,就开始往上回溯,回溯的时候会通过一个effect链表,将有 effectTag 的节点串联起来,然后一直回溯到 RootFiber 节点。
这个时候开始 commit 阶段,这个时候会根据在递归的时候的 effectTag 链表开始做 DOM 插入,这里会从链表头节点一直到链表末尾,这里一口气更新好 DOM 节点。很多事情都是在这个阶段做,比如执行 useEffect、componentDidMount、componentDidUpdate。

setState

在递归阶段执行 setState 的时候,会把它放到一个队列里面,至于要不要立即更新,这里做了判断,需要判断当前是否需要批量更新,不需要就不更新,等 commit 阶段再去更新。
但是如果 setState 放到异步任务里面,这里就会出现问题,commit 阶段已经更新完了,这个时候才会 setState,就会判断立即更新,所以不管是用 Promise.resolve、async/await、setTimeout 等等,都会导致 setState 立即更新。

Redux

Mobx

SSR

HTTP

浏览器缓存

强缓存

Expires、cache-control

协商缓存

Last-Modified、Etag

Web 安全

XSS

转义、CSP

CSRF

httpOnly、sameSite、referer、下发token

恶意扫描

设置 IP 黑名单
HTTP 状态码、请求头、HTTP1.1、HTTP2、HTTP3、HTTPS

Node

Fastify、流、中间件、事件循环、多进程

Webpack

babel

babel-loader 来转换各种语法,其中 @babel/preset-react 可以转换 jsx 的语法,它包括了 @babel/plugin-syntax-jsx、@babel/plugin-transform-react-jsx、@babel/plugin-transform-react-display-name 三个插件。
babel-loader 可以设置 cacheDirectory,下次构建的时候可以从缓存中读取数据,提高构建速度,一般在 node_modules/.cache/babel-loader 文件夹下面。
如果很慢的话,需要写更精确的正则匹配,还要排除 node_modules,在 exclude 里面配置。
@babel/env 是转换 ESNext 语法的,stage 阶段的无法转换需要特别安装 preset-stage 插件。
@babel/polyfill 体积过大,目前我们项目里面都用的是 core-js,体积更小,按需引入。

entry 和 output

一般可以打包多个页面,使用 html-webpack-plugin,设置多个 entry,这里的 plugin 可以选择某几个 entry 作为 chunk 依赖,可以实现首页只加载关键资源。
output 里面可以设置打包后文件的地址,一般是 html 里面的文件资源地址,这里可以选择 CDN 的地址。
filename 一般是指 entry 里面我们要打包出来的文件名,chunkFilename 是指不在我们 entry 里面,却又要打包出来的文件,一般就是懒加载的和公共第三方库。
output 里面还可以设置 libraryTarget 和 library,一般是用于打包第三方类库使用的,libraryTarget 可以选 commonjs、umd、amd 等规范,library 则是设置暴露出来的变量名。
但是 webpack 打包出来的会有一些无用的代码,所以我这里一般使用 microbundle 或者 rollup 来打包纯 JS SDK。

CSS

处理 CSS 一般使用 mini-css-extract-plugin 这个插件来处理,可以进行压缩,参数和 output 里面类似,filename 和 chunkFilename,代表含义也是一样的。
css-loader 里面可以设置 options 来实现 css-modules。

  1. modules: {
  2. localIdentName: '[name]__[local]___[hash:base64:5]'
  3. }

loader

一般在 module.rules 下面去编写,使用 test 来编写一个正则匹配文件名,use 一般传一个数组,数组里面可以是字符串(babel-loader),也可以是一个对象,包括 loader、options 属性,这里可以传入参数给 loader 进行处理。

hash

一般为了避免线上浏览器缓存,对打包后的文件后缀添加hash,hash分为hash、chunkhash、contenthash,hash是项目中所有文件共享一个hash,只要一个文件改变了,其他的文件后缀也会变。
chunkhash 是针对一个 chunk,但如果 JS 文件变了,依赖的 css 文件后缀也会变。
contenthash 是目前使用最多的,也是最优的,js 和 css 是分离的。

optimization

minimizer

这是一个数组,可以接受多个 options,可以用自带的,也可以用 terser-webpack-plugin 来配置压缩、缓存、parallel。

splitChunks和runtimeChunk

参数 chunks 支持三个,分别是 async、initial、all。
async 的意思是只从动态加载的模块拆分,意味着如果不是动态加载的模块里面的第三方库和引入,这个是不会拆分 chunk 文件的。
initial 意思是只从入口文件拆分,意味着不是入口文件,也不会进行拆分。
all 表示两个都支持,动态加载的文件和入口文件都会拆分。
runtimeChunk是将包含 chunks 映射关系的 list 单独提取出来,不然的话每次改动都会重新生成hash,导致runtimeChunk变化,进而导致包含它的 app.js 变化,这里单独提取出来,有利于 app.js 缓存。
script-ext-html-webpack-plugin 支持把 JS 直接内联到 HTML 里面,有利于一些文件不用重复加载,比如 runtimeChunk 每次构建后hash都会变化。

cacheGroups

cacheGroups 是用来对 chunk 进行拆分的规则,常用的属性是 chunks 和 priority、test,chunks是按什么规定拆分,priority是拆分的优先级,test是拆分的文件匹配规则。

  1. module.exports = {
  2. //...
  3. optimization: {
  4. splitChunks: {
  5. chunks: 'async',
  6. minSize: 30000,
  7. minChunks: 1,
  8. maxAsyncRequests: 5,
  9. maxInitialRequests: 3,
  10. automaticNameDelimiter: '~',
  11. name: true,
  12. cacheGroups: {
  13. vendors: {
  14. test: /[\\/]node_modules[\\/]/,
  15. priority: -10
  16. },
  17. default: {
  18. minChunks: 2,
  19. priority: -20,
  20. reuseExistingChunk: true
  21. }
  22. }
  23. }
  24. }
  25. };

resolve

  1. alias 设置别名
  2. extensions:指定添加后缀
  3. modules:指定引入文件路径

module

  1. rules:配置 loader
  2. noParse:忽略解析某些库

devServer

  1. hot:模块热替换
  2. historyApiFallback:如果是true,则是默认将所有请求都返回 index.html,如果是多页面,可以设置一个数组,类似于:
  1. historyApiFallback: {
  2. // 使用正则匹配命中路由
  3. rewrites: [
  4. // /user 开头的都返回 user.html
  5. { from: /^\/user/, to: '/user.html' },
  6. { from: /^\/game/, to: '/game.html' },
  7. // 其它的都返回 index.html
  8. { from: /./, to: '/index.html' },
  9. ]
  10. }

图片

可以用 file-loader 和 url-loader,但是 url-loader 是转换成 base64,可能导致体积过大,应该在 options 里面设置 limit 和 fallback。

优化

  1. optimization 拆分多 chunk
  2. terser-webpack-plugin parallel
  3. babel-loader cacheDirectory
  4. hard-source-webpack-pluginresolve
  5. resolve.modules
  6. externals CDN
  7. dll 缓存公共库

原理

算法

链表、树、图、动态规划

Vue

生命周期

通信

Vuex

Nuxt

错误上报

Sentry

Promethus

项目

Admin、权限系统、H5 项目

其他

性能优化

图片优化

雪碧图、webp、base64、图片懒加载

首屏优化

DNS 预解析、资源预加载、只加载关键资源、资源懒加载、服务端渲染、

其他优化

规范

利用 husky(git的钩子)和 lint-staged(过滤暂存区文件,避免检查整个项目文件)来做commit前的代码处理,当然格式化校验还是用 eslint 和 prettier,一般是 eslint --fix 和 prettier --write。
Webpack、Jenkins、Docker

项目

Auth 设计、运维、监控,h5pay 访问量、h5ssr 设计、Jenkins 部署构建

目前还需要多补上的一个是性能优化,包括web和nodejs,一个是监控方面的,比如定位内存泄露。
一个是

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注