元芳

13 posts published

base64

base64 原理及转换会变大的原因

以前用到base64有这么几个场景: 使用html2canvas 将html 转成图片的时候,html 里面的跨域图片无法生成图片,所以将图片先转成base64再生成jpg之类的图片有损压缩,使用canvas.toDataUrl()webpack 打包时,为了减少 https(http) 的请求数量(主要是为了减少三次握手,如果是http1.1开启了长连接或者http2.0/3.0之类的有多路复用,其实我觉得可以不用转base64),将小于10k(好像是10k,记不清了)的图片转成base64打在代码里。但是,图片转成base64,体积会变大33%,所以大点的图片也不建议转换。 那么,转成 base64 为什么会变大呢? 还有为啥叫 base64, 不叫base16或者base24、base32呢? 针对上面的疑问,我们一步步来解释,别急,老弟! base64 生成步骤假设我们有个单词要转成base64: Hello 1. 找到每个字母对应的ASCII值ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符0NUT32(space)64@96、

gizp

gzip压缩的LZ77算法和哈夫曼编码实现原理

前端在性能优化那块有提到过gzip,但是gzip 的实现原理只是简单提了一下是基于deflate的算法,使用的是LZ77 + huffman Code。今天就来详细的总结下原理,不过有些问题还是没搞清楚,什么问题后面再说。 在这之前有个问题要先说下,nginx 和 webpack 中都是能做 gzip 压缩的,那有什么区别呢? web 服务器(nginx)在向客户端发送gzip文件的时候,会先在本地文件系统查找 .gz 的文件,如果没有,则会去生成一份。生成的时候肯定会占用cpu的资源,所以当请求量比较大的时候,会占用较多的cpu来生成gz文件。而 webpack 的 gzip 则是在编译阶段就生成,所以服务器不用再生成,可以达到减少cpu资源占用的目的。 LZ77LZ77 这个算法是两个以色列的大神 Lempel 和 Ziv 于1977 年提出的,所以简称为LZ77。 LZ77原理:压缩原理其实很简单,就是找出那些重复出现的字符串,然后用更短的符号代替, 从而达到缩短字符串的目的。比如

性能优化

性能优化之prefetct、dns-prefetch、preload

在做项目优化的时候,遇到了 prefetch、preload,之前没有总结过,所以今天顺带都总结下。 首先这些属性都是在 link 标签上使用,以前都是拿 link 标签来加载外部css,没想到还有这个妙用。 preload示例代码<link href="app.9dad33ea7f9b9e219e85.js" rel="preload" as="script"> <link href="css/app.613f0ba0.css" rel="preload" as="style"> 作用 (提前加载)preload 是一个高优先级的资源加载声明,专注于当前页面。 通过 Chrome devtools 的 network 面板,可以看到带有 <

原型链

原型链之__proto__和prototype

原型链每隔一段时间就容易忘记,所以整理一下,便于回顾。 用下面的代码 demo 来帮助理解: function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function() { console.log(this.name); } } let person1 = new Person('nick', 29, '程序员') let person2 = new Person('tom', 28, '摄影师') person1.sayName(); //nick person2.sayName(); // tom 先看图,有个大体印象: 定义prototype是个对象,

性能优化

前端性能优化

思维导图获取 基础的 Web 技术层面的优化Web服务器优化开启压缩 content-encoding 有五个参数值: gzip、compress、deflate、identity、br(Brotli)。 它表示消息主体进行了何种方式的内容编码转换。这个消息首部用来告知客户端应该怎样解码才能获取在 Content-Type 中标示的媒体类型内容。 Gzip: 基于 DEFLATE 算法,它是 LZ77 和霍夫曼编码的组合,最早用于 UNIX 系统的文件压缩。HTTP 协议上的 Gzip 编码是一种用来进 Web 应用程序性能的技术,Web 服务器和客户端(浏览器)必须共同支持 Gzip,当下主流的浏览器都是支持 Gzip 压缩,包括 IE6、IE7、IE8、IE9、FireFox、Google Chrome、Opera 等。

深拷贝

使用 JSON.parse、JSON.stringify 深拷贝的缺陷

