- 博客(72)
- 收藏
- 关注
原创 浏览器原理的小知识
浏览器原理浏览器架构进程与线程进程:一个应用运行的实例。当应用启动时,操作系统为该程序划分一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,这个运行环境就是进程。线程:由进程来启动和管理,进程中使用多进程可以提高运算效率。两者的关系:进程中的任意线程出错,可能会导致进程崩溃。线程之间是共享进程数据的。进程之间的内容相互隔离。进程销毁后,操作系统会回收这部分内存。单进程浏览器:浏览器的所有模块都运行在一个进程里,这样会带来很多缺点:不稳定,不安全,不流畅。
2021-10-27 17:18:56
208
原创 Axios源码入门解析
Axios源码Axios的特性从浏览器中构建XMLHttpRequests对象从node中构建http请求支持promise拦截请求和响应,对数据做转换、封装等操作可以取消请求自动转化JSON格式客户端可以支持CSRF(伪造跨域请求)Axios类源码Axios的类源码如下:function Axios(instanceConfig) { this.defaults = instanceConfig; this.interceptors = { // 处理请求的
2021-10-13 21:04:59
200
原创 前端性能:浏览器的重绘和回流
浏览器的重绘和回流浏览器渲染机制浏览器采用流式布局模型浏览器将HTML解析成DOM树,CSS解析成CSSOM树,将DOM和CSSOM合并成Render树。有了RenderTree,就需要计算他们在页面上的大小和位置,最后绘制到页面上。由于浏览器使用流式布局,对Render Tree只需要计算一次布局,但是table元素及其内部元素需要进行多次计算,通常要花3倍同等元素的时间,因此要避免使用table。重绘由于结点的几何属性改变或者样式改变而不会影响布局的称为“重绘”。例如:visibi
2021-09-29 15:32:08
252
原创 前端性能:缓存
缓存缓存特征命中率某个请求能够通过缓存得到响应,称为缓存命中。命中率越高,缓存利用率越高。最大空间缓存的最大空间通常在内存中,当缓存存放的数据量超过最大空间,需要淘汰部分数据来存放新的数据。常见的缓存淘汰策略FIFO:先进先出,先进入缓存的数据在缓存空间不够时会优先被清除。LFU:最少使用策略。根据元素被使用次数判断,释放使用次数少的元素。LRU:最近使用策略。根据元素上一次使用的时间戳,清除最远使用时间戳的元素。其他:过期时间、随机请理、优先请理大对象。浏览器缓存按缓
2021-09-26 15:33:19
292
原创 前端性能:RAIL模式
RAIL模式概念RAIL是一个以用户为中心的性能模型,它把用户的体验拆分成几个关键点(例如,tap,scroll,load),并且帮你定义好了每一个的性能指标。分为四个方面:ResponseAnimationIdleLoad用户体验用户对性能延迟的感知:延迟时间用户感知0-16ms很流畅0-100ms基本流畅100-1000ms感觉到网站上有一些加载任务1000ms or more失去耐心了10000ms or m
2021-09-25 15:38:40
363
原创 前端性能:PRPL模式
PRPL模式概念PRPL模式是一种让网页加载变得可交互、更快速的模式。Push或Preload:给用户推送最重要的资源;Render:尽快渲染最初始的路由,使网页有交互能力;Pre-cache:提前缓存剩余的资源;Lazy-load:懒加载其他的路由或者次要的资源。PreloadPreload是一个声明性质的fetch request,告诉浏览器尽快请求该资源。<link rel="preload" as="style" href="css/style.css">
2021-09-22 20:04:06
462
原创 Node:进程学习笔记
九、进程1. 多进程架构Node提供了child_process模块,并提供了child_process.fork()函数供我们复制进程。下面来看看一个例子:// worker.jsconst http = require('http');http.createServer((req,res)=>{ res.writeHead(200,{ 'Content-Type' : 'text/plain' }) res.end('hello,worl
2021-08-10 17:07:02
154
原创 Node:Web应用学习笔记
八、Web应用1. 基础1.1 CookieCookie的处理分为几步:服务器向客户端发送Cookie;浏览器将Cookie保存;之后每次浏览器都会将Cookie发送到服务器端。由于Cookie的实现机制,当服务器端向客户端发送了设置Cookie的意图,除非Cookie过期,否则客户端每次发送请求都得带上Cookie,当设置的Cookie过多,会导致报头过长,浪费了部分带宽。1.2 SessionSession的数据保存在服务器端,客户端无法随意修改,这样数据的安全性能够
2021-08-10 17:06:03
114
原创 Node:网络编程随记
七、网络编程Node提供了net,dgram,http,https模块,分别用来处理TCP、UDP、HTTP、HTTPS,适用于服务器端和客户端。1. 构建TCP服务TCP全称为传输控制协议,作用于传输层。OSI模型:应用层:HTTP、SMTP、IMAP等表示层:加密、解密会话层:通信连接、维持通话传输层:TCP、UDP网络层:IP链路层:网络特有的链路接口物理层:网络物理硬件许多应用层协议基于TCP构建,如HTTP、SMTP、IMAP等。在TCP创建会话的
2021-07-16 10:03:55
135
原创 Node:Buffer
六、Buffer1. Buffer结构1.1 模块结构buffer的性能相关部分用C++实现,非性能部分用JavaScript实现;Node在进程启动时就已经加载了,并将其放在全局对象。1.2 Buffer对象Buffer类似与数组,他的元素未16进制两位数。不同编码所占的元素个数不相同,UTF8编码下一个中文字符占三个元素,字母和半角标点占一个字符。可以通过buffer.length来获取Buffer对象的长度。如果给Buffer元素赋值0-255以外的值,Buffer就会对其连续
2021-07-04 21:40:47
415
原创 Node:内存控制学习笔记
五、内存控制基于无阻塞,事件驱动建立的Node服务,具有内存消耗低的优点,非常适合处理海量的网路请求,而内存控制就是在海量网络请求和长时间运行的前提下探讨的。1. V8的垃圾回收机制与内存限制与Java一样,JavaScript由垃圾回收机制来及逆行自动内存管理。1.1 V8的内存限制Node通过JavaScript只能使用部分的内存:64位系统下为1.4GB,32位系统下位0.7GB。在这样的限制下,Node无法直接操作大内存对象,比如无法将一个2GB的文件读入内存进行字符串分析处理
2021-06-08 10:35:52
374
2
原创 Node:异步编程学习笔记
四、异步编程1. 函数式编程1.1 高阶函数高阶函数是指能够把函数当作参数,或者将函数作为返回值的函数:function foo(x) { return function (){ return x; }}对于程序编写而言,高阶函数比普通函数要更加灵活。除了通常的函数调用返回外,还形成了一种后续传递风格的结果接收方式。后续传递风格的程序编写将业务重点从返回值转移到了回调函数中:function foo(x,bar) { return
2021-05-22 16:35:37
113
原创 Node:异步I/O学习笔记
三、异步I/O1. 推行异步的原因在浏览器中,JavaScript在单线程中执行,且与UI渲染公用一个线程,这就会出现JavaScript在执行时,UI渲染和响应处于停滞状态的现象;如果脚本执行时间超过100ms,用户就会感觉到页面卡顿,而在BS模型中,网速的限制会给网页的体验造成很大干扰。因此,前端采用异步的方式可以解决UI渲染阻塞的问题,但响应也却决于服务器的速度。**同样的任务t1~tn,同步的执行时间T=t1+t2+…+tn,而异步的执行时间为Max(t1,t2,…,tn)。**因此,随
2021-04-26 21:42:14
166
原创 Node:模块机制学习笔记
模块机制1. CommonJS1. 模块规范a. 模块引用在CommonJS中,存在require()方法,接收模块标识,以此引入一个模块的API到当前模块中。b. 模块定义对应引入功能,上下文提供了exports对象用于导出当前模块的方法或者属性,并且是唯一的出口。在模块中,module对象代表模块自身,而exports是module的属性。在Node中,一个文件就是一个模块,将方法挂载在exports对象上作为属性即可定义导出的方式。c. 模块标识模块标识其实就是传递给re
2021-04-19 22:12:56
153
原创 HTML:SEO优化之旅
HTML:SEO优化之旅一、何为SEOSEO(Search Engine Optimization),即搜索引擎优化;SEO是随着搜素引擎的出现而来的;他的存在是为了提升网页在搜索引擎自然搜索结果中的收录数量以及排序位置,是的用户在搜索网站时能排在前面;二、SEO能做什么大于网站的标题、关键字、描述进行设置,反映网站的定位,让搜索引擎明白该网站时干什么的;内容优化:内容与关键字的对应,增加关键字密度;在网站上合理设置Robot.txt文件;生成针对搜索引擎友好的网站地图;增加外部链
2021-04-13 16:19:07
197
1
原创 TS:装饰器
TS:装饰器一、定义是一种特殊类型的声明,它能够被附加到类、方法、访问符、属性或参数上。二、几种模式(以类装饰器为例)1.普通模式/** @target : 当前对象原型**/function logClass(target : any) { target.prototype.myAttr = '动态扩展的属性'; target.prototype.myFunc = () => { console.log('动态扩展的方法'); }}@
2021-04-12 22:09:31
277
原创 TS:模块解析策略
TS:模块解析策略一、 传统模块解析策略相对导入相对导入的模块是相对于导入它的文件进行解析的。例如,从/root/src/test.ts文件中有这样一个语句import { foo } from "./foo",它的查找流程如下:/root/src/foo.ts==>/root/src/foo.d.ts非相对导入非相对模块的导入,编译器则会包含导入文件的目录一次向上级目录遍历,尝试定位匹配的声明文件;例如,从/root/src/test.ts文件中有这样一个语句im
2021-04-10 14:41:31
730
原创 Javascript:手撕Promise
JavaScript:手撕Promise源码一、什么是Promise?Promise可以实现异步操作;可以将异步操作队列化,按照期望的顺序执行任务;拥有三种状态:等待(Pending)、已兑现(Fullfilled)、已拒绝(Rejected),且状态只能从Pending向其他两个转化,一旦变化就冻结了;有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。二、Promise的使用过程
2021-03-31 22:15:49
131
原创 Vue:Array变化侦测
Vue:Array变化侦测1. 数组追踪变化 与Object不同,数组无法通过getter和setter方式来追踪变化,因此,我们需要自定义一个拦截器来追踪变化。2. 拦截器的准备 拦截器其实就是一个与Array.prototype一样的Object,里面所包含的属性一样,但是改变数组的方法是我们修改过的。 首先,我们先对Array.prototype来个定制。const arrayProto = Array.prototype;const arrayMethods = Object.
2021-03-06 13:20:03
371
原创 Vue:Object变化侦测
Vue:Object变化侦测1. 什么是变化侦测 Vue.js会自动检测状态并生成DOM,然后将其输出到页面上,这个过程称为渲染,这个渲染过程是声明式的,我们通过模板来描述状态和DOM之间的映射关系。 而通常情况下,我们的页面是不断在更新状态的,此时页面根据状态来重新渲染,想要检测这个过程,就涉及到了变化侦测。 变化侦测有两种类型:“推”和“拉”。国内三大主流框架中的Angular和React都采用“拉”,Vue采用的是“推”。 “推”的优势是,当状态发生变化,Vue能够立刻知道,
2021-03-04 22:44:34
235
1
原创 ES6:几种get和set的使用
ES6:几种get和set的使用一、基于普通对象的实现const demo = { _name = ''; get name(){ return this._name; } set name(val){ this._name = val; }}demo.name = 'yivi';console.log(demo.name); // 'yivi'二、基于class的实现class Demo{ constr
2021-03-01 19:58:50
2663
原创 JavaScript:原型链继承与对象冒充继承及ES6语法的解决
JavaScript:原型链继承与对象冒充继承及ES6语法的解决在ES5语法中,没有类这种概念,只能通过特殊的方式来实现继承;在学习原生js继承的过程中,遇到了两种继承模式的特点,特此记录下来以便下次复习。1.原型链继承原型链继承可以继承构造函数以及原型链上的属性和方法,但实例化子类的时候,无法给父类传参;function Father(name,age){ this.name = name; this.age = age; this.info = function
2021-02-25 16:59:12
151
原创 d3.js:取代d3.mouse的d3.pointer
前言今天在学习如何使用d3.js的事件处理函数过程中,发现d3.mouse和d3.event在浏览器报错不是函数,于是前往官方文档,发现这里两个函数已经在d3V6.0中删除了!于是,我在往上查了好久,没有查到替代的函数,只能回头再次翻阅文档,终于被我找到了!对比在V5.0和更早的版本中,sel.on(type,callback)的callback有三个参数:d:绑定当前元素的数据点;index:当前数据点在选择集中的索引;nodes:当前数据点所在的选择集;而在最新的V6.0版本
2021-02-03 14:58:04
2656
1
原创 SVG:基础知识
SVG:基础知识一、viewBox和preserveAspectRatio1. viewBoxsvg的viewBox是一个十分强大的属性,他允许svg画布无限延伸,并且精准控制其可视区域。总共有4个参数,按照x,y,width,height的顺序设置;viewBox的参数是不用单位的,原因是svg的可视空间不是通过像素来定义的,而是一个可以随意延申的空间,这样就可以适应不同的尺寸;我们可以理解为,svg画布会被分成一张网格,即使svg的宽高改变,里面方格的数量也不会改变,因此图形占画布的比例也不
2021-01-24 15:24:21
661
2
原创 HTML5:移动端开发入门
HTML5:移动端开发入门一、前言常见的移动端开发分为移动版网站和响应式设计。移动端开发可以让技术人员专注于移动端的页面优化,而无需在意桌面版的兼容,但页面一旦改动内容,维护成本就翻倍了;响应式设计让开发人员只需维护一份项目,节省开发和维护成本,不过缺点是需要做好移动端和桌面端的兼容,也十分考验页面设计。两种开发方式孰强孰弱,暂无定论,本博客主要探讨一下移动端开发的技巧。二、移动端开发技巧1. Viewport设置传统桌面端网站的显示窗口往往都是在1024X768的分
2020-12-20 15:40:09
4264
2
原创 Vue:插槽真香
Vue:插槽真香一、前言插槽为组件提供了灵活性,使用组件的时候可以通过修改插槽的内容实现灵活的展示内容。下面正式介绍一下插槽的使用方法。二、插槽的使用1. 匿名插槽<comp>yivi</comp>let comp = { template : ` <div> <h1>怎央打</h1> <p>朋友们好,我是混元形意太极门掌门人<slot></slot><
2020-12-01 11:14:48
215
原创 Vue:nexttick是何方神圣?
Vue:nextTick是何方神圣?1. 官方定义在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。2. 解释Vue.nextTick()其实主要用于生命周期里,当你在上一个钩子函数中需要处理下一个钩子函数层面的内容时,可将这些操作放在Vue.nextTick的回调函数中。当Vue实例进行到该钩子阶段时,会将nextTick中的操作放到下一个钩子阶段去进行,实现了延迟处理。3. 举个例子当你需要在created阶段对dom进行操作时,一
2020-11-29 17:19:00
168
原创 TS:声明合并de妙处
TS:声明合并一、基础概念声明合并是指编译器将针对同一名字的多个独立声明合并为单一声明。合并后的声明同时拥有多个声明的特性。二、声明合并的种类1. 接口合并接口合并的机制时将双方的成员放到一个同名的接口里;接口里的非函数成员必须是唯一的,如果不唯一,必须是统一类型的;如果声明了同名的非函数成员但是类型不同,编译器就会报错;interface Animal { name : string; age : number;}interface Animal {
2020-11-20 20:11:46
875
原创 TS:迭代器和生成器
JS:迭代器和生成器当一个对象实现了Symbol.iterator属性时,我们认为他是可迭代的;对象上的Symbol.iterator函数负责返回供迭代的值;for...of语句for...of语句会遍历可迭代的对象或列表,并输出对应的值。let someArray = [1, "string", false];for (let entry of someArray) { console.log(entry); // 1, "string", false}for...
2020-11-19 22:22:26
1467
原创 TS:高级类型的十八般武艺
TS:高级类型1. 交叉类型交叉类型是将多个类型合并为一个类型,使得这个类型包含了所有类型的特性。大多数是在混入mixins或者其他不适合典型面向对象模型的地方看到交叉类型的使用。function extend<T,U>(first: T,second: U):T & U{ let result = <T & U>{}; for (let id in first) (<any>result)[id] = (&
2020-11-19 21:52:32
269
原创 TS&&Node:项目实战笔记
TS&&Node:项目实战笔记一、项目初始化首先先初始化一个npm项目npm init其次,在项目目录中初始化tsconfig.json文件tsc --init修改tsconfig.json文件,设置根目录和输出目录:{ "compilerOptions": { "target": "es5", "module": "commonjs", "outDir": "./dist", // 输出目录文件
2020-11-19 20:27:19
577
原创 Vue:使用History模式打包时注意事项
Vue: 使用History模式打包时需要注意的事项1. 前言今天在使用history模式打包vue项目,后台部署时遇到了种种问题,特地写一篇博客记录一下。2. 路由配置在History模式下,在路由配置文件中首先要将mode改为history;部署项目时,如果在域名后还有额外路径的话,需要注意添加base,作为每次跳转路由时的前缀;以下是设置样例:// router/index.jsexport default new Router({ mode : "histor
2020-11-13 12:40:35
4661
3
原创 TS:类型的推论兼容
TS:类型的推论兼容1. 变量类型兼容若变量x要兼容y,那么y必须至少拥有与x相同的属性:interface Named { name : string;}let x : Named;let y = { name : 'yivi',age : 12};x = y; // ok,y中拥有x的属性name2. 函数类型兼容首先是参数兼容:要看函数x能否赋值给y,x的每一个参数必须在y里能找到对应类型的参数。(参数名字无所谓,类型一致即可)。let x = (a
2020-11-09 20:51:00
278
原创 TS:枚举的拓展
TS:枚举的拓展1. 枚举的计算枚举成员可以使用常量枚举表达式进行初始化:enum E { None , OK = 1 << 1, Read = 1 << 2, Write = 2 << 1, ReadWrite = Read | Write, Pending = "123".length}2.枚举成员的类型枚举成员被枚举后,就带有了一种特殊的语义;枚举成员成为了类型:enum E { A
2020-11-08 15:59:23
1087
1
原创 TS:泛型的使用方法
TS:泛型1. 前言有时候,我们想让一个函数的参数和返回类型是相同的,就可以使用类型变量。类型变量是一种特殊的变量,用于表示类型而不是值。function identity<T>(arg : T) : T{ return arg;}定义了泛型函数后,可以用两种方法使用。一种是传入所有的参数,包括类型参数:let out = identity<string>("yivi");另一种是使用类型推论——即编译器会自动推断类型:let ou
2020-11-08 15:30:02
7785
原创 TS:ES6类的扩展
TS:ES6类的扩展1. 公共、私有、受保护的修饰符在typescript中,对ES6标准的类的成员做了扩展,即可以使用public,private,protected,readonly对成员进行修饰,限制其使用域。理解protected与private的区别:protected成员在其派生类(子类)中仍然可以访问到;若将构造函数标记成protected,意味着这个类不能再包含他的类以外被实例化,但是能够被继承:class Person { protected name
2020-11-07 21:51:05
597
原创 TS:接口的奥妙
TS: 接口的奥妙1. 接口基础语法interface Person{ name : string}function sayhelloto(person : Person){ console.log('hello,' + person.name);}let x = { name : 'yivi', age : 20}sayhelloto(x); // hello,yivi类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对应的就能够被识别。
2020-11-07 20:48:38
154
原创 TS : typescript 类型注解
TS : typescript 类型注解在ts中,类型注解是一种为函数或者变量添加约束的方式。1. 基础的类型boolean,number,string2. 数组ts可以想js一样操作数组元素,定义数字有两种方式。let list : number[] = [1,2,3];//orlet list : Array<number> = [1,2,3];3. 元组元组类型表示允许数组内的类型各不相同,但是在赋值时需要按照类型顺序来赋值。let list :
2020-11-06 15:26:41
4195
原创 ES6:模块的加载,与CommonJS进行比较
ES6 : Module的加载ES6模块与CommonJS模块的差异CommonJS输出的是一个值的复制值,ES6模块输出的是一个值的引用,也就是说,对CommonJS模块输出的值进行更改,不会影响到其模块本身的值,而ES6则会影响对同一个模块引用的值。CommonJS是运行时加载,ES6是编译时输出接口。import命令加载CommonJS模块在Node环境中,使用import命令加载CommonJS模块,Node将会自动将module.exports属性当作模块的默认输出,等同于exp
2020-10-29 22:08:27
335
原创 Vue:vue-router的基础原理
Vue:vue-router的基础原理一、前言大多数Vue应用都为单页面应用,而实现单页面应用最关键的工具就是router,router的底层封装了浏览器的History类,使得页面在切换时浏览器无需请求新页面;二、 vue-router的基本知识1. vue-router的三种模式vue-router总共有三种模式:HTML5 History、HashHistory、AbstractHistory(暂时不拓展)History模式:例如:http://test.com/abc
2020-10-27 10:32:58
303
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人