目录
浏览器缓存机制前端缓存如何解决浏览器的缓存问题为什么操作 DOM 慢插入几万个 DOM,如何实现页面不卡顿?什么是阻塞渲染?在不考虑缓存和优化网络协议的前提下,考虑可以通过哪些方式来最快的渲染页面,也就是常说的关键渲染路径,这部分也是性能优化中的一块内容。get,post,put,delete,patch的区别前端性能优化项目性能优化常用的http状态码如何进行项目自测如何修复紧急线上bug前端如何做信息攻防在微信支付中如何防止用户重复提交(在请求延时的情况下)token怎么处理,以及怎么验证http 2.0 新特性跨域请求是怎么理解的?Post和get的区别是怎么理解的?vue中的ajax,用于向后台发起请求
浏览器缓存机制
缓存可以说是性能优化中最简单的一直优化方式,它显著的减少了网络传输所带来的损耗
对一个数据请求来说,分为三步:网络请求,后端处理,浏览器响应!我们可以借助浏览器缓存来实现第一步,第三步的性能优化!
比如说发起发起网络请求后,之后直接拿缓存的数据,或者之后,发起请求后,发觉前端数据与后端数据一致时,则不需要在返回新的数据,这就减少了数据响应!
浏览器缓存机制
缓存位置缓存策略实际场景应用缓存策略
缓存位置:
缓存位置分为四种,并且拥有优先级,当依次查找缓存且都没有命中的时候,才会去请求网络
Service WorkerMemory CacheDisk CachePush Cache网络请求
缓存策略:
强缓存和协商缓存,并且缓存策略都是通过设置 HTTP Header 来实现的。
强缓存
前端缓存
前端缓存分为两种:http缓存 浏览器缓存
http缓存
http缓存是http请求传输时用到的缓存,主要是在服务器代码上设置的强缓存(exprires等) 和 协商缓存 浏览器缓存
浏览器缓存则是前端开发中js所设置的缓存浏览器缓存有 localStorage sessionStorage cookie 等
缓存可以说是性能优化中简单高效的一种优化方式了。一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。
https://www.jianshu.com/p/256d0873c398
如何解决浏览器的缓存问题
鼠标按住 刷新的箭头 (左右箭头的右边)浏览器的 三个竖直的三个点=> 更多工具=>清除缓存newWork => Disable给发起请求的url后面拼接一个时间戳 => 随机字符串或者随机数!
为什么操作 DOM 慢
因为 DOM 是属于渲染引擎中的东西,而 JS 又是 JS 引擎中的东西。当我们通过 JS 操作 DOM 的时候,其实这个操作涉及到了两个线程之间的通信,那么势必会带来一些性能上的损耗。操作 DOM 次数一多,也就等同于一直在进行线程之间的通信,并且操作 DOM 可能还会带来重绘重排的情况,所以也就导致了性能上的问题。
插入几万个 DOM,如何实现页面不卡顿?
虚拟滚动(virtualized scroller)。
这种技术的原理就是只渲染可视区域内的内容,非可见区域的那就完全不渲染了,当用户在滚动的时候就实时去替换渲染的内容。
什么是阻塞渲染?
首先渲染的前提是生成渲染树,所以 HTML 和 CSS 肯定会阻塞渲染。如果你想渲染的越快,你越应该降低一开始需要渲染的文件大小,并且扁平层级,优化选择器。然后当浏览器在解析到 script 标签时,会暂停构建 DOM,完成后才会从暂停的地方重新开始。也就是说,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的原因。
在不考虑缓存和优化网络协议的前提下,考虑可以通过哪些方式来最快的渲染页面,也就是常说的关键渲染路径,这部分也是性能优化中的一块内容。
当发生 DOMContentLoaded 事件后,就会生成渲染树,生成渲染树就可以进行渲染了,这一过程更大程度上和硬件有关系了。
从文件大小从 script 标签使用来考虑从 HTML CSS 的代码书写来考虑从 需要下载的内容是否需要在首屏使用上考虑
get,post,put,delete,patch的区别
RESTful => 接口规范
get:查询 (不要涉及到数据的操作) => req.querypost:增加 (以请求体的方式传递数据) => req.paramsput/patch:修改 (以请求体的方式传递数据)delete:删除 (请求体的方式发起请求 { data: 要传递的数据 })
前端性能优化
1 请求合并2 图片转化为base643 节流4 防抖5 减少css 这样的引入 @import 这样会造成额外的请求6 使用缓存7 减少重定向8 代码的压缩 合并9 使用CDN10 按需导入11 减少回流和重绘12 采用webpack的对上述的优化!
项目性能优化
性能优化
按需加载
路由的懒加载模式,Home首页采用一进入页面就加载的方式导入,然后其他的则是采用路由懒加载的模式UI框架的按需加载方式
代码质量
Eslint
http请求优化
合并压缩,就是同一个页面的相同请求,合并为一个请求
图片优化
合并和压缩,小的img可以转化为base64大小缓存:针对静态资源(图片、css,js)
更新问题件如何避免缓存:添加时间戳 xxx.js?t=11234366345
SSR
服务器端渲染,首页采用服务器端渲染较为合适,有利于seo优化!
服务器压缩:
vue.config.js中配置 devServer:{ compress:true}
…
UEO(用户使用产品过程中的主观感受)
界面友好性操作便捷性增加用户粘性…
SEO(让页面对搜索引擎更友好)
语义化标签关键字分布热搜(原创)友情链接…
安全性优化
加密解密
常用的http状态码
100
200
200 成功
300 -> 重定向方面的问题
301 永久重定向302 临时重定向304 缓存造成的问题
400 -> 请求错误,权限问题
403 无权限访问404 无法找到该页面
500
500 服务器错误
如何进行项目自测
测试用例
如何修复紧急线上bug
hotfix紧急修复bug分支
把master代码合并到hotfix分支上,然后hotfix上修改,测试完成后,就在上线!
前端如何做信息攻防
xss -> 跨域脚本攻击
利用服务器对客户端的信任进行攻击防守:
对用户输入进行过滤(对应script标签过滤掉)v-html(使用v-pre 输出结构)对输出进行处理 csrf -> 请求伪造
原理:利用用户对服务器的信任进行攻击防范:
对get请求不对数据的修改不让第三方网站访问cookie阻止第三方网站请求接口请求携带token值
在微信支付中如何防止用户重复提交(在请求延时的情况下)
订单状态法
步骤: 1、查询订单支付状态 2、如果已经支付,直接返回结果 3、如果未支付,则支付扣款并且保存流水 4、返回支付结果
token怎么处理,以及怎么验证
Token实际就是在计算机身份验证中的令牌(临时)的意思。 当前端向后端发起数据请求的时候,后端需要对前端进行身份验证,但是我们又不想每次都输入用户名和密码,这是就需要一个标识来证明自己的身份,这个标识就是token。 基于Token的身份验证流程 客户端使用用户名和密码请求登录 服务端收到请求,验证登录是否成功 验证成功后,服务端会返回一个Token给客户端,反之,返回身份验证失败的信息 客户端收到Token后把Token用一种方式存储起来,如( cookie / localstorage / sessionstorage / 其他 ) 客户端每次发起请求时都会将Token发给服务端 服务端收到请求后,验证Token的合法性,合法就返回客户端所需数据,反之,返回验证失败的信息
http 2.0 新特性
二进制分帧 首部压缩 流量控制 多路复用 请求优先级 服务器推送
https://juejin.im/post/6844903545532071943
跨域请求是怎么理解的?
所谓跨域请求,就是浏览器的安全策略影响,阻止一个域的js脚本对另外一个域的内容进行交互,来实现浏览器的安全性同源策略:
同源策略就是同域名,协议,端口一致的时候,就是同一个域名,只要三者之一出现不同,那么就会出现跨域! 跨域的解决方案:
corsjsonp服务器代理
Post和get的区别是怎么理解的?
post
请求参数是放在请求体之中理论上讲,POST是没有大小限制的 ger
请求参数拼接在url中的?后面GET方式提交的数据最多只能是1024字节 区别:
GET能被缓存,POST不能GET回退浏览器无害,POST会再次提交请求(GET方法回退后浏览器再缓存中拿结果,POST每次都会创建新资源)
vue中的ajax,用于向后台发起请求
特点: 从浏览器中创建XMLHttpRequests 从node.js创建http请求 支持Promise API 拦截请求和响应 转换请求数据和响应数据 取消请求 自动转换json数据 客户端支持防御XSRFpromise: 一个对象用来传递异步操作的信息 promise的出现主要是解决地狱回调的问题,无需多次嵌套 本质:分离异步数据获取和业务拦截器分为请求拦截器和响应拦截器
请求拦截器 axios.interceptors.request.use(function(config){ return config; },function(error){ return Promise.reject(error); });响应拦截器 axios.interceptors.response.use(function(response){ return response; },function(error){ return Promise.reject(error); });