在用SON.parse、JSON.stringify做对象深拷贝时,发现会丢失对象中某些类型的值,所以我们来一探究竟,看看在转换过程中做了什么处理。 先看下MDN是怎么介绍 JSON.stringify 的JSON.stringify(value[, replacer [, space]]) 参数value将要序列化成 一个JSON 字符串的值。 这是第一个参数,应该都不陌生,最常用的也是这个。其他两个基本用不到。 一般传入一个对象。但是不仅仅如此,还可以传入其他值哦。 replacer | 可选可以三种类型的值: 函数,在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理数组,只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中null或者未提供,对象所有的属性都会被序列化一般情况下,我们都不传,按第3种方式处理。 space | 可选指定缩进用的空白字符串,用于美化输出。 可以指定三种类型的值: 数字,代表有多少的空格。上限为10,该值若小于1,则意味着没有空格。字符串,字符串的前十个字母,该字符串将被作为空格。null或者未提供,将没有空格。

Etag

浏览器协商缓存中的ETag是怎么生成的?

上一篇 浏览器的缓存机制 讲了整个的缓存流程,那么其中的ETag是怎么生成的呢? 其实在不同的Web服务器有不同的算法,今天,我们就以nginx为例,看一下是怎么生成的。 以这个资源文件的请求为例 可以看到Server是 nginx/1.14.0,那我们再去看看nginx的源码是怎么生成ETag的ngx_http_core_modules.c etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"", r->headers_out.last_modified_time, r->headers_out.content_length_n) -

缓存机制

浏览器的缓存机制

场景当我们浏览器使用久了,会发先他的占用空间越来越大,用清理软件扫描的时候,会发现有个缓存文件目录 这些文件都是经过16进制加密的,window上可以用ChromeCacheView查看,mac os 没找到查看的办法,所以我也没有验证缓存文件的内容。 不过据 ChromeCacheView 的截图来看,是可以看到存储文件原来的信息。 所以当我们首次浏览网页的时候,浏览器会从服务器获取所有数据和媒体并缓存到本地存储。 当再次访问同一站点时,浏览器仅从Web服务器检索HTML页面信息。 页面的所有静态部分(例如图像或JavaScript文件 )都将从现有的浏览器缓存中提取。由于第二次从远程Web服务器传输到浏览器的数据量很小,因此页面加载速度更快。 前端性能优化之缓存优化既然访问网站的时候可以对一些文件进行缓存,那就可以达到减少带宽,降低网络负荷,加快页面加载速度的目的,所以制定一个合理缓存策略就很重要了。 浏览器缓存解释浏览器缓存其实就是浏览器保存通过HTTP获取的所有资源,是浏览器将网络资源存储在本地的一种行为。浏览器的缓存机制是根据HTTP报文的缓存标识进行的。 总览思维导图获取点这里 缓存过程分析第一次发起HTTP请求过程如下: 完整的的流程图 流程图这里获取 参考资料: https://www.jianshu.com/p/54cc04190252 https://www.cnblogs.com/suihang/p/12855345.html

页面渲染

从输入URL到页面渲染出来的过程(详细)

思维导图获取 一、 URL 解析1. 输入内容合成地址用户输入URL,浏览器会根据用户输入的信息判断是搜索还是网址。 如果是搜索内容,就将搜索内容(会对内容进行字符编码等操作)+ 默认搜索引擎合成新的URL; 如果用户输入的内容符合URL规则,浏览器就会根据URL协议,在这段内容上加上协议合成合法的 2. HSTS(HTTP Strict Transport Security)因为 http 存在安全隐患(比如:明文传输,http 劫持),所以建议通过 HSTS 强制客户端使用 HTTPS。 关于HSTS和http劫持可以看下这两篇文章: 你所不知道的 HSTS 什么是HTTP劫持? 3. 其他操作安全检查 比如访问某网站出现安全警告访问限制 之前国产浏览器限制 996.icu黑客篡改网址 经过黑客封装的浏览器,可能会对链接做些修改,比如淘宝客的推广码换成自己的4. 检查缓存强制缓存 根据Cache-Control、Expires(优先使用Cache-Control)判断资源是否过期。 过期,则走协商缓存流程;

页面录制

web页面录制、回放以及生成视频

