前端性能优化垃圾回收,闭包,跨域
Posted 别Null.了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端性能优化垃圾回收,闭包,跨域相关的知识,希望对你有一定的参考价值。
目录
将 CSS 放在文件头部,JavaScript 文件放在底部
前端性能优化
前端性能优化的目的:
1、从用户角度而言:优化可以使页面加载速度更快,对用户的操作响应更加及时,增加用户的体验感。
2、从服务器角度而言:优化可以减少页面的请求次数,节约资源。
减少HTTP请求
一个完整的 HTTP 请求需要经历 DNS 查找,TCP 握手,浏览器发出 HTTP 请求,服务器接收请求,服务器处理请求并发回响应,浏览器接收响应等过程。
1、css和js 文件合并压缩
因此在项目中我们可以将css或者js文件进行合并或者压缩,在移动端开发时可以采用内嵌式,以此减少http的请求次数,加快页面加载速度。
2、用图标代替图片
使用字体图标代替一些页面中的图片,这样不仅做适配的时候方便,而且更加轻量级,而且减少了htttp请求次数。(例如antd中的图标icon中的CloseOutlined就代表红色的删除符号)。
使用服务器端渲染
客户端渲染过程
- 访问客户端渲染的网站。
- 服务器返回一个包含了<div id='app'></div>的html文件。
- 客户端通过HTTP向服务器请求资源,当必要的资源都加载完毕后,渲染页面。
服务器端渲染过程
- 访问服务器端渲染的网站。
- 服务器填充当前路由组件需要的资源文件到HTML文件中;若有ajax请求则会执行它并填充到HTML文件里,最后返回这个HTML页面。
- 客户接收到HTML页面就开始渲染页面,此时页面也会加载资源,当必要资源加载完成后接管页面。
从以上两个过程可以看出客户端渲染会直接返回HTML文件,而服务器端渲染的网站会渲染完页面再返回这个HTML文件。
举个例子:若一个网站里有四个文件,则客户端渲染的网站需要加载四个文件和HTML文件才能完成首页渲染;而服务器端渲染的网站只需要加载一个渲染完毕的HTML文件就能完成首页渲染。这就是服务器端渲染更快的原因。
将 CSS 放在文件头部,javascript 文件放在底部
原因:CSS 执行会阻塞渲染,阻止 JS 执行,JS 加载和执行会阻塞 HTML 解析。
将css文件放在头部: 因为先加载HTML再加载css,会让用户先看到的页面没有样式,为了避免此情况发生会选择将css文件放在头部。
将js文件放在底部:若css,js标签放在head标签里并且需要加载和解析很久的话会使得页面空白,将js文件放在底部(不阻止DOM解析,会阻塞渲染),等HTML解析完再加载js文件就会今早向用户呈现页面内容。
更多使用异步编程
同步编程会导致上面的东西完不成,下面任务也做不了,开发的时候可以把某一个区域模块都设置为异步编程,这样只要模块之间没有必然的先后顺序,都可以独立进行加载,不会受到上面模块的堵塞影响。(在ajax数据请求中一般都使用异步编程,并使用基于promise的模式进行管理)。
ES6新特性
let,const,var的区别以及箭头函数
解构赋值
数组的解构
ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值。之前想要获取其中的值,只能通过下标。
let arr = [1,2,3];
const [a,b,c] = arr; // a,b,c将与arr中的每个位置对应来取值
console.log(a,b,c); //输出为:1,,,,3
const [x] = arr; // 只匹配一个参数值
console.log(x); //输出为:1
对象的解构
const person = { //定义一个对象
name: "Tom",
age: 20,
language: ['Java','JavaScript','Python']
}
const {name,age,language} = person; // {}内的属性名必须是person的属性名
console.log(name); //输出为:Tom
console.log(age); //输出为:20
console.log(language); //输出为:'Java','JavaScript','Python'
// 如果想用其他变量接收,需要指定别名
const {name:n} = person;
console.log("n: ",n); //输出为:n:Tom
模板字符串
ES6中提供了 `` (反引号)来作为字符串模板标记。
<script type="text/javascript">
let str = `hello Java and JavaScript `;
console.log(str);
</script>
map()和reduce()方法
在ES6中,数组新增了map()
和 reduce()
方法 。
map()
:接收一个函数,将原数组中的所有元素用这个函数处理后放入新的数组返回。
let arr = ['1','2','3','4']
console.log(arr); //输出为:['1','2','3','4']
let newArr = arr.map(s => parseInt(s));
console.log(newArr); //输出为:[1,2,3,4]
reduce()
:接收一个函数(必须)和一个初始值(可选),该函数接收两个参数:第一个参数是上一次reduce处理的结果,第二个参数是数组中要处理的下一个元素
class(类)的基本语法
JavaScript的传统方法是通过构造函数定义并生成对象。ES6中引入了class
的概念,通过class
关键字自定义类。
//定义类
class Person{
constructor(name){
this.name = name;
}
}
//使用类创建对象
var p1 = new Person('张三') //创建p1对象
var p2 = new Person('李四') //创建p2对象
console.log(p1.name); //访问p1对象的name属性
console.log(p2.name); //访问p2对象的name属性
Symbol
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第7种数据类型,是一个类似字符串的数据类型。
- Symbol的值是唯一的,用来解决命名冲突的问题。
- Symbol值不能与其他数据进行运算,也不能与自己进行运算,譬如+、-、*、/、比较运算。
- Symbol定义的对象属性不能使用for…in遍历。
ES6新特性不止这些 ...
垃圾回收机制
为了解决内存的泄露,垃圾回收机制会周期性的找出那些不再用到的内存(变量),然后释放其内存。
标记清除法
标记清除法分为标记阶段和清除阶段。
当变量进入执行环境(函数中声明变量)的时候,垃圾回收器将其标记为“进入环境”,当变量离开当前环境进入另一个环境时(此函数执行结束)的时候将其标记为“离开环境”,等到垃圾回收执行时,会根据标记来决定要清除哪些变量。
引用计数法
此方法会引起内存泄漏。其原理是在变量进入环境时跟踪一个引用类型值的引用次数,即当声明一个变量并将一个引用类型赋值给该变量时该值引用次数加1,当这个变量指向其他时该值引用次数减一,当它的引用次数变为0时就会被回收。
闭包
闭包就是能够读取其他函数内部变量的函数。闭包可以理解成“定义在一个函数内部的函数”。闭包让这些变量始终保存在内存中,不会随着函数的结束而自动销毁。
闭包简单应用:累加器
function add(){
var num = 0;
function a(){
console.log(++num); //读取外函数定义的num值
}
return a;
}
var myAdd = add();
myAdd(); //输出为:1
myAdd(); //输出为:2
跨域的几种方式
同源:
- 同协议:都是为http或者https;
- 同域名:比如http://a.com/index.html 与http://a.com/server.js 的域名一致;
- 同端口:端口号一致(如同为8089);
JSONP方式
利用html里面的script标签可以加载其他域下的js文件,使用<script src=""></script>的形式获取其他域下的数据;但是获取到的数据是json格式,因此需要提前将返回的数据包装,封装成函数进行运行(所获得的数据作为函数的参数传递),函数名通过接口传参的方式传给后台,后台解析到函数后再发送给前端。
CORS方式
CORS全称是跨域资源共享,是一种 ajax 跨域请求资源的方式。
当我们在运行项目文件需要使用CORS跨域请求时,需先安装cors跨域模块:npm install cors
以上是关于前端性能优化垃圾回收,闭包,跨域的主要内容,如果未能解决你的问题,请参考以下文章