我是靠谱客的博主 可靠月光,最近开发中收集的这篇文章主要介绍前端性能优化、二进制、流(Stream)、缓冲区(Buffer)、图片文件转Base64,Base64转Blob,Blob转File对象、js和css与dom执行关系、游览器进程、woker、new,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、前端性能优化

1.http
从页面请求一个页面地址到返回看到全部数据的优化:强缓存/协商缓存、减少/合并请求数量、带宽、cdn的域名不同页面访问域名
2.资源大小
Js/css/html合并压缩
3.优化图片
雪碧图:优点减少请求,缺点图片资源过大,jpg有损压缩,压缩率大,没有图片透明,png兼容性好,可以图片透明,webp在ios和webview存在兼容性问题,svg矢量图,内嵌代码。
4.Css/js加载和执行
css写在head,js写在body(后面说为什么)
注意:GUI 渲染线程为什么与 JS 引擎线程互斥,防止渲染线程前后获得的元素就可能不一致。
5.回流重绘
减少重排、重绘。
设置图层:可以直接使用CSS的will-change属性,该属性可以表明元素将修改特定的属性,让浏览器事先进行必要的优化。也就是说,will-change是一个UA提示,它不会对你使用它的元素产生任何样式上的影响。但值得注意的是,如果创建了新的层叠上下文,它可以产生外观效果。

6.游览器离线存储

7.强缓存和协商缓存

二、二进制、流(Stream)、缓冲区(Buffer)

二进制、流(Stream)、缓冲区(Buffer)
二进制:我们还有字符、图片甚至视频。计算机是知道如何将这些表示为二进制的。就拿字符来说,比如计算机如何用二进制来表示”L“这个字母。为了将数据存储为二进制形式,无论任何类型的数据都会先被转换为数字,然后将数字转为二进制形式。“L”.charCodeAt(0)。你看到了什么?数字76?但是计算机怎么知道具体哪个数字代表那个字母呢?
字符集
字符集就是定义数字所代表的字符的一个规则表,同样定义了怎样用二进制存储和表示。那么,用多少位来表示一个数字,这个就叫字符编码(Character Encoding)有一种字符编码叫做UTF-8。它规定了,字符应该以字节为单位来表示。一个字节是8位(bit)。所以8个1和0组成的序列,应该用二进制来存储和表示任意一个字符。
为了更好的理解,举个例子: 比如之前提到的12的二进制表示是1100。 所以,使用UTF-8的格式来表示,应该使用一个字节,也就是8位来完整表示,也即00001100, 没有错吧?
因此,76在计算机中的存储形式应该是01001100。
当然,计算机也有一些特殊规则,将图片、视频等存储为二进制的,总之,计算机会将无论图片、视频或其他数据都转换为二进制并存储,这就是我们说的二进制数据。

流:
在Node.js中,流(stream)就是一系列从A点到B点移动的数据。完整点的说,就是当你有一个很大的数据需要传输、搬运时,你不需要等待所有数据都传输完成才开始下一步工作。

缓冲区(Buffer)
1)因此当数据到达的时间比数据理出的时间快的时候,这个时候我们处理数据就需要等待了。
2)如果处理数据的时间比到达的时间快,这一时刻仅仅到达了一小部分数据,那这小部分数据需要等待剩下的数据填满,然后再送过去统一处理。

这个"等待区域"就是buffer! 它是你电脑上的一个很小的物理地址,一般在RAM中,在这里数据暂时的存储、等待,最后在流(stream)中,发送过去并处理。
如果播放器已经处理完或播放完前一个数据,buffer仍然没有填满,“buffering”(缓冲)字符就会再次出现,等待和收集更多的数据。
注意:
如果你曾经搜索过 buffer 相关的知识,你应该见过以下这几兄弟:ArrayBuffer,Uint8Array,Uint16Array,Uint32Array,TypedArray,Blob,DataView