假如有这么一个需求: 记录一个用户在页面上的所有操作,包括点击、滑动、表单填写等;可以回放用户的操作;对现有代码侵入影响小;我们该如何去做呢?方案一客户端截图并上传至服务端服务端图片合成视频回放端播放视频试想一下,如果这么做会有什么问题? 首先服务端图片合成视频可以使用ffmpeg,生成mp4文件,回放端播放mp4文件就较简单了。 但是在客户端的问题就比较多了: 1. 怎么截图? 我们可以采用html2canvas或rasterizeHTML。 html2canvas的原理: 通过遍历DOM克隆一份副本,将此副本在Canvas上重新绘制,并根据DOM的样式应用在对应的绘制元素上,再通过Canvas生成图片。转换过程可理解成:DOM→Canvas→Image。rasterizeHTML原理: 通过遍历DOM克隆一份副本,利用SVG的foreignObject把DOM作为外部资源嵌套在SVG中,将此SVG在Canvas上重新绘制,并根据DOM的样式应用在对应的绘制元素上,再通过Canvas生成图片。转换过程可理解成:DOM→SVG的ForeignObject→Canvas→Image。两种截图方式最后都是通过把DOM绘制到Canvas,再通过Canvas输出图片。所以并不是直接屏幕截图,而是基于从 DOM 读取的属性构建页面的表示。因此,它只能正确地描述它所理解的属性,所以许多 CSS 属性可能不起作用。 另外两种方式都存在比较多的问题和限制: Canvas截图的限制性

公众号

对于微信小程序发布以来的看法与是否能够结合公司的业务做一些探索

自2017.1.9微信小程序正式发布以来,就被各种关于它的信息刷屏了,从QQ、微信技术群到朋友圈、微博再到各种新闻软件,无不充斥着关于小程序的信息。有些人对它充满了期待,认为他能搞死一大片App,也有些人并不看好,当然大部分人的态度还是吃瓜看戏。 这里我也想发表一些自己的看法,从多个角度剖析下微信小程序,不想看的自行跳过。 从腾讯的角度来看: 腾讯2016年第二季度的微信月活用户高达8.06亿(包括wechat),每天, 61%的微信用户打开微信超过10次,36%的用户每天打开微信超过30次。70%的用户每月在微信上花费100元以上;32%的用户每天使用微信超过2小时。从数据来看,微信已经成了社交领域的霸主,那么小程序对于微信又意味着什么呢? 神一样的男人张小龙曾这样描述它:小程序是一种不需要下载安装即可使用的应用,它实现了应用「触手可及」的梦想,用户扫一扫或搜一下即可打开应用。 相信这句话很多人都看过,我们再来看一个数据: 2016Q1中国手机网民用户规模达到6.9亿聪明的你或许猜到了我要说什么了吧?对,互联网的人口红利时代已经马上结束了,小企业害怕什么?害怕活不到明天。大企业害怕什么?害怕没有未来。那么什么是大企业的未来?先不说,再来看个信息,

MVVM

双向数据绑定总结

MVVM框架主要包含3个部分:model、view和 viewmodel。 Model:指的是数据部分,对应到前端就是javascript对象View:指的是视图部分,对应前端就是domViewmodel:就是连接视图与数据的中间件1.双向数据绑定的实现方式简单的来说,就是框架的控制器层(这里的控制器层是一个泛指,可以理解为控制view行为和联系model层的中间件)和UI展示层(view层)建立一个双向的数据通道。当这两层中的任何一方发生变化时,另一层将会自动作出相应的变化。 一般来说要实现这种双向数据绑定,在前端我目前了解的有三种形式: 基于脏检查 angular,regular(网易开发)观察机制封装属性访问器2.基于脏检查目前angular,regular的实现都是基于脏检查。当发生某些特定的事情的时候,框架会调用相关的digest方法。内部逻辑就是遍历所有的watcher,对监控的属性做对比。如果值发生了变化,则执行相应的handler。 2.1基于regular详细介绍一下:watcher对象看起来是这样的: { get: function(context){...} //获得表达式当前求值,此函数在解析时,已经生成 set: function(){} // 有些表达式可以生成set函数,用于处理赋 值,这个一般用于双向绑定的场景 once:

垂直居中

css垂直居中的三种实现

1.基于绝对定位它要求元素具有固定的宽度和高度。 main{ position: absolute; top: 50%; left: 50%; margin-top: -3em; /* 6/2 = 3 */ margin-left: -9em; /* 18/2 = 9 */ width: 18em; height: 6em; } 或者 main{ position: absolute; top: calc(50% - 3em); left: calc(50% - 9em); width: 18em; height: 6em; } 显然,这个方法最大的局限在于它要求元素的宽高是固定的。在通常情 况下,对那些需要居中的元素来说,其尺寸往往是由其内容来决定的。 如果 能找到一个属性的百分比值以元素自身的宽高作为解析基准,那我们的难题