说说你最近的项目
- 记叙文六要素:时间、人物、地点、起因、经过、结果;
- 时间:研发周期;
- 人物:团队成员、分工、我负责那几个模块;
- 起因:项目背景、项目的用户是谁、用户能用这个App干嘛、基本业务逻辑描述;
- 经过:我负责哪几个模块,目前处于何种状态;
- 结果:耗时多久上线、目前处于何种状态;
- 项目亮点:最好有并且输出10分钟;
你负责哪几个模块?
- 先下载一个业务及其相近的App在自己手机上;
- 对着该蓝本App玩烂、充分脑补,而不是对着空气脑补;
- 该蓝本App的各种菜单、导航、页面跳转按钮...就是所谓【模块】;
- 信手一划拉就有十几个模块备选(不要来来回回就是登录、网络通信、路由跳转...)
- 从以上几个模块中找几个你最能脑补出东西的模块来,号称是自己做的;
讲讲XX模块的实现细节
- 业务功能是什么?事先玩透、脑补透;
- 静态组件布局 + 网络通信获取数据 + 动态渲染 + 时间交互 + 后期优化;
- 静态布局部分:核心组件,给核心组件传递的主要props与callback(组件与通信);
- 网络通信:axios三层封装 + vuex/pinia/redux的数据缓存;
- 事件交互:可能有基于antd/elementPlus的二次封装(初中级)、自定义组件库(中高级);
- 后期优化:性能优化 + 复用提取(Vue和React如何复用逻辑);
为每个模块实现准备一些物料
- 二次封装的组件若干(有明确的的名字与逻辑)
- 自定义Hook若干
- 自定义指令若干
- HOC/RenderProp若干
有什么亮点?
- 性能方面:性能方面:性能优化25条(简单:至少输出20分钟)
- 复用方面:mixin、自定义指令、自定义hook、HOC、RenderProp、自定义组件(二次封装/自定义组件库)(略难:尽量准备)
有什么难点?
- 不一而足,请为最近的两个项目各自准备一个难点;(至少输出20分钟)
怎么做优化?
- 性能方面:性能优化25条(简单:至少输出20分钟)
- 复用方面:mixin、自定义指令、自定义hook、HOC、RenderProp、自定义组件(二次封装/自定义组件库)(略难:尽量准备)
如何排查BUG?
- 多打log(解决了记得清除)
- 网络错误多看控制台中的网络项,善用其中的各种过滤器
- 看报错信息,先看一下日志结构,迅速找到重点:例如错误id、代码行号等
- 善用vscode的全局搜索功能,迅速定位关键词出现的位置
- 多提交,这样可以利用版本回退定位bug发生的阶段
- 依赖方面的错误,删除lock文件,删除node_modules,重新执行
npm i试一下 - 重启开发服务器、重启vscode、重启电脑
- 百度、掘金、烂笔头
- 实在搞不定就先搞别的,有时候做到后面会突然获得灵感
日常开发中遇到过哪些问题?
-
项目跑不起来,依赖有问题(特别是哭的版本兼容性问题);
解决方案:删除依赖分析文件package.lock、node_modules,重新执行npm i
-
JS项目拿TS重构,不知道原始入参的类型,前期可以先any,后期追源码;
-
Git的公共文件,忌讳重名、移动位置、删除等操作;
-
......
命令行工具
- node版本切换/源切换:nvm/nrm
- mock数据:json-server,fast-mock
- 兼容性检查:canluse + caniuse-cmd
npm install -g caniuse-cmd
caniuse fetch
- 删除文件/文件及:rimraf
npm i -g rimraf
rimraf ./node_modules
从数据中过滤掉不需要的字段后形成JSON
const info = {
name: 'qxy',
age: 18,
friends: ['tom','bob']
}
// 在info的地址中将age覆盖为undefined
Object.assign(info, {friends: undefined})
// JSON的特性:不识别undefined
console.log(JSON.stringify(info))
// 返回:{name:'qxy, age:18}
如何处理海量/大量数据?
- 前后端协同处理,让后端数据接口支持分页获取数据;
- 考虑手动缓存数据 + 重构服务端接口;
- 懒加载:Suspense + lazy;
- 长长的大列表,内存里永远只留3屏数据【当前屏】+【上一屏】+【下一屏】;上上屏/下下屏的数据直接设置为null等待垃圾回收器去缓存;有一个库叫做betterScroll实现了该逻辑;
白屏问题
- 正常使用异步的话,就不会阻塞渲染
- 本质上是渲染被阻塞了(数据没回来,数据量太大);
- Nuxt/Next收评使用服务端渲染
首屏渲染优化
-
代码层面
- 组件库的按需引入
- 路由的懒加载
- 使用服务端SSR,直接由服务端返回渲染好的HTML
- 事件防抖节流,减少事件处理次数
- 减少DOM层级
- 减少DOM渲染次数(批量渲染documentFragment,差量渲染Vue/React)
-
通信层面
- 缓存网络数据在localStorage里或vuex/pinia/redux里,减少请求次数
- 小图片直接使用base64以减少网络请求次数
- 使用HTTP协议的强援,服务端给更新频率低的数据一个较长的缓存时间
- 从CDN或静态资源服务器去获取图片、js、css、图标字体等静态资源
-
打包层面
- 对图片进行物理压缩,如在线压缩工具TinyPNG
- 打包时对HTML、CSS、JS进行压缩处理
- 开启Gzip压缩
- 合理分包,将第三方包、轮子包、业务代码包分开,这样在前端版本升级时,往往还需要更新业务代码包,而第三方包和轮子包由于内容未变导致hash未变,因此直接被服务端视为304,从而直接使用本地缓存;
- 打包时开启Tree-Shaking,摇掉无用代码,减少包体积
- 从HTML中抽离CSS文件,以便单独下载与缓存
小程序的微信授权流程(用微信账号登录自家服务器)
- 在小程序端wx.login()得到登录码code
- 小程序请求自家的登录接口,携带登录码code
- 自家服务器请求微信服务器,使用appid + appSecret + code 换回 session_key与openid
- 自家服务器将session_key与openid重新换算为自家的登录信息(如token)
- 小程序在后续请求自家服务器的过程中都携带token,自家服务器就知道小程序已经登录过了
前端权限控制
- 登录成功后,服务端返回该用户的角色/权限
- 可以将该角色/权限等级数据存储在全局(例如全局状态管理)
- 路由层面A计划-动态生成路由表:根据该用户的等级动态添加它有权访问的路由(一旦用户访问自己无权访问的路由时命中404)
- 路由层面B计划-路由守卫:使用路由守卫,当用户越权的路由时一脚踹到登录页
- 界面层面A计划-条件渲染:根据用户的权限条件渲染它能访问的link、组件、具体元素
- 界面层面B计划-封装:
- vue中可以自定义指令如
v-auth="3",当用户的等级不足3级时将该按钮disabled调或隐藏掉 - React中可以使用HOC实现例如
WithCustomAuth(MyButton,3)在返回JSX的时候使用条件渲染
function withCUstomAuth(Com,level){ function Parent(props){ authFromRedux >= level ? <Com{...props} /> : <a href="/login">登录</a> } } - vue中可以自定义指令如