网站建设详细合同范本,docker wordpress 发布,企业网站大图,徐州软件外包前言
面试中除了问常见的算法网络基础#xff0c;和一些八股文手写体之外#xff0c;经常出现的一个问题就是#xff0c;你做过什么项目吗#xff1f; 面试官其实是想看看你做过什么有亮点的项目, 其实大家日常做的项目都差不多#xff0c;增删改查#xff0c;登录注册和一些八股文手写体之外经常出现的一个问题就是你做过什么项目吗 面试官其实是想看看你做过什么有亮点的项目, 其实大家日常做的项目都差不多增删改查登录注册弹窗等等所谓有亮点就是在这些实现功能的基础上在以下几个方面做出了探索和优化, 个人能力有限先聊这几个方面。
大数据量优化研发效率的提高研发质量的提高性能优化用户体验优化复杂 新场景…
我们以大家都做过的需求举例通过优化每个需求都可以做成有亮点的需求也就是所谓企业级的项目。
1、大数据量
想做出亮点首先做一些你周围同事做不到的需求首先就是数据量变大变得贼大虽然大部分场景遇不到但是挡不住骚包面试官喜欢问我们只聊面试。
1.1、课程页面增删改查
这种场景我们可以让数据量变成1W行大部分场景都是分页只有极端场景移动端无限滚动的商品页如果直接渲染1W行列表不出意外你的页面就要卡了比较常见的优化方案就是虚拟滚动就是只渲染你能看到的视窗中的几十行然后通过监听滚动来更新这几十个dom大致原理图如下 (网上找的。
解决方案出来后无论是Vue还是React解决方案都是类似的这里用ReactTypescript举栗子首先我们就得完成下面的任务为了简化场景先假定每个元素高度都一样。
可视区的高度固定 viewHeight clientHeight);每个列表高度height 固定);可视区域的数据索引start和end scrollTop / height);基于startIndex计算出offset偏移scrollTop - (scrollTop % height);渲染数据 监听滚动事件
代码大致如下
// 列表容器的domconst container useRefHTMLDivElement(null)// 开始位置const [start, setStart] useState(0)// 视图中的数据const [visibleData, setVisibleData] useStateVirtualProps[list]([])// 控制偏移量const [viewTransfrom, setViewTransfrom] useState(translate3d(0,0,0))useEffect(() {const containerDom container.currentconst viewHeight containerDom?.clientHeight || 500 // 视窗高度const visibleCount Math.ceil(viewHeight / HEIGHT) // 视窗内有几个元素const end start visibleCountsetVisibleData(list.slice(start, end))}, [])function handleScroll(e: React.UIEventHTMLDivElement, UIEvent) {const scrollTop e.currentTarget.scrollTop // 滚动的距离const containerDom container.currentconst viewHeight containerDom?.clientHeight || 500 // 视窗高度const start Math.floor(scrollTop / HEIGHT)const end start Math.ceil(viewHeight / HEIGHT)setVisibleData(list.slice(start, end))setStart(start)setViewTransfrom(translate3d(0,${start * HEIGHT}px,0))}稍微难一丢丢或者更骚包的面试官还会问如果每行都是一段文字不知道有多高呢其实解决方案也不复杂可以预估一个大致的高度然后渲染的时候获取实际dom的高度 缓存到数组 下面是伪代码由于位置数组是一个累加的数组其实还可以用二分算法继续优化给博友们留个作业吧。
// 预估高度60
const PREDICT_HEIGHT 60// 不定高数组维护一个位置数据
const [positions, setPosition] useState{ top: number;height: number }[]([])// 渲染数组之后更新positions数组
Array.from(listDom?.children).forEach((node, index) {const { height } node.getBoundingClientRect()// console.log(startindex, node.id)if (height ! positions[start index].height) {setPosition((prev) {const newPos [...prev]newPos[start index].height heightfor (let k index 1; k prev.length; k)newPos[k].top newPos[k - 1].top newPos[k - 1].heightreturn newPos})}
})
}, [visibleData])1.2、文件上传
其实就是数据量大了之后想继续让用户有比较好的交互体验就得不断地解决新问题 上传普通文件axios.post 进度条就搞定了如果想有亮点可以把文件的体积想的大一些比如2个G直接上传容易断我们需要断点续传就诞生几个新的问题
文件切片 秒传 暂停文件计算hash值就像文件的身份证号用来问后端有没有切片存在计算hash的卡顿 可以使用web-worker,时间切片,抽样Hash三种解决方案上传文件切片
2、研发效率的提高
程序员也是一种很贵的资源能提高他们的研发效率也算是给公司省钱了当然是亮点了但是每个人的开发能力不同我们可以从团队协作和多项目间复用两条路来寻求研发效率的提高
团队效率
最常见的就是统一规范js规范git 分支规范log规范项目文件规范并且用恰当的工具进行自动化校验和修正 然后是多项目间的复用率也能极大地提高效率
代码初始化可以封装成脚手架类似create-vite, 可以内置上面说的各种规范新项目直接启动代码研发效率 前端主要就是组件库和工具库utils封装代码联调效率 比如接口json自动生成Typescript接口类型等等比如mock数据工具代码上线效率发布部署部署结果同步到聊天群等等把日常重复的行为自动化 这部分也有大量的开源代码可以参考比如React生态的AntDesignVue生态的Antd-vue和element-ui, vueuse, 通用工具库参考lodash等等,这里就不赘述了 这也是大部分团队能有机会做开源的领域由于需要多个项目之间的共用所以对代码质量版本管理代码文档也会有更高的要求无形中也提高了我们的段位和能力 现在很火的rust生态可以极大地提高前端编译的速度其实也无形中提高了开发者写代码时候的心情和效率比如webpack换成vitebabel换成swc还有现在很火的rspack都是努力让前端开发环境能有丝滑秒开的体验 还有一些非代码层面的协作效率比如敏捷看板高效开会代码review啥的不在本篇文章讨论范围之内先略过
3、研发质量的提高
质量的提高也是程序员上限的提高 这一部分其实也是一个大话题【重构】【整洁代码的艺术】【代码大全】等经典书籍数不胜数不过在前端这个比较蛮荒的领域能把自动化测试做好就已经非常难得了 业务性的页面写测试成本过高但是上面说的多项目之间共享的组件库工具库还是需要用测试来确保代码质量学会jest或者vitest写测试也是我们有机会参与热门开源项目的机会代码测试覆盖率也是一个项目质量高低的重要指标而且也是代码可维护性高的体现 你可以现在就尝试用vitest给你项目中写的工具函数 or组件库来点测试代码保驾护航把 除了代码层面的单元测试还有流程层面的比如code-review
4、性能的提高
天下武功唯快不破 如何让页面打开速度更快是一个永恒的话题性能优化第一课首先你就得知道页面性能几个常见的指标,FCP,TTI,LCP就像我们想提高游戏水平就得了解攻击力防御力这些参数的含义 前端优化可以先从两个方向开始
4.1. 更快的加载文件
首先前端工程化中的打包压缩就是减少了文件的体积和数量并且通过很好的文件缓存管理最大限度的利用浏览器的缓存达到更快加载文件的目的 文件体积里其实图片的格式选择和优化是大头jpg, png, webp的选择还有打包中图片的压缩都可以获得比较可观的体积收益静态资源还可以使用cdn继续提高加载文件的速度 还可以使用懒加载的思想减少首屏加载的文件数量也可以很好的提高文件加载的速度图片/路由懒加载现在在前端开发领域都是必备特性了快去手写一个lazy-load把 rollup带来的tree-shaking能力跟互联网公司裁员还挺像囧可以去除项目中的无用代码现在也成了前端工程化的标配这也是为什么我们要尽量向esm规范靠拢的原因之一而且静态分析还可以给我们带来一些额外的收益比如vite中的预打包等等 这些我们都可以在工程化环节使用工具or插件的形式存在所以学会定制webpack/vite的插件也成为前端架构师的必备能力之一 快去学起来把
4.2. 代码执行的更快
这里也很好理解执行的速度也是鉴定代码好坏的一个指标比如同样一个leftpad函数前面补齐字符如果这么写
function leftpad(str,length,ch){let len length-str.length1return Array(len).join(ch)str
}
console.log(leftpad(hello,10,0))
相比于我们用二分法位运算的优化思路的写法
function leftpad2(str,length,ch){let len length-str.lengthtotal while(true){// if(len%21){if(len 1){totalch}if(len1){return totalstr}ch chlen len 1// len parseInt(len/2)}
}
console.log(leftpad2(hello,10,0))console.time(leftpad)
for(let i0;i10000;i){leftpad(hello,1000,0)
}
console.timeEnd(leftpad)console.time(leftpad2)
for(let i0;i10000;i){leftpad2(hello,1000,0)
}
console.timeEnd(leftpad2)❯ node leftpad.js
00000hello
00000hello
leftpad: 51.97ms
leftpad2: 2.077ms数据量越大性能差距就越大数据量是1W的时候性能有25倍的差距当然也可以看出来算法和数据结构对前端的必要性对不同的场景选择合适的算法or数据结构也是高级前端的必备能力 不同的框架内部也有不同的性能优化方式减少组件不必要的rerender减少浏览器的重绘回流减少页面内部的dom操作等等经典的优化方式 就不赘述了 还有按需执行代码的思想比如vue3种的静态标记只有dom种的动态部分需要参与计算diff静态的dom会直接略过 还有astro,nuxt3这种ssr框架中的岛屿架构就是只对页面中的动态组件进行js激活都是按需思想的表达
5、复杂场景
一些天生复杂的场景或者是前端新兴的领域或者热门的领域面试官也比较喜欢这个方向就比较多了以后有机会展开详细说说
很火的低代码搭建平台文档技术 在线officenotion笔记图形学figma白板canvas3D 可视化游戏webglapp、桌面端flutter、rn、elecrton更多未来的可能性…
6、不要陷入成长陷阱
写了这么多我们要无限进步但是不要陷入低水平的成长陷阱中也就是我们要努力学会通用技能而不是单纯的招式。 比如以前浏览器混战的时候我有花了很多时间研究ie6/7/8的兼容性问题并且感觉自己进步很大但是浏览器兼容是一个特定混乱时期的问题现在回头看看那些兼容性的写法对于现在的我毫无积累 我们要花更多的时间学习能够对我们有积累效果的技能现在webpack和vite是工程化领域混乱发展的时期过于关注api的使用以后有一个工具统一这个领域后你现在努力学习的工程化工具技能跟当年的ie6兼容性一样都被历史埋了。 可以试着学习webpack和vite内部的原理学习他们内部优化的思想怎么收集文件的依赖关系怎么实现模块化怎么实现loader和plugin机制扩展自身怎么实现高效的热更新等等这些才是能够帮助我们对未来有积累的技能。 少学api多研究点问题和本质。