性能的考量:第一回(方法篇)
本文旨在梳理目下通用的性能优化方法性能优化没有一个统一的指标,但目的是明确的,就是要让站点应用的加载速度够快,如此用户体验才能高(暂且不管页面做的烂不烂),毕竟从应用开发者的角度看,时间就是金钱。为了让时间压缩到极致,我们需要从请求到完全响应的全部细节入手,尽可能的压缩。即:从用户在地址栏中输入—>页面加载完成,该过程中的每一个点,都需要倍加注意。可能这就是为什么那么多面试官那么喜欢问一道烂大街的题: 地址栏里输入地址后到直到页面展示,尽可能详细地说说…
精髓部分根据《高性能浏览器网络》的研究结论得出,性能优化三个大的角度:带宽、延时和渲染耗时.那么由于现代光纤通信的大规模普及,带宽的影响因素,已经小到可以忽略不计的地步(管道宽到你怎么都塞不满),所以本文不讨论,剩下的就是延时和渲染。
延迟耗时层面《计算机网络》的第六版中,对于延迟给出了明确的定义,从c端发出消息到s端收到消息的时间消耗,具体包括:排队延迟 –(缓冲)-> 处理延迟–(路由)->传输延迟—>传播延迟。但是扯了这么多是基于一个大前提的,就是真实发送请求的情况下。引用《高性能浏览器网络》的终极解决 ...
设计模式:单例模式
所谓单例模式,就是保证类的实例只有一个。思路很清晰,就是在构造函数中置一个标志,或者已存在的实例对象。先来一道简单版:**const f = function(name) {
this.single = null
this.name =name
}
f.getObj = function(name) {
if(!this.single) {
this.single = new f(name)
return this.single
} else {
return this.single
}
}
const a = f.getObj('s1')
const b = f.getObj('s2')
console.log(a)
console.log(b)
// f { single: null, name: 's1' }
// f { single: null, name: 's1' }
这种实现方式其实很简单,实际上就是 ...
js的上古规则:原型链那些事儿
本文目标:捋清原型链那一套在《JS类型详论》的那篇文章中,我们有提到过自有属性和原型属性的概念。二者的区别,就是原型链存在的意义。
const obj = {
name: 'dddd'
}
console.log(obj.hasOwnProperty('constructor'))
console.log('constructor' in obj)
在上面的代码中,我们创建了一个对象obj,含有一个name属性。随后用两种方式打印constructor,很显然我们并没有看到constructor属性,但是,通过in的方式,打印出了true。为什么?我们说过in能够扫描的属性不单单是对象上显式写出来的属性(自有属性),还包括了对象原型链上的(原型属性)。而此处的constructor,就存在于obj的原型对象中,所以打印出了true。具体查找流程:发现自有属性没有,然后沿着obj的__proto__属性找到其原型对象,发现目标输出。倘若依旧没有,那就继续沿着原型对象的原型对象找。直到世界尽头。这,就是原型链。
__proto__和prototype首先我们需要搞清 ...
JS类型详论
本文主旨: 极尽一切可能的,详细介绍js类型相关内容主要数据类型两类
基本类型: 变量存储值数字、布尔、undefined、null、字符串、Symbol
引用类型:变量存储地址,类似于c语言中的指针函数、数组、对象
判断数据类型
typeof: 能够判断除了null和数组的所有数据类型
console.log(typeof 'a')
console.log(typeof true)
console.log(typeof Symbol())
console.log(typeof undefined)
console.log(typeof null)
console.log(typeof {})
console.log(typeof function() {})
console.log(typeof [])
// 结果
string
boolean
symbol
undefined
object
object
function
object
instanceof: 实话讲,该方法用的并不多,因为他明显没有typeof用的舒服,且他并不是用来做类 ...
Git亲妈级教程
一般的代码提交流程:
git add .
git commit -m 'message'
git push
提交到自己的分支,发起合并到dev分支的merge交由负责人审查合并代码。
克隆分支并同步远端
git checkout -b '分支名'
git push origin '分支名'
查看哪些文件被修改及修改的内容
git diff --cached
本地仓库与远程主机仓库关联起来
git remote add origin "https://github.com/kinglion580/shiyanlou.git"
如何在本地给远程仓库创建一个分支?(就是远程仓库没有该分支)首先需要在本地新建一个分支: git checkout -b 分支名同步到远程:git push –set-upstream origin 分支名然后通过命令直接push到远程:git push
如何在本地删除远程分支
// 删除本地分支
git branch -d 分支名
// 删除远程分支
git push origin --delete 分支名
// 本地分支和远程同步
git re ...
关于所谓的“梯子”的实现逻辑
不知道从什么时候开始,”挂个梯子”,成了很多大陆网友常挂嘴边的词。对于我而言,不仅仅是常挂嘴边,也曾一度想要实现一个自己的专属“梯子”。但是经过自己的一番研究之后,果断放弃了,因为不具备实现的条件。欲知详情,且听我缓缓道来。
说到梯子,就不得不提一下GFW,即:大名鼎鼎的长城防火墙。类似进击的巨人中,那三层巨大的高墙,将墙内的人们与世界割裂。区别在于,前者是虚拟不可见的,而后者,则是正儿八经的看得见摸得着石头墙。GFW的实现原理,其实很简单,针对特定的站点,进行访问限制。可以简单理解为,大陆的所有的对外访问,都会经由一个统一的出口,如果访问的是受限制的站点,则会失败。
那么“梯子”是如何突破这种限制的呢?本质在于“映射”,专业词汇“代理”。当我们挂上梯子访问外站的时候,机器首先访问的并不是我们输入的地址,而是中间层的机器。类似于“存储转发”的概念。
有网络知识基础的人都晓得,当我们在浏览器的地址栏中输入网址,会通过tcp/ip协议族,跟目标主机建立通信链路,然后发送资源请求,只涉及双方:我的机器—>目标服务器,等同于现代的通话。那么“梯子”做的事情,相当于在双方之间加了 ...
Down视频资源时的偶然发现
鄙人关于互联网上的资源,向来的主张都是:但凡挂到了网上的资源,都应该免费共享。这也是伯纳斯李那些前辈们的初衷。但是目下很多站点尤其视频站点以版权为由,在制造各种障碍阻挠我们去获取到。我觉得吧,版权固然要保护,对于那些利用有版权的东西获利的人必须严厉打击但是,向我们这种纯粹想down下来收藏的人,是不是太过不友好?
关于视频资源的处理,各有千秋。有直接暴露src的,也有通过blob伪加密的,也有片段加载的,总体来讲,手段低劣,都不用自己去写工具,稍微懂点搜索常识的小白,也可以很容易的找到对应的工具达到目的。比如b站的you-get,油管的seg等。
最近碰到个手段风骚的站点。起因出于自己想借重温一遍《Big Bang》听力,但是翻了半天几乎没有可用的,即使可用但是字幕糟糕。索性就找了个在线的站点。看着看着老毛病又犯了,这么好的资源down下来岂不美哉?
但是,当我打开控制台懵逼了。
快捷键打开控制台:弹框“你知道的太多了”,直接无法打开…
页面一直死循环debugger!!!。
手段真骚。仔细看下代码(图片有点模糊):
<script type="text/javascr ...
HTTP版本演进:第三回
本文的目的,就是要填前文留下的坑。为了更加充分的使用c端和s端的效率,解决队首阻塞。两个方案:并行tcp链接,以及http2.0版本的多路复用。
并行tcp链接这个方法简单粗暴。1.1版本的http协议不是严格执行串行传输嘛,那好,我们就多开几个tcp链接。同时s端开启多线程并行处理响应。目前主流的浏览器厂商都默认最大支持6条线路。至于为什么是6,而不是更大的数值,权衡的结果。这种方法,能在一定程度上,实现优化的效果,但是治标不治本,对于并行的每条链路而言,依然存在队首阻塞的问题。
HTTP的2.0HTTP/2基于SPDY,专注于性能,最大的一个目标是在用户和网站间只用一个连接(connection)
1. 二进制分帧如下图所示:
传统1.x传输的是纯文本的报文(字节), 而2.0是将请求和响应的数据切分成更小的数据帧,传输的是其二进制格式的数据,提高解析的效率。
2.0版本的数据传输如下图所示,所有的数据传输都是基于一个TCP链接。一个完整的请求响应称为一个流,流又有请求消息和响应消息组成,而具体的消息就是帧。这样的解释更多的是逻辑上的理解。本质就是数据被二进制分帧,乱序发送与组装, ...
HTTP版本演进:第二回
续前文,本文将详细的介绍一下1.x版本的特性,主要就是1.1啦。
1.x版本的三个特点:
长连接
管道化
串行传输
长连接1.0版本遵循的规则是:建立链路--发送请求--接收响应--断开链路。对于每一个请求而言,1.5个rtt(往返时延)是必须的。假使我们现在有n个请求,那么固定的时耗就是1.5 * n。那么1.1的重大改进,就是利用长连接,实现了多个请求共用一个TCP连接通道。这样除了第一个请求外,对于后面的每个请求,都能省去用于建立链路的1个rtt耗时,即:我们能够节省(n-1)次的rtt(往返时延)。这就是长连接带来的好处。
插个题外话:我们知道,c端在发送资源请求之前,需要通过三次握手建立连接链路,时间损耗,就用掉了1.5个往返,这里有个细节我之前一直没在意。就是发送资源请求的时间点与建立连接的那最后0.5的往返时刻是同时发生的,可以理解为,1.5的往返耗时,包含了请求时间,见下图:
同时,通过上图,也能看出,为什么1.1版本的改进影响巨大。著名案例就是苹果的工程师们针对itunes的改进,有兴趣自行谷歌。
但是,通过长连接虽然实现了公用tcp链路,我们发现了新的问题,因为规 ...
HTTP版本演进:第一回
本系列文章,严重参考《高性能浏览器网络》和《HTTP权威指南》
前言:http的设计思路,起源于20世纪三十年代的一篇文章:《As we may think》,作者美国MIT工程学院的电子工程师Vannevar Bush,该文尝试探讨了人们每天生产的信息量和社会消化信息的能力。一句话总结:信息太多,别说消化了,查找都费劲。得设计一个更牛叉的东西,帮助我们提高效率。这就是http超文本概念的起源,超越文本的信息存在。虽然概念的正式提出得30多年之后但是,在此还是由衷的对这些仰望星空的前辈们致敬。
http和https:http就是超文本传输协议,所谓的协议就是一种约定,约定了在双方或者多方之间传输的数据的格式,仅此而已。这是1991年万维网之父伯纳斯李同学提出并设计的一套协议。主要目的就是机器之间能够互传资源,实现网络互联的真实需求。请求与响应。即:客户端向服务器发送资源请求,服务器端响应返回对应资源。https则是在http之外,又包了一层SSL,也就是安全套接层,用于加密传输,保证数据的可靠性。
总体划分四个版本:0.9、1.0、1.1和2.0
0.9版本该版本可以视为初代机,只有一 ...
