
获得徽章 1
- #青训营笔记创作活动#
1月22日 Day9
图片压缩---前端的必备技能
1.TinyPng
很多时候,我们从 PS 等工具导出来的图片,或者是美术直接给到切图,都是未经过压缩的,体积都比较大。这里,就有了可优化的空间。TinyPNG使用智能的有损压缩技术来减少WEBP、JPEG和PNG文件的文件大小。通过选择性地减少图像中的颜色数量,使用更少的字节来存储数据。这种效果几乎是看不见的,但在文件大小上有非常大的差别。TinyPng提供两种压缩方法:一是通过在官网上进行手动压缩,二是通过官方提供的tinify进行压缩。
2.实现思路
总体分为五个过程,查找(找出所有的图片资源);分配(均分任务到每个进程);上传(把原图上传到TinyPng);下载(从TinyPng中下载压缩好的图片);写入(用下载的图片覆盖本地图片)。
3.具体流程
查找:通过命令行交互后,拿到目标文件夹的路径path,然后获取该path下的所有内容,接着遍历所有内容。首先判断该内容的文件信息:若为“文件夹”,则把该文件夹路径作为path,递归调用deepFindImg;若不为“文件夹”,判断该内容为图片,则读取图片数据,push到images中。最后,返回所有找到的图片。
均分:使用cluster,根据cpu核心数创建等量的进程,works用于保存已创建的进程,list中保存的是要处理的压缩任务,通过遍历list,把任务依次分给每一个进程。接着遍历works,通过send方法发送进程任务。通过监听message事件,利用pageNum记录进程任务的完成情况,当所有进程任务执行完毕后,则关闭进程。
上传:使用node自带的Https模块,构造请求头,把deepFindImg中返回的图片进行上传。上传成功后,会返回已经压缩好的图片的url链接。
下载:使用node自带的Https模块把upload中返回的图片链接进行下载。下载成功后,返回图片的buffer数据。
写入:process.on监听每个进程发送的任务,当接收到任务类型为「图片」,使用compressImg方法来处理图片。当任务类型为svga,使用compressSvga方法来处理svga。最后把处理好的资源写入到本地覆盖旧资源。展开评论点赞 - #青训营笔记创作活动#
1月21日 Day8
Esbuild----基于Go开发的一款打包工具
1.优势
相比传统的打包工具,主打性能优势,在构建速度上可以快 10~100 倍。采用 Go 语言开发,相比于 单线程 + JIT 性质的解释型语言 ,一方面可以充分利用多线程打包,并且线程之间共享内容,另一方面直接编译成机器码,大节省了程序运行时间。内部打包算法充分利用多核 CPU 优势。Esbuild 内部算法设计是经过精心设计的,尽可能充分利用所有的 CPU 内核。所有的步骤尽可能并行。从零开始造轮子,没有任何第三方库的黑盒逻辑,保证极致的代码性能。Esbuild 中从头到尾尽可能地复用一份 AST 节点数据,从而大大提高了内存的利用效率,提升编译性能。
2.与SWC对比
Esbuild 与 SWC 在性能上是在一个量级的,但不排除其他例子里面 SWC 比 Esbuild 略快的场景。Esbuild 本身的限制包括没有TS类型检查,不能操作AST,不支持装饰器语法,产物 target 无法降级到 ES5 及以下,这就意味着需要 ES5 产物的场景只用 Esbuild 无法胜任,相比之下,SWC 的兼容性更好。
3.应用场景
Esbuild 和 SWC 作为 transformer 性能是差不多的,但 Esbuild 兼容性远远不及 SWC。因此,SWC 作为 Transformer 更胜一筹。但作为 Bundler 以及 Minimizer,SWC 就显得捉襟见肘了,首先官方的 swcpack 目前基本处于不可用状态,Minimizer 方面也非常不成熟,很容易碰到兼容性问题。而 Esbuild 作为 Bundler 已经被 Vite 作为开发阶段的依赖预打包工具。
但总体来说,目前 Esbuild 对于真实的 Web 场景还有很多能力不支持,还有一些硬伤,包括语法不支持降级到ES5,拆包不灵活、不支持 HMR,对于真正能作为 Webpack 一样的构建工具来讲还有很长的路要走。
展开评论点赞 - #青训营笔记创作活动#
1月20日 Day7
WebRTC-----一项新技术
1.WebRTC的概念
WebRTC 是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点的连接,实现视频流和音频流或者其他任意数据的传输。WebRTC 包含的这些标准使用户在无需安装任何插件或者第三方的软件的情况下,创建点对点的数据分享和电话会议成为可能
2.应用场景
直播、游戏、视频会议、屏幕共享、远程控制等等,都可以使用。
3.媒体流
要想了解 WebRTC,首先要了解媒体流,媒体流可以是来自本地设备的,也可以是来自远程设备的。媒体流可以是实时的,也可以是非实时的。上述的应用场景中,我们都需要使用到媒体流,我们可以通过摄像头,麦克风,屏幕共享等方式获取到媒体流,然后通过 WebRTC 技术将媒体流传输到远端实现实时通讯。
4.通过摄像头获取媒体流
要实现音视频通话,我们肯定要先获取到摄像头的媒体流,然后通过 WebRTC 技术将媒体流传输到远端实现实时通讯。如何通过摄像头获取媒体流。先设置好用于播放媒体流的 video 标签,获取通过摄像头获取媒体流后,将媒体流赋值给 video 标签的 srcObject 属性,让其播放。如果想实现拍照功能,使用canvas 标签可以将媒体流绘制到 canvas 上,也可以通过 toDataURL 方法将 canvas 转换为 base64 图片后做一些其他操作。
5.通过共享获取媒体流
在 WebRTC 中,我们可以通过 getDisplayMedia 来获取屏幕共享的媒体流,这个 API 与 getUserMedia 类似,但是它只能获取屏幕共享的媒体流。执行 shareScreen 函数后,会弹出一个权限询问框,询问是否允许获取屏幕共享的媒体流。然后你就可以分享你的整个屏幕,如果你又多个屏幕的话,你可以选择其中一个进行分享。展开评论点赞 - #青训营笔记创作活动#
1月19日 Day6
一项技能——抓包
1.抓包的概念
抓包就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作。为前端开发者,通常是抓取应用层的 HTTP/HTTPS 的包。
2.HTTP抓包原理
HTTP/HTTPS 是应用层使用的通信协议,常见的应用层体系结构是客户端-服务器体系。抓包的思路就是设置一个中间进程负责抓包,每次目标进程之间的会话都会先于中间进程通信,从而实现抓包。
在HTTP标准中,没有对通信端身份验证的标准。对于服务器来说,它接收的 HTTP 请求报文只要格式符合规范,就发送响应报文。对于客户端来说也是如此,它无法校验服务器的身份。因此,对于 HTTP 抓包,无需做过多的处理,只需要让中间进程负责转发客户端和服务端的数据包。
3.HTTPS抓包原理
在HTTPS协议下抓包相比HTTP要复杂一些,因为HTTP是明文传输,容易受到中间人攻击,不安全。HTTPS语义仍然是 HTTP,只不过是在 HTTP 协议栈中 http 与 tcp 之间插入安全层 SSL/TSL。安全层采用对称加密的方式加密传输数据和非对称加密的方式来传输对称密钥,所以想用中间进程来抓包,需要设置在HTTPS加密通信之前,其中很重要的一步是浏览器的根证书校验。
具体中间的细节参考文末的链接,这里只给出整体流程。
4.电脑抓手机的包
PC 端建立一个服务器中间进程,伪装为 web 应用的目标服务器。手机端 web 应用发送的请求数据先经过中间进程,中间进程进行拦截处理再发送给目标服务器。反过来,目标服务器发送的数据包先通过中间进程,再由中间进程响应给浏览器客户端。这里要注意的是,无论是个人电脑PC,还是移动端手机,都需要接入互联网网络,可以相互找到对方才能建立通信。
一般对开发来说,个人电脑本地起的服务器进程,在公网上是访问不到的。一般是无线局域网,个人电脑与手机端连接同一个路由器发出的 Wi-Fi,就可以相互通信。
5.抓包工具
whistle是基于 Node 实现的跨平台抓包免费调试工具,其功能很强大,而且完全跨平台,操作简单,可以实现设置代理,反向代理,抓包重放等功能。具体关于whistle的操作可以参考文末的链接。展开评论点赞 - #青训营笔记创作活动#
1月18日 Day5
JS中常用的几个函数方法
这里只记录关键思路步骤,具体代码参考链接内容。
1.回到顶部
通过设置DOM的scrollTop的值来实现,具体要用一个计时器去控制scrollTopH.value的值,最后到达顶部时再消除计时器。
2.复制文本
也是通过DOM操作,通过创建DOM元素,去把要复制的内容拿,拷贝当前内容到剪贴板,然后再把元素删除。
3.过滤特殊字符,
首先要先设置一个模式,let pattern = new RegExp("[`~!@#$^&*()=:”“'。,..........]")
然后通过字符串的replace()方法,来把这些特殊字符替换成空,最后再拼接在字符串最后
resultStr = resultStr + str.substr(i, 1).replace(pattern, '');
4.校验6到18位大小写字母数字下划线组成的密码
通过正则表达式来判断,const reg = /^[a-zA-Z0-9_]{6,18}$/;return reg.test(password);
5.防抖和节流
先介绍防抖和节流的概念和出现场景
概念:
防抖:指定时间内 频繁触发一个事件,以最后一次触发为准
节流:指定时间内 频繁触发一个事件,只会触发一次
出现场景:
防抖是: input搜索,用户在不断输入内容的时候,用防抖来减少请求的次数并且节约请求资源
节流:一秒点击 10 下会发起 10 次请求,节流以后 1 秒点再多次,都只会触发一次,节约资源
两者都是通过计时器来实现。
防抖是通过设置一个计时器,然后判断计时器是否存在,如果存在就消除计时器,重新计时,只有计时器过了之后才会继续执行后面的函数。
节流死先设置一个变量,没有执行计时器时,默认为 false,当定时器没有执行的时候timer永远是false,当定时器执行时修改变量为true,如果出现多次点击,则直接返回,不会重复执行函数,执行完毕时再把变量修改为false,再用于下一次节流。
展开评论点赞 - #青训营笔记创作活动#
1月17日 Day4
JS中最特别且重要的一环——Promise
在我的认识中,Promise就是用来解决回调地狱的一种方法,可以让代码的可读性更高。官方的描述是:Promise是异步编程的一种解决方案,在ES6中Promise被列为了正式规范,统一了用法,原生提供了Promise对象。
对于Promise的概念,比较官方的介绍就是:Promise是异步编程的一种解决方案。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
在我的理解下,所谓Promise其实就是一个通知。就像你期末考试,你不知道老师试卷什么时候改好,每天都担惊受怕自己是否及格。终于到了暑假的某一天,试卷发到你手里,这个时候只有两种结果:及格或不及格。 也就是Promise中的fulfilled(已成功)和 rejected(已失败)。然而我们等待试卷的过程就叫pending(进行中)。
官方里有这么一句话:除了异步操作的结果,任何其他操作都无法改变这个状态。
什么意思呢,也就是,我拿到了试卷,及格和不及格这个状态已经是事实了。也就是(已成功) 或 (已失败) 是没办法改变了。
怎么来定义Promise呢?它可以定义为成功(也就是resolve中返回的数据),和失败(也就是reject返回的数据)。
如果说Promise是决定成功与否的命运,那么then就是我们面对这些结果的处理。
对于then方法的概念,官方文档是这样描述的:then 方法接收两个函数作为参数,第一个参数是 Promise 执行成功时的回调,第二个参数是 Promise 执行失败时的回调,两个函数只会有一个被调用。
也就是说,我们这个暑假考完试后,老爸跟你讲了两种情况,如果你及格了,给你买一台ps5。如果不及格,罚你洗碗一个月。
而then就是处理结果的一个方法,分别是成功的回调(第一个参数),和失败的回调(第二个参数)。 我们还在等待结果的时候就可以安排好怎样应对这个结果。
这就是对于基本的Promise概念的理解,当然Promise是一个庞大的内容,对于它更深入的理解就等用到它的时候再记录吧~展开评论点赞 - #青训营笔记创作活动#
1月16日 Day3
Monorepo —— 一个重要的项目管理方式什么是Monorepo?最简单的理解就是把多个项目放到一个仓库里面,它是一种模式,也可以理解成是一种环境,与其对立的是MultiRepo模式,即一个项目对应一个仓库。现在的前端基本上都在往Monorepo靠拢,所以这种开发模式是我们一定要熟悉的。一般的Monorepo的模式就是在 packages 存放多个子项目,并且每个子项目都有自己的package.json
Monorepo的优势?
1.代码复用
在维护多个项目时,当出现bug时,或者需要修改一部分代码时,就需要修改多个项目中的代码,成本高。因为不同的仓库工作区的割裂,导致复用代码的成本很高,开发调试的流程繁琐,甚至在基础库频繁改动的情况下体验会很差。
2.版本管理
依赖包的管理是开发中很重要的一环,但在这里就存在着一个问题,比如刚开始一个工具包的版本是1.0.0,有很多项目都依赖于这个包,但是有一天,这个包发布了一个新的版本,和原来版本中的API完全不兼容,但是有很多项目并没有升级这个依赖,就会导致报错,而如果是一个项目对应一个仓库,那就需要对每个仓库也就是package.json进行依赖升级,当项目多的时候就会很麻烦,如果是Monorepo环境下,就只需要升级一次就可以了。
3.项目基建
如果每个项目由一个仓库管理,那每个项目都需要单独配置开发环境、配置部署发布流程等,甚至每个项目都有自己单独的一套脚手架工具。但这些东西的逻辑其实是相似的,这就增加了重复的工作量,同时如果各个操作规范不统一,那管理起来将会非常麻烦。
4.团队协作
团队在一个仓库开发,能够方便地共享和复用代码,方便检索项目源码,同时,git commit 的历史记录也支持以功能为单位进行提交,所以只需要提交一次,简化了 commit 记录,方便协作。
现在已经有一些集成的Monorepo方案,比如nx,rushstack,不过由于这些顶层方案内部各种流程和工具链都已经非常完善了,如果要基于这些方案来定制,适配和维护的成本过高,可行度也比较低。展开评论点赞 - #青训营笔记创作活动#
1月15日 Day2
今天是记录一些前端开发中一些好用的网站
1.GitHub Desktop
git可视化工具,方便git命令的查找
2.tintpng
前端离不开图片,一个很好用的在线压缩网站,文件大的话可以用squoosh
3.码上掘金
很方便的在线代码编辑网站
4. Json.cn
在线格式化JSON
5. carbon
方便写笔记或者写文档的时候记录代码
6.emojiall
各种表情符号,颜文字的收录
7. iconfont
阿里巴巴推出的字体图标库,支持自定义图标库
8.surge
一个免费的部署网站,可以通过这个来自己部署一个网站。展开赞过评论1 - #青训营笔记创作活动#
1月14日 打卡Day1
今日学习 ——对HTML5中拖曳操作(Drag和Drop)的优化,用原生JS实现一个自定义拖曳效果
具体实现思路就是首先要考虑鼠标的三个事件(按下,移动,松开),当点击按下的时候,克隆一个绝对定位的元素,并记录一个正在移动的状态,然后就可以判断应该执行的具体方法(是往哪儿移动,怎么移动),这样就可以让元素随着鼠标移动起来。
实现的功能分别是实现元素抓取,性能优化,实现拖曳放大,实现放置,边界判断和体验优化。
我主要是学习了一下元素抓取和拖曳放大的功能。
元素抓取的原理就是克隆,在鼠标按下的时候克隆鼠标按下的那个元素,并把克隆出来的元素设置为绝对定位,只有变成绝对定位才能让元素浮起来,实现抓取的操作。同时还需要优化操作体验,让本体隐藏,同时不改变DOM的结构,具体操作就是在按下拖动时给本体的opacity样式设置为0,结束时再改为1就能实现。而对于鼠标松开之后的回退操作,可以通过transition来实现一个自然的动画,添加一个过渡属性,得到一个自然的回退动画。
拖曳放大的功能是通过设置了一个变化系数来实现的,这个变化系数就是拖动位置之间的距离(两点之间距离的计算公式),放大是transform: scale,只需要通过变化系数来修改scale,比如scale = (元素宽度 + 变化系数) / 元素宽度,或者其他的计算方式也可以,只要是添加了跟移动位置相关的变化系数,那么scale的值就可以按一定规律变化,就能实现放大的动画功能。展开赞过评论1