ArrayBuffer 和它的兄弟们:
ArrayBuffer 是最基础的二进制对象,是对固定长度的连续内存空间的引用
TypedArray 就是上面提到的 Uint8Array 那几个家伙的统称。他们都是 TypedArray (类型数组)的一种形式罢了。
Blob
Blob 是浏览器环境上提供的一种承载原始数据的二进制对象,它和 ArrayBuffer 没有必然联系,但是又可以互相转化。可以简单理解成另一种形式的,没这么底层的 ArrayBuffer
DataView
DataView 是一种底层的,更灵活的读取 ArrayBuffer 的视图。
· ArrayBuffer 是对内存的连续引用,这玩意没法直接操作。所以我们需要诸如 Unit8Array 等多种视图来 “翻译” 这厮
· 我们将那堆视图称之为 TypedArray 类型数组。但事实上并不存在 TypedArray 这个构造函数,它只是那堆视图的统称
· Blob 是另一种形式的二进制对象,主要在浏览器环境
· DataView 是一种更灵活的视图,更灵活的操作 ArrayBuffer

三、图片文件转Base64,Base64转Blob,Blob转File对象、画布转图片地址,HTMLCanvasElement.toDataURL()

1.读取File和blob文件
FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
2.FormData的格式
该FormData接口提供了一种方法来轻松构造一组表示表单字段及其值的键/值对,然后可以使用该XMLHttpRequest.send()方法轻松发送。如果编码类型设置为 ,它使用与表单相同的格式"multipart/form-data"。

后端兄弟:前端大佬,下载文件的接口,接口返回+个文件流,你处理一下
前端兄弟:啥?文件流?
发送一个原始数据的类文件对象下载:

axios({
method: 'post',
data: param,
responseType: 'blob',
url: _urls'
}).then(data => {
// 这里的返回值data应该是只包含二进制流文件的内容
const blob = new Blob([data],
{type: "application/vnd.ms-excel"}
);
let link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = '自定义导出表的名称';
link.click();
link.remove();
})

2023年4月23号补充:
如果需要捕获后端的错误码:

/**
 * blob转json
 * @param data 文件流blob
 * @returns
 */
function blobToObj(data: any) {
  return new Promise((resolve, reject) => {
    let reader = new FileReader();
    reader.readAsText(data, "utf-8");
    reader.onload = function () {
      try {
        resolve(JSON.parse(reader.result as string));
      } catch (error) {
        resolve({
          code: 1,
          message: "获取文件信息成功",
        });
      }
    };
  });
}
// 上面的代码修改
axios({
    method: "post",
    params,
    responseType: "blob",
    url,
    headers: {
    },
  }).then((data: any) => {
    // 这里的返回值data应该是只包含二进制流文件的内容
    blobToObj(data.data).then((res: any) => {
      console.log("res", res);
      if (res.code === 1) {
        const blob = new Blob([data.data], {
          type: "application/vnd.ms-excel",
        });
        let link = document.createElement("a");
        link.href = window.URL.createObjectURL(blob);
        link.download = decodeURI(data.headers.name);
        link.click();
        link.remove();
        message.success(res.message);
      } else {
        message.error(res.message);
      }
    });
  });

正题:
图片文件转Base64,Base64转Blob,Blob转File对象

Base64转Blob:

dataURLtoBlob(dataurl) {
    // base64转blob
    var arr = dataurl.split(',');
    var mime = arr[0].match(/:(.*?);/)[1];
    var bstr = atob(arr[1]);
    var n = bstr.length;
    var u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], { type: mime });
}

Blob 转 base64:

function blobToDataURL(blob, callback) {
    var fileReader = new FileReader();
    fileReader.onload = function (e) { 
    	callback(e.target.result); 
    }
    fileReader.readAsDataURL(blob);
}

Blob->File对象:

var files = new window.File([this.blob], file.name, {option})

base64转File:

dataURLtoFile(dataurl,fileName) {
     // base64转File
     var arr = dataurl.split(',');
     var mime = arr[0].match(/:(.*?);/)[1];
     var bstr = atob(arr[1]);
     var n = bstr.length;
     var u8arr = new Uint8Array(n);
     while (n--) {
         u8arr[n] = bstr.charCodeAt(n);
     }
     return new File([u8arr],fileName,{ type: mime });
 }, 

