项目问题~

栏目:小说资讯  时间:2023-08-11
手机版

  一、 国际化(i18n)北京外国语大学27种语言? ? vue-i18n + i18n Ally? +?xlsx +?vue-json-excel

  1. 开始开发用zh-cn.json的文件写完页面逻辑

  2. 通过公司免费的api接口将每个字段翻译成27种语言(生成一个大对象)

  3. 使用vue-json-excel读取json数据,导出一个excel文件

  4. 让内容组同事修正翻译,通过腾讯文档同步内容,改完导成本地

  5. 通过 xlsx 插件xlsx文件内容读出来,FileSaver 生成js文件

  但是有个问题,后续添加的翻译,不能使用i18n Ally翻译了,它是全量翻译,会覆盖同事手动翻译的内容,只能使用公司翻译的接口,把新增的字段翻译(拿到zh-cn文件字段,对比en.json文件没有的就是新增的,翻译完第一个将所有新增的字段放在一个数组里边)将翻译内容写入json文件。后端的返回信息也需要翻译,在自己封装的接口请求方法加个变量,每个接口都需要传语言字段

  国际化翻译 Vue-i18n 的架构组织和 $t 的原理,当遇到插值对象的时候,需要进行 parse 和 compileVue-i18n 通过转义字符避免 XSS通过观察者模式对数据进行监听和更新,做到无刷新更新页面全局自定义指令和全局组件的实现 二、大文件分片上传,断点续传

  1.通过el-upload组件拿到binary类型文件

  2.校验文件不能超高20G,通过请求接口盘点磁盘大小,是否够存储文件

  3. 直接将文件抛给webworker,file.slice()进行分片5M每片,用spark-md5给每一片加密(md5是一种信息摘要算法,它是一段数据,即128bit的由“0”和“1”组成的一段二进制数据。无论原始数据长短是多少,其MD5值都只是128bit)

  4. 传送index、hash、file、size、total

  5. 断点续传,刷新或者退出前端会停止上传,再次上传拿到MD5,后台先查有没有这个,有的话返回上次的index,前端从index继续上传。

  6. 每一片5M传输最合理(nginx默认的上传文件大小是有限制的,一般为2MB,修改client_max_body_size 30M),oss存储有自动清理垃圾文件机制。调用的oss的api

  7. nginx默认限制请求1M,修改client_max_body_size 20M;

  https://segmentfault.com/a/1190000021367378

  JS 实现流式打包下载 - 知乎JS前端批量下载大文件并打包zip(StreamSaver.js)_斗战圣佛91的博客-CSDN博客_js批量下载文件生成zip

  responseType: 'arraybuffer'(请求arraybuffer文件流)

  Service worker?本质上充当 Web 应用程序、浏览器与网络(可用时)之间的代理服务器。这个 API 旨在创建有效的离线体验,它会拦截网络请求并根据网络是否可用来采取适当的动作、更新来自服务器的的资源。

  StreamSaver.js 包含两部分代码,一部分是客户端代码,一部分是 Service Worker 的代码(对于不支持 Service Worker 的情况,作者在 GitHub Pages 上提供了一个运行 Service Worker 的页面供跨域使用)。

  在初始化时客户端代码会创建一个??并将可写入的一端封装为??暴露给外部使用,在脚本调用??写入文件片段时,客户端会和 Service Worker 之间建立一个?,并将之前的??中可读取的一端通过??传递给 Service Worker。Service Worker 里监听到通道的??事件时会生成一个随机的 URL,并将 URL 和可读取的流存入一个 Map 中,然后将这个 URL 通过??传递给客户端代码。

  客户端接收到 URL 后会控制浏览器跳转到这个链接,此时 Service Worker 的??事件接收到这个请求,将 URL 和之前的 Map 存储的 URL 比对,将对应的流取出来,再加上一些让浏览器认为可以下载的响应头(例如?)封装成??对象,最后通过??返回。这样在当客户端将数据写入??时,经过 Service Worker 的流转,数据可以立刻下载到用户的设备上。这样就不需要分配巨大的内存来存放 Blob,数据块经过流的流转后直接被回收了,降低了内存的占用。

  所以借助 StreamSaver.js,之前下载图片的流程可以优化如下:JSZip 提供了一个??的接口来模拟流的实现,所以我们可以调用??方法以小文件块的形式接收数据,每次接收到数据时数据会写入 StreamSaver.js 的 writer,经过 Service Worker 后数据直接被下载。这样就不会再像之前那样在生成 zip 时占用大量的内存空间了,因为 zip 数据在实时生成时被划分成了小块并迅速被处理掉了。

  下载完成流---->postmessage发送给serviceWorker------>onmessage事件内部随机生成一个URL,存在map中 ------> 通过postMessage发送给客户端?----> 客户端通过跳转这个url------->serviceWorker拦截请求------>将对应流拉取出来,加上响应头,下载线程拿到响应,开启流式下载

  readableStream .pipeTo(fileStream) .then(() => console.log("done writing"))

  三、主题切换

  1. 给ued组开发了一个定义主题颜色的系统,table表格展示每一个主题色的属性,通过FileSaver保存生成scss文件,供前端使用 ,新增主题,修改主题只需要UI去修改颜色,生成新的scss文件供前端使用。

  2. table是一个数组,一列就是一个主题,每个主题有多个属性,最后点确认,生成一个js文件存放这次生成的数组,供下次使用。还要将数组对象拼接成字符串,输出成scss文件。

  a = { '--theme-color': "#eee", '--theme-background': "#333" } ->

  a = '.a {--theme-color: "#eee";--theme-background: "#333"}'

  3. 基础常用的样式的样式?通过@mixin,@extend减少重复

  4. 通过动态设置html的class实现切换主题

  5. 还有一个项目用户需要自定义主题颜色,自己选择每一个模块的颜色(可以颜色面板选择)

  四、网盘存储、资源管理

  1. 资源分片上传

  2. 大文件下载,批量下载(生成一个zip)

  3. 资源、文件夹的分享、复制、移动、收藏、下载、公开、编辑、删除

  4. 视频资源支持打点、剪切、视频融合、字幕、分享、字幕转写、添加笔记、无效片段处理,COR识别、编辑字幕、字幕翻译、词云、图文模式、多路视频随意切换、局部全屏(所有全屏)

  5. 文件预览。文档,图片,视频 ,音频

  6. 直播,字幕(实时语音翻译,websocket拿到数据展示),实时语音聊天(类似腾讯课堂,但是支持多路和多路全屏,显示实时语音翻译,)

  五、大屏数据展示,移动端

  大屏适配

  移动端适配:rem是相对长度单位。相对于根元素(即html元素)font-size计算值的倍数的一个css单位,默认1rem = 16px,不好计算,重新设置比率? ?html{font-size: 100px;} 1rem = 100px

  等比缩放

  vw,wh是 1/100宽高,兼容性不太好

  em:相对于父元素的大小,一个改变后边子元素也得变

  postcss-plugin? pxtovw? 实现px转化为vw

  六、弹幕问题

  通过css3

  transition: -webkit-transform 0s?linear?0s;(过度效果时间,匀速,延迟)

  transform: matrix(1, 0, 0, 1, -406.081, 0);(矩阵变换,线性代数,运动就是在线性空间的一种变换,transform: matrix(a,b,c,d,e,f);,x'=ax+cy+e y'=bx+dy+f)

  animation: 0s?ease?0s 1 normal none running none;(动画: 动画-名 动画-持续时间 动画-时间控制函数 动画-延时 动画-重复次数 动画-方向 动画-填充方法 动画-播放状态;)

  will-change: transform, opacity;(和将动画交给GPU,硬件加速,属性允许你提前告知浏览器你可能会对一个元素进行什么样的改变,这样它就可以提前设置适当的优化,该元素会被移动到属于它自己的“图层”,在那里它可以独立于页面的其他部分进行渲染。避免其他元素的重排和重绘)

  stroke-width:1px;stroke: rgba(0,0,0,.5); 文字描边

  

  直播半屏,显示右侧聊天室,网页全屏显示弹幕功能

  录播功能2分钟根据当前时间请求一次最新的弹幕,轮循,websocket常

  直播使用websocket(弹幕+实时字幕),录播30s根据播放时间获取一次弹幕

  流程:添加新弹幕到等待队列、寻找合适的轨道、从等待队列中抽取弹幕并放入轨道、整体渲染、清空。

  分为三部分:舞台、轨道、弹幕池

  舞台是整个弹幕的主控制,它维护着多个轨道、一个等待队列、一个弹幕池

  弹幕池:[[1,2,3],[4,5,6]](new?WeakMap()?)? ?等待队列:[7,8,9,10]

  获取每一行的宽度,找到最小的给他添加新的弹幕,(先填充满上边的一行)

  transition:1s linear 0s, 速度是transition的时间控制的

  追及问题,设置最大速度为两倍,计算两个之前的距离

  丢弃排队时间过长的弹幕大神

  -webkit-mask-image:url() //防止弹幕遮挡人物

  自定义指令:水印(手机端人名字水印和视频水印,mutationObserver检测dom变化,执行生成水印方法,防止人为删除dom),懒加载,按钮节流,输入防抖,拖拽

  前端优化

  1、减少请求量

  雪碧图,iconfont、spritesmith(生成png和scss)、nginx开启http2(server {listen 10.10.10.10:443 backlog=20480 http2 ssl;ssl_async on;)、图片懒加载、虚拟列表、

  2、减小文件大小

  ?? ? 路由懒加载,组件按需加载、开启zip(CompressionPlugin)、压缩css(css-minimizer-webpack-plugin)、压缩图片(image-webpack-loader / webp )、提取公共库(SplitChunksPlugin)、?移除无用代码、减少不必要的 cookie

  3、加快请求速度

  ?? ??预解析DNS(<link rel="dns-prefetch" href="xxx.com"> ,官网配置子应用)、CDN 分发、nginx负载均衡、使用??提前建立连接、webpackPrefetch(预加载资源文件)、CDN 托管静态资源 + HTTP 缓存(强缓存,协商缓存)

  4.?交互层面:减少回流/重绘(使用??开启??加速、减少对??进行频繁操作、使经常变动的元素脱离文档流)、防抖/节流

  5.?Web Worker

  是单线程的,如果存在需要大量计算的场景(如视频解码),?线程就会被阻塞,甚至浏览器直接卡死。

  可以使脚本运行在新的线程中,它们独立于主线程,可以进行大量的计算活动,而不会影响主线程的??渲染,但不能滥用??。

  6、虚拟列表

  最常用的还是?分页加载?的方式:

  基于??列表的渲染,随着加载数据的增多,对应的??节点也会增多,达到某个限制页面一定会发生卡顿

  虚拟列表?核心就是固定渲染的??数,通过动态切换数据内容实现视图的更新,并保证文档中真实??的数量不随着数据量增大而增大(其实和??分页很像,但它支持滚动)。

  7.?大文件分片上传、下载

  8. 前端文件导入/导出

  ? Minify把 CSS 和 JS 压缩和削减(Minify:去掉空格回车符等),以及把多个CSS,JS文件整合到一个文件里。

  4、缓存

  ? ① HTTP协议缓存请求(ng开启强缓存,协商缓存)

  ? ② 离线缓存 manifest(webpack-manifest)

  ? ③ 本地缓存 localStorage

  补充知识:

  ? GET请求可以缓存,POST请求不能缓存。GET请求后退/刷新无害,POST后退/刷新则会致使重新提交数据

  4、渲染

  ? ① JS优化,如防抖、节流、事件委托、减少重排重绘等。

  ? ② CSS优化,如提取公共样式减少代码量、减少选择器嵌套层数、精灵图等。

  ? ③ 服务器端渲染

  ? ④ 使用Web Workers

  ? ⑤ CSS写在文件头部,JS写在文件底部。

  img/css这些文件都可以用强缓存。通过更改文件名的方式来获取最新的数据,index.html就要用协商

  FP : 首次绘制(白屏时间)

  FCP:首次内容绘制(绘制第一个元素)

  LCP:首屏时间(最大内容绘制,应在2.5s完成)mutationObserve*dom树的层级计算一个权重,页面元素一直在变化,取一个相对的比较大的变化作为首屏渲染截止时间

  FID:第一次输入事件延迟

  CLS:累积布局偏移

  浏览器perfermace观察各项指标,但是不直观

  可以用lightHouse观察(各项指标性能)

  会在项目部署的初期,通过设置变量控制各个性能指标的开启,监听load事件,load完成以后将各项指标上传,前端人员进行分析,运行平稳以后,可以把一些dns,tcp的检测给去掉。

  axios取消请求CancelToken = axios.CancelToken

  HTTP?响应代码指示服务器正在根据发送包括请求头的消息的客户端的请求切换到的协议。

  服务器在此响应中包含一个响应标题,指示它切换到的协议。该过程在文章“协议升级机制”中有详细描述

  1.?可以捕捉语法错误,也可以捕捉运行时错误,可以拿到出错的信息,堆栈,出错的文件、行号、列号

  2. 当一项资源(如图片或脚本)加载失败,加载资源的元素会触发一个??接口的??事件,并执行该元素上的?处理函数

  window.addEventListener('error', function(event) {

  // onerror_statements

  })

  3.?在vue中使用errorHandler?或者生命周期钩子?errorCaptured

  app.config.errorHandler = (err, vm, info) => {

  // 处理错误

  // `info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子

  }

  4.?请求异常在响应拦截器中处理? 在axios中拦截

  5.?promise异常使用Promise Catch,在全局增加一个对??的监听,用来全局监听。使用方式:

  6.?崩溃和卡顿

  1.利用??对象的??和??事件实现了网页崩溃的监控(在页面加载时(load 事件)在 sessionStorage 记录 good_exit 状态为 pending,如果用户正常退出(beforeunload 事件)状态改为 true,如果 crash 了,状态依然为 pending,在用户第2次访问网页的时候(第2个load事件),查看 good_exit 的状态,如果仍然是 pending 就是可以断定上次访问网页崩溃了!存在的问题:采用 sessionStorage 存储状态,但通常网页崩溃/卡死后,用户会强制关闭网页或者索性重新打开浏览器,sessionStorage 存储但状态将不复存在;如果将状态存储在 localStorage 甚至 Cookie 中,如果用户先后打开多个网页,但不关闭,good_exit 存储的一直都是 pending,完了,每有一次网页打开,就会有一个 crash 上报。)。

  2. 可以使用??来实现网页崩溃的监控

  (1).Service Worker 有自己独立的工作线程,与网页区分开,网页崩溃了,Service Worker 一般情况下不会崩溃;

  (2).Service Worker 生命周期一般要比网页还要长,可以用来监控网页的状态;

  (3).网页可以通过 navigator.serviceWorker.controller.postMessage API 向掌管自己的 SW 发送消息。

  基于心跳检测的监控方案:

  p1:网页加载后,通过 postMessage API 每 5s 给 sw 发送一个心跳,表示自己的在线,sw 将在线的网页登记下来,更新登记时间;p2:网页在 beforeunload 时,通过 postMessage API 告知自己已经正常关闭,sw 将登记的网页清除;p3:如果网页在运行的过程中 crash 了,sw 中的 running 状态将不会被清除,更新时间停留在奔溃前的最后一次心跳;sw:Service Worker 每 10s 查看一遍登记中的网页,发现登记时间已经超出了一定时间(比如 15s)即可判定该网页 crash 了 Sentry Init 初始化,读取配置的 Release 和 DSN 信息,然后将 Sentry 对象挂在到全局当代码在运行过程中发生错误时,往上抛出一个 Error 对象,会执行 TraceKit 重写的 window.onerror 方法如果是一个未捕获的 Promise 错误是,将执行重写的 window.onunhandledrejection然后使用网络请求上报到 Sentry 服务器,这里会用到配置时使用的 DNS 主应用需要安装乾坤,子应用有三个周期函数,bootstrap,mount,unmount

  原理?手写微前端qiankun框架,vue+react双重配置_进阶的巨人001的博客-CSDN博客

  1.监视路由变化

  2.匹配子应用

  3.加载子应用 (unmount(prevApp); 之前的应用需要先卸载)

  4.渲染子应用

  1.客户端渲染需要通过执行 js 来生成内容

  2.浏览器出于安全考虑, innerHtml中的 script 不会加载执行

  3.所以需要手动加载子应用的script,执行script中的代码,我们可以用eval或者new Function

  监听路由变化,hash的话是 onhashchange, history 监听?popstate、pushState、replaceState

  GitHub - lsh555/qiankun: 手写微前端qiankun框架,vue+react双重配置

  import-html-entry 里,也就是加载后的 js 就被包裹了一层

  function 包裹了一层,所以代码放在了单独作用域跑,又用 with 修改了 window,所以 window 也被隔离了。

  先查找要添加的应用是否有相应的属性,没有的话给子应用容器添加一个属性。然后遍历每个style标签,在每个style标签代码前面增加属性选择符,通过属性选择符+样式来确保样式不被重写

  div[data-qiankun="app-vue"]

  1.??props,主应用通过全局的mount生命周期传递props

  2.?initGlobalState(state)

  (1)onGlobalStateChange:注册 观察者 函数 - 响应 globalState 变化,在 globalState 发生改变时触发该 观察者 函数。

  (2)setGlobalState:设置 globalState - 设置新的值时,内部将执行 浅检查,如果检查到 globalState 发生改变则触发通知,通知到所有的 观察者 函数【深度监听的】

  (3)offGlobalStateChange:取消 观察者 函数 - 该实例不再响应 globalState 变化

  ==第一步:==首先需要在父应用中使用initGlobalState设置全局状态actions并导出供其他组件使用。

  ==第二步:==然后在main.js中引入actions实例并在注册子应用时通过props传递全局状态actions:

  ==第三步:==主应用中的组件要修改全局状态actions,就在此组件中引入actions实例

  ==第四步:==配置子应用的全局状态Actions,子应用中的全局状态必须要跟主应用中的全局状态变量属性名相同,比如主应用中全局状态变量为{project_id: “项目2”},则子应用中也需要保证在setGloabalState时也需要设定相同的变量名。

  然后在mounted的生命周期里注入actions实例:

  微前端qiankun框架的底层实现原理_veggie_a_h的博客-CSDN博客_qiankun原理

  微前端解决方案-qiankun实战及部署 - 简书

  

  1.?、?和??三者的权重依次减小,我们要想网页有好的排名,必须合理使用这三个标签。

  2.?搜索引擎是识别文字,而不识别图片的。就拿网站的Logo来举例子,用a标签包裹,设置背景图(京东)

  3.?使用语义化元素(禁止滥用H1标签)

  4.?利用??中的 alt 属性

  5.?设置?忽略跟踪,如果某个链接不需要跟踪,可以忽略,爬虫分给每个页面的权重是一定的

  6.?提高加载速度(减少重排和重绘)

  7.?扁平化网站结构(一个网站的结构层次越少,越有利于“爬虫”的爬取。模仿用户操作)

  8.?,,有的搜索引擎对,所以要保证重要内容被并且,重要内容不应该由 JavaScript 输出,因为“爬虫”没有办法读取 JavaScript ,同时也要少用 iframe ,因为“爬虫”一般不会去读取它里面的内容。

  客户端渲染 CSR

  服务器端渲染 SSR

  静态站点生成 SSG:缺点是内容可能过时,每次更改内容时都需要构建和部署应用程序。

  增量静态再生 ISR:ISR 是 SSG 的下一个改进,它定期构建和重新验证新页面,以便内容永远不会过时。适合电商,新闻类页面

  SSG和ISR都是next提出的

  适合高度动态的 Web 应用程序

  客户端渲染 CSR. : 典型代表:单页面应用,内容都是js动态渲染

  服务器端渲染 SSR : 在服务端获取数据组装页面,返回到浏览器是html,对服务器要求高,主要应用是交互多的页面需要seo的

  适合高度静态的web程序? 插件 PrerenderSPAPlugin

  静态站点生成 SSG: 在build的的时候就已经生成好静态页面,放在服务端的也是静态页面,博客,静态官网都非常合适

  增量静态再生 ISR:ISR 是 SSG 的下一个改进,它定期构建和重新验证新页面,以便内容永远不会过时

  原理:?就是利用 Chrome 官方出品的??工具,对页面进行爬取。

  在??构建阶段的最后,在本地启动一个??的服务,访问配置了预渲染的路由,然后将??中渲染的页面输出到 HTML 文件中,并建立路由对应的目录。

  所以预渲染的缺点除了需要插件支持以外,由于渲染是在打包阶段,如果页面上有实时更新的数据,则在渲染时显示的不是最新的数据。

  打包的时候就预先渲染页面,所以在请求到 index.html 就已经是渲染过的内容。

  可以看出,SSR 和 Prerender 的最大区别就在于,。

  vue-meta-info插件配置 title和meta

  公司官网用的就是?PrerenderSPAPlugin 生成的,每个页面一个目录。没用ssg是因为基于nuxt的ssg

  1. 如果页面无数据,或者是纯静态页面,建议使用 Prerender,这是一种通过预览打包的方式构建页面,也不会增加服务器负担,但其他情况并不推荐。如果页面数据请求多,又对 SEO 和加载速度有需求的,建议使用 SSR。

  2. 对于高操作需求的项目来说,CSR 可能更加适合,页面显示元素即绑定了操作,而 SSR 和 Prerender 虽然会提前显示页面,但此时页面元素无法操作,仍需要下载完 bundle.js 进行事件绑定才能执行。

  3. 客户端渲染中,用户的浏览器中永远只存在一个 Store,服务器端的 Store 是所有用户都要用的,共享Store是有问题的,需要为每个用户提供一个独立的 Store。

  4. vue的生命周期钩子函数中, 只有??和??会在服务器端渲染(SSR)过程中被调用,这就是说在这两个钩子函数中的代码以及除了vue生命周期钩子函数的全局代码,都将会在服务端和客户端两套环境下执行。

  在beforeCreate,created生命周期以及全局的执行环境中调用特定的api前需要判断执行环境。

  5. 在客户端到SSR服务器的请求中,客户端是携带有cookie数据的。但是在SSR服务器请求后端接口的过程中,却是没有相应的cookie数据的。因此在SSR服务器进行接口请求的时候,我们需要手动拿到客户端的cookie传给后端服务器。

  6. vue有两种路由模式,一种是hash模式,就是我们经常用的#/hasha/hashb这种,还有一种是history模式,就是/historya/historyb这种。因为hash模式的路由提交不到服务器上,因此ssr的路由需要采用history的方式

  https://yydatav.blog.csdn.net/article/details/119251135?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-119251135-blog-124731943.pc_relevant_3mothn_strategy_and_data_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-119251135-blog-124731943.pc_relevant_3mothn_strategy_and_data_recovery&utm_relevant_index=1

  Webpack?本质上是一个函数,它接受一个配置信息作为参数,执行后返回一个?compiler 对象,调用??对象中的?run?方法就会启动编译。?方法接受一个回调,可以用来查看编译过程中的错误信息或编译信息

  入口文件()被包裹在最后的立即执行函数中,而它所依赖的模块(、)则被放进了 对象中( 用于存放入口文件的依赖模块,)。

  Tapable?了!它是一个类似于 Node.js 中的?EventEmitter?的库,但更专注于自定义事件的触发和处理。通过 Tapable 我们可以注册自定义事件,然后在适当的时机去执行自定义事件。

  syncHook.tap("监听器3", (name) => { console.log("监听器3", name); });

  在 Webpack 中,就是通过??在??和??上像这样挂载着一系列,它就像是一座桥梁,贯穿着整个构建过程:

  当 Webpack 内部进行插件挂载时会执行??函数。我们可以在??方法中订阅各种生命周期钩子,当到达对应的时间点时就会执行。

  (1)搭建结构,读取配置参数

  (2)用配置参数对象初始化 对象

  (3)挂载配置文件中的插件

  (4)执行 对象的 方法开始执行编译

  (5)根据配置文件中的 配置项找到所有的入口

  (6)从入口文件出发,调用配置的 规则,对各模块进行编译

  (7)找出此模块所依赖的模块,再对依赖模块进行编译

  (8)等所有模块都编译完成后,根据模块之间的依赖关系,组装代码块

  (9)把各个代码块 转换成一个一个文件加入到输出列表

  (10)确定好输出内容之后,根据配置的输出路径和文件名,将文件内容写入到文件系统

  中的 (本次打包涉及到的文件)是用来做什么的?为什么没有地方用到该属性?

  这里其实是为了实现?Webpack 的 watch 模式:当文件发生变更时将重新编译。

  思路:对 里面的文件进行监听,当文件发生变化时,重新执行 函数。

  二十张图片彻底讲明白Webpack设计理念,以看懂为目的 - 掘金

  使用 webpack-dev-server (后面简称 WDS)托管静态资源,同时以 Runtime 方式注入 HMR 客户端代码;浏览器加载页面后,与 WDS 建立 WebSocket 连接;Webpack 监听到文件变化后,增量构建发生变更的模块,并通过 WebSocket 发送 hash 事件;浏览器接收到 hash 事件后,请求 manifest 资源文件,确认增量变更范围;浏览器加载发生变更的增量模块,jsonp请求拿到最新模块代码;Webpack 运行时触发变更模块的 module.hot.accept 回调,执行代码变更逻辑;done; 第一步,在 webpack 的 watch 模式下,文件系统中某一个文件发生修改,webpack 监听到文件变化,根据配置文件对模块重新编译打包,并将打包后的代码通过简单的 JavaScript 对象保存在内存中。

  第二步是 webpack-dev-server 和 webpack 之间的接口交互,而在这一步,主要是 dev-server 的中间件 webpack-dev-middleware 和 webpack 之间的交互,webpack-dev-middleware 调用 webpack 暴露的 API 对代码变化进行监控,并且告诉 webpack,将代码打包到内存中。

  第三步是 webpack-dev-server 对文件变化的一个监控,这一步不同于第一步,并不是监控代码变化重新打包。当我们在配置文件中配置了 devServer.watchContentBase 为 true 的时候,Server 会监听这些配置文件夹中静态文件的变化,变化后会通知浏览器端对应用进行 live reload。注意,这儿是浏览器刷新,和 HMR 是两个概念。

  第四步也是 webpack-dev-server 代码的工作,该步骤主要是通过 sockjs(webpack-dev-server 的依赖)在浏览器端和服务端之间建立一个 websocket 长连接,将 webpack 编译打包的各个阶段的状态信息告知浏览器端,同时也包括第三步中 Server 监听静态文件变化的信息。浏览器端根据这些 socket 消息进行不同的操作。当然服务端传递的最主要信息还是新模块的 hash 值,后面的步骤根据这一 hash 值来进行模块热替换。

  webpack-dev-server/client 端并不能够请求更新的代码,也不会执行热更模块操作,而把这些工作又交回给了 webpack,webpack/hot/dev-server 的工作就是根据 webpack-dev-server/client 传给它的信息以及 dev-server 的配置决定是刷新浏览器呢还是进行模块热更新。当然如果仅仅是刷新浏览器,也就没有后面那些步骤了。

  HotModuleReplacement.runtime 是客户端 HMR 的中枢,它接收到上一步传递给他的新模块的 hash 值,它通过 JsonpMainTemplate.runtime 向 server 端发送 Ajax 请求,服务端返回一个 json,该 json 包含了所有要更新的模块的 hash 值,获取到更新列表后,该模块再次通过 jsonp 请求,获取到最新的模块代码。这就是上图中 7、8、9 步骤。

  而第 10 步是决定 HMR 成功与否的关键步骤,在该步骤中,HotModulePlugin 将会对新旧模块进行对比,决定是否更新模块,在决定更新模块后,检查模块之间的依赖关系,更新模块的同时更新模块间的依赖引用。最后一步,当 HMR 失败后,回退到 live reload 操作,也就是进行浏览器刷新来获取最新打包代码。

  模块热更新的错误处理,如果在热更新过程中出现错误,热更新将回退到刷新浏览器

  需求描述:

  浏览器限制每次最多发出10个请求接口,总共有1000个待请求接口,每个接口的响应时间是随机的,要保证在某个接口请求成功之后立即请求下一个接口,保证当前并发度始终为10。

  代码的核心思路为:

  先初始化 limit 个 promise 实例,将它们放到 executing 数组中使用 Promise.race 等待这 limit 个 promise 实例的执行结果一旦某一个 promise 的状态发生变更,就将其从 executing 中删除,然后再执行循环生成新的 promise,放入executing 中重复2、3两个步骤,直到所有的 promise 都被执行完最后使用 Promise.all 返回所有 promise 实例的执行结果 ? ? ? 通过该函数实例化出来的对象都可以继承得到原型上的所有属性和方法

  原型对象默认有一个属性constructor ,值为对应的构造函数;另外,有一个属性__proto__,值为Object.prototype

  在JavaScript中万物都是对象,对象和对象之间并不是独立存在的,对象和对象之间有一定关系。

  通过对象__proto__属性指向函数的原型对象(函数.prototype)一层一层往上找,直到找到Object的原型对象(Object.prototype)为止,层层继承的链接结构叫做原型链(通过proto属性形成原型的链式结构,专业术语叫做原型链)

  flex-direction: 设置主轴的方向

  justify-content: 设置主轴上的子元素排列方式

  flex-wrap: 设置子元素是否换行

  align-content: 设置侧轴的子元素的排列方式(多行)

  align-items:设置侧轴上的子元素排列方式(单行)

  flex-flow:复合属性,相当于同时设置了flex-direction 和 flex-wrap

  flex:1 是 flex-grow, flex-shrink, flex-basis. 三个属性的简写,默认值为 0 1 auto。该属性有两个快捷值:auto(1 1 auto) 和 none(0 0 auto)。建议优先写 flex 属性,而不是写三个分离的属性,因为浏览器会自动计算其相关值。

  flex-grow 默认为0, 只能是正整数。即父元素有剩余空间也不放大元素。如果为 1,则把剩余空间的一份加给自己的宽度。

  flex-shrink 默认为1,只能是正整数。即父元素空间不足则按比例收缩。如果为 0,则不收缩

  flex-basis 默认为 auto, 即元素本身的大小。这个属性定义了在分配多余空间之前,元素占据的主轴空间,浏览器根据这个属性计算是否有多余空间。可以设置为和 width 和 height 属性一样的值,比如 220px,则元素占据固定空间。

  0 -?(未初始化)还没有调用send()方法

  1 -?(载入)已调用send()方法,正在发送请求

  2 -?(载入完成)send()方法执行完成,已经接收到全部响应内容

  3 -?(交互)已经接收部分数据。但若在此时调用responseBody和responseText属性获取部分结果将会产生错误,因为状态和响应头部还不完全可用。

  4 -?(完成)响应内容解析完成,可以在客户端调用了

  readyState为3的时候把网线拔了,可能只接收到部分信息

  切换本地npm源?(可使用nrm?源管理工具)

  npm config set registry=http://verdaccio.iflyhed.com/

  本地登录

  3.使用安装? ? npm i fif-base

  4.?上传包

  angular 的数据绑定采用什么机制?详述原理

  脏检查机制。

  双向数据绑定是 AngularJS 的核心机制之一。当 view 中有任何数据变化时,会更新到?model?,当 model 中数据有变化时,view 也会同步更新,显然,这需要一个监控。

  原理就是,Angular 在?scope?模型上设置了一个监听队列,用来监听数据变化并更新 view 。每次绑定一个东西到 view 上时 AngularJS 就会往 $watch 队列里插入一条 $watch ,用来检测它监视的 model 里是否有变化的东西。当浏览器接收到可以被 angular context 处理的事件时, $digest 循环就会触发,遍历所有的 $watch ,最后更新 dom。

  在 newVue() 后, Vue 会调用 _init 函数进行初始化,也就是init 过程,在 这个过程Data通过Observer转换成了getter/setter的形式,来对数据追踪变化,当被设置的对象被读取的时候会执行 getter 函数,而在当被赋值的时候会执行 setter函数。

  当render function 执行的时候,因为会读取所需对象的值,所以会触发getter函数从而将Watcher添加到依赖中进行依赖收集。

  在修改对象的值的时候,会触发对应的 setter, setter通知之前依赖收集得到的 Dep 中的每一个 Watcher,告诉它们自己的值改变了,需要重新渲染视图。这时候这些 Watcher就会开始调用 update 来更新视图。

  1.Proxy性能优于Object.defineProperty。 Proxy代理的是整个对象Object.defineProperty只代理对象上的某个属性,如果是多层嵌套的数据需要循环递归绑定;

  2.对象上定义新属性时,Proxy可以监听到,Object.defineProperty监听不到,需要借助$set方法;

  3.数组的某些方法(push、unshift和splice)Object.defineProperty监听不到,Proxy可以监听到;

  4.Proxy在ie浏览器存在兼容性问题? ,vue做了降级处理使用??Object.defineProperty

  内部使用reflect,proxy存在get陷阱,this可能不会指向调用者。用reflect修正this指向到调用者。

  13个api方法。

  type一般定义基本类型,(可定义所有类型)扩展用&? ??基本类型的别名,联合类型,元组类型

  interface 一般用来定义接口,描述数据类型 , 扩展用extend,声明合并

  cdn的概念,cdn失败了,如何处理。

  sort内部原理,找到数组第二大元素,边界问题(一个元素,全都是一个元素)? new Set()

  sort length<10 插入排序? O(n2),n>10快速排序(二分法,nlogn)

  双向绑定

  vue层面的优化

  虚拟dom的理解

  性能优化

  学习的途径

  http2相比于http1.1的优势

  微任务和宏任务

  重绘和回流

  index.html? 如何清缓存? (nginx配置不缓存index.html)

  <--如果需要在html页面上设置不缓存,这在标签中加入如下语句-->

  <meta http-equiv="Pragma" content="no-cache">

  <--用于设定禁止浏览器从本地机的缓存中调阅页面内容-->

  <meta http-equiv="Cache-Control" content="no-cache, must-revalidate">

  <-- Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。-->

  <meta http-equiv="Expires" content="0">

  router,axios封装,

  Vuex 是通过 new 一个 vue 实例,并把 state 作为 vue 的 data 利用 vue 的响应式系统把 state 中的数据变为了 响应式数据。* **getter 本质上是依赖了 vue 的 computed 实现了缓存机制。**store.js定义了 install 方法,该方法在执行 Vue.use(Vuex) 时会自动调用,install 方法中主要是调用 mixin 方法,在 beforeCreate 勾子中为每个组件都混入一个$store 属性,他们都指向同一个

  进程是cpu资源分配的最小单位(是能拥有资源和独立运行的最小单位)

  线程是cpu调度的最小单位(线程是建立在进程的基础上的一次程序运行单位)

  VUEX应用场景 ?原理

  D3 ?api

  适配问题 不同分辨率

  性能优化

  什么场景不能用this

  es6语法

  关系图的数据结构

  pinia和vuex的区别

  qiankun沙箱原理(js、css)

  vite 和wabpack的区别

  vite首次启动过慢解决方案

  $forceUpdate? ??this.$router.go(0)? ?使用v-if标记? ? 改变key

  $forceUpdate? ? 在依赖发生变化的时候会通知??watcher??,然后通知??watcher??来调用??update??方法,重新render

  requestIdleCallback? ? 会在网页渲染完成后,CPU 空闲时执行

  requestAnimationFrame? ? ?浏览器每次渲染都会执行,不用自己计算时间

  首屏时间? firstScreen - performance.timing.navigationStart

  白屏时间

  

  async脚本会在页面加载完毕后执行。

  js -----(parse)? --> ast语法树? -----(类型推断,不同类型存储地址不同,ts有类型定义,省去了推断,更高效)---------->? ?字节码? ?->机器码运行

  1. 响应式系统升级? object.defineProperty,递归对象每个属性,proxy 在对象外层加一个拦截,惰性响应式,只有获取属性时才会动态设置proxy,? 内部使用reflect,避免了proxy的get陷阱

  2. Vue2中会通过标记根节点的操作,优化diff过程,但是静态节点还需要被diff,这个过程没有被优化

  当组件的状态发生变化后,会通知 watcher 触发 update 函数,最终执行虚拟dom的patch操作,遍历所有的虚拟节点,找到差异更新到真实节点上

  diff的过程中会去比较整个虚拟dom,先对比新旧的div以及他的属性,然后再对比他的子节点

  Vue2中渲染的最小单位是组件

  Vue3中标记和提升所有的静态节点,diff的时候只需要对比动态节点内容??片段的特性

  几个静态节点的dom全部都被提取到了最外层,这些被提升的静态节点,只有在创建的时候被创建一次,之后我们在调用render的时候,只需要进行复用就好。

  3. catchHandler 缓存函数,再次进行调用的时候,就会通过缓存中获取函数

  4.?对 Tree-shaking 的依赖更好,按需引入做的更好

  vite服务器启动速度比webpack快,由于vite启动的时候不需要打包,也就无需分析模块依赖、编译,所以启动速度非常快。当浏览器请求需要的模块时,再对模块进行编译,这种按需动态编译的模式,极大缩短了编译时间,当项目越大,文件越多时,vite的开发时优势越明显。vite热更新比webpack快,vite在HRM方面,当某个模块内容改变时,让浏览器去重新请求该模块即可,而不是像webpack重新将该模块的所有依赖重新编译。

  Vite的使用简单,只需执行初始化命令,就可以得到一个预设好的开发环境,开箱即获得一堆功能,包括:CSS预处理、html预处理、异步加载、分包、压缩、HMR等。使用复杂度介于Parcel和Webpack的中间,只是暴露了极少数的配置项和plugin接口,既不会像Parcel一样配置不灵活,又不会像Webpack一样需要了解庞大的loader、plugin生态,灵活适中、复杂度适中。

  1. vite.config.ts,添加配置预打包的文件,比较繁琐

  2.?vite-plugin-optimize-persist?插件,首次启动会给package.json文件添加预打包的配置, 第一次启动慢,再次进入会使用缓存,加速启动

  ...? ?当拷贝对象的属性值对应的都是基本类型数据,可以理解为深拷贝。当拷贝对象的属性对应的值为数组或对象等引用类型时,为浅拷贝

  跨域的方案,线上如何解决的

  前端优化

  promise.all原理

  从0开始搭建框架需要考虑什么

  jsonp是一种跨域通信的手段,它的原理其实很简单:

  首先是利用script标签的src属性来实现跨域。

  通过将前端方法作为参数传递到服务器端,然后由服务器端注入参数之后再返回,实现服务器端向客户端通信。

  由于使用script标签的src属性,因此只支持get方法

  Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。

  loader它只专注于转化文件(transform)这一个领域,完成压缩,打包,语言翻译; 而plugin不仅只局限在打包,资源的加载上,还可以打包优化和压缩,重新定义环境变量等

  watch和computed的区别

  CORS全称“跨域资源共享”,它是一种机制通过添加额外的HTTP头部告诉浏览器,允许origin上的web应用访问不同源服务器资源,可以在XMLHttpRequest、Fetch中使用CORS发起跨域请求。

  移动端bug

  移动端页面开发bug记录 多年总结 长期更新_泡面而已的博客-CSDN博客_前端开发 移动端输入bug

上一篇:世间安得双全法 :评《霜花店》
下一篇:文化意识教育论文十篇

最近更新小说资讯