四、js和css与dom执行关系

在这里插入图片描述

(解释一开始说:css写在head,js写在body)
js和css会不会阻塞dom解析和渲染?
1)CSS 不会阻塞 DOM 解析,但是会阻塞 DOM 渲染
看出DOM Tree的解析和CSSOM Tree的解析是互不影响的,两者是并行的。因此CSS不会阻塞页面DOM的解析,但是由于render tree的生成是依赖DOM Tree和CSSOM Tree的,因此CSS必然会阻塞DOM的渲染。

2)JS 会阻塞 DOM 解析
比较合理的解释就是,首先浏览器无法知晓JS的具体内容,倘若先解析DOM,万一JS内部全部删除掉DOM,那么浏览器就白忙活了,所以就干脆暂停解析DOM,等到JS执行完成再继续解析。

3)CSS 会阻塞 JS 的执行
其实这样做也是有道理的,设想JS脚本中的内容是获取DOM元素的CSS样式属性,如果JS想要获取到DOM最新的正确的样式,势必需要所有的CSS加载完成,否则获取的样式可能是错误或者不是最新的。因此要等到JS脚本前面的CSS加载完成,JS才能再执行,并且不管JS脚本中是否获取DOM元素的样式,浏览器都要这样做。

五、游览器进程

从浏览器进程:游览器进程、第三方插件进程、GPU进程(3D渲染)、渲染进程(渲染线程、js引擎线程、事件触发线程、定时器线程、异步http请求线程)。多进程目的,防止一个页签崩溃,影响其他页签,防止进程之间的影响
记忆:一个异步请求经过:
Js引擎线程>异步http请求线程>事件触发线程>js引擎线程>渲染线程,如果有定时器就有定时器线程

注意:load事件与DOMContentLoaded事件的先后
上面提到,渲染完毕后会触发load事件,那么你能分清楚load事件与DOMContentLoaded事件的先后么?很简单,知道它们的定义就可以了:
当 DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片。
(譬如如果有async加载的脚本就不一定完成)
当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片都已经加载完成了。
(渲染完毕了)
所以,顺序是:DOMContentLoaded -> load

六、WebWorker与SharedWorker

1)WebWorker只属于某个页面,不会和其他页面的Render进程(浏览器内核进程)共享,所以Chrome在Render进程中(每一个Tab页就是一个render进程)创建一个新的线程来运行Worker中的JavaScript程序。
2)SharedWorker是浏览器所有页面共享的,不能采用与Worker同样的方式实现,因为它不隶属于某个Render进程,可以为多个Render进程共享使用,所以Chrome浏览器为SharedWorker单独创建一个进程来运行JavaScript程序,在浏览器中每个相同的JavaScript只存在一个SharedWorker进程,不管它被创建多少次。
3)看到这里,应该就很容易明白了,本质上就是进程和线程的区别。SharedWorker由独立的进程管理,WebWorker只是属于render进程下的一个线程

七、Js 中new做了什么

function myNew(Con, ...args) {
	// 创建一个新的空对象
	let obj = {};
	// 将这个空对象的__proto__指向构造函数的原型
	// obj.__proto__ = Con.prototype;
	Object.setPrototypeOf(obj, Con.prototype);
	// const obj = Object.create(func.prototype) // Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
	// 将this指向空对象
	let res = Con.apply(obj, args);
	// 对构造函数返回值做判断,然后返回对应的值
	return res instanceof Object ? res : obj;
}

最后

以上就是可靠月光为你收集整理的前端性能优化、二进制、流(Stream)、缓冲区(Buffer)、图片文件转Base64,Base64转Blob,Blob转File对象、js和css与dom执行关系、游览器进程、woker、new的全部内容,希望文章能够帮你解决前端性能优化、二进制、流(Stream)、缓冲区(Buffer)、图片文件转Base64,Base64转Blob,Blob转File对象、js和css与dom执行关系、游览器进程、woker、new所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部