备战校招第三天
css 垂直水平居中
闭包
浏览器缓存相关
性能优化
css 垂直水平居中
第一种 position+transform1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 <style>
#box {
width: 800px;
height: 800px;
background-color: gray;
position: relative;
}
#cbox {
width: 300px;
height: 300px;
background-color: orange;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<body>
<div id="box">
<div id="cbox"></div>
</div>
</body>
第二种 flex1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<style>
#box {
width: 800px;
height: 800px;
background-color: gray;
display: flex;
align-items: center;
justify-content: center;
}
#cbox {
width: 300px;
height: 300px;
background-color: orange;
}
</style>
<body>
<div id="box">
<div id="cbox"></div>
</div>
</body>
第三种 padding + margin1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<style>
#box {
width: 800px;
height: 800px;
background-color: gray;
box-sizing: border-box;
padding: 250px 0;
}
#cbox {
width: 300px;
height: 300px;
background-color: orange;
margin: 0 auto;
}
</style>
<body>
<div id="box">
<div id="cbox"></div>
</div>
</body>
以上三种代码显示效果均为
闭包
闭包可以从内部函数访问到外部函数作用域。
模拟私有方法
Java有私有属性,
private
,而 js 也可以通过模拟来实现私有变量和方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27var makeCounter = function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
};
var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */经典闭包问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
var btns = document.getElementsByTagName('button')
for (var i = 0; i < btns.length; i++) {
var btn = btns[i]
btn.onclick = function () {
console.log('点击了第' + i + '个按钮')
}
}
</script>运行上面代码,点击会发现,输出的均为
这是因为虽形成了三个闭包作用域,但他们共享了一个词法作用域,在这个作用域中又只有一个变量
i
,var
的作用域数函数作用域,但定义i
外并未有函数,所以这里的i
是挂载在全局的。在循环后执行点击时间前,i
的值都已经指向了最后一个数5
了。解决方法(修改下列任何一种都可以)
将
var i=0;
换为let i=0;
,这种也是最简单的,let
是 ES6 修复var
的设计缺陷而出现的使用更多的闭包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
function handleClick(i) {
return function() {
console.log('点击了第' + i + '个按钮')
}
}
var btns = document.getElementsByTagName('button')
for (var i = 0; i < btns.length; i++) {
var btn = btns[i]
btn.onclick = handleClick(i)
}
</script>匿名闭包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
var btns = document.getElementsByTagName('button')
for (var i = 0; i < btns.length; i++) {
;(function (i) {
var btn = btns[i]
btn.onclick = function () {
console.log('点击了第' + i + '个按钮')
}
})(i)
}
</script>
性能
在处理速度和内存消耗方面都是有负面影响,所以原则是少用,别再不必要的地方使用。
缓存相关
浏览器缓存机制
强缓存
浏览器加载资源前,会根据请求头 expires
和 cache-control
判断是否命中强缓存,如果命中,则不会发送请求到服务器。
Expires
http1.0 提出,表示资源过期时间的 header,描述为一个绝对时间,服务器返回。(如果修改本地时间,可能会造成缓存失效。)1
expires: Tue, 14 Jul 2020 13:13:53 GMT
Cache-Control
http1.1 提出,优先级高于 Expires
,表示相对时间
缓存请求指令1
2
3
4
5Cache-Control: max-age=<seconds>
Cache-Control: max-stale[=<seconds>] // 表示客户端接受一个已过期的资源
Cache-Control: min-fresh=<seconds> // 表示客户端获取一个在指定的秒数内保持最新状态的响应
Cache-control: no-cache // 在发布缓存前,强制要求把缓存提交给服务器进行验证(协商缓存验证)
Cache-control: no-store // 不存储和不使用任何缓存
缓存响应指令1
2
3
4
5
6
7Cache-control: must-revalidate
Cache-control: no-cache // 如缓存请求指令
Cache-control: no-store // 如缓存请求指令
Cache-control: public // 表示响应可以为任何对象(客户端、代理服务器等,包括通常不可缓存的
Cache-control: private // 只能被单个用户缓存(私有缓存)
Cache-Control: max-age=<seconds> // 缓存存储最大周期,单位秒
Cache-control: s-maxage=<seconds> // 覆盖 max-age或 expires 头,仅在共享缓存中有效
协商缓存
如果没有命中强缓存,浏览器会发送一个请求到服务器,通过 last-modified
和 etag
验证资源是否命中协商缓存,如果命中,会将这个请求返回,但不返回资源的数据,依旧从缓存中读取资源。
Last-Modified 和 If-Modified-Since
http1.0 引入,Last-Modified
是响应头中的属性,表示资源的修改时间。浏览器请求时会在请求头上加上 If-Modified-Since
(上次返回的Last-Modified
的值),询问是否资源有更新,如有立刻将新的资源返回。
准确性不如 Etag
,所以这个为备用机制。
ETag 和 If-None-Match
http1.1 引入,Etag
就像一个指纹,资源变化都会导致ETag变化,跟最后修改时间没有关系,ETag
可以保证每一个资源是唯一的。优先级高于 Last-Modified
。
If-None-Match
的header会将上次返回的Etag
发送给服务器,询问该资源的Etag
是否有更新,有变动就会发送新的资源回来
异同点总结
- 相同点,都是从客户端缓存中加载资源,而不是从服务器加载资源。
- 不同点,强缓存不发送请求到服务器,协商缓存会发送请求到服务器。
缓存优先级顺序(由低到高)
强缓存
- Expire
- Cache-Control
协商缓存
- Last-Modified 和 If-Modified-Since
- ETag 和 If-None-Match
用户操作和行为
- 普通F5刷新,强缓存失效,只进行协商缓存
- Ctrl+F5刷新,强缓存和协商缓存均失效
性能优化
图片优化,可以减少 http
请求数量
- 雪碧图、精灵图
- Base64
- 字体图标
压缩资源大小
- HTML压缩
- css 压缩
- js 压缩与混淆
- 图片压缩,(可以尝试webp格式)
- 开启 gzip
缓存
- DNS 缓存
- http 缓存
- 浏览器缓存
其他优化
数据校验,避免无用数据重复发送
不使用
css @import
比如你使用空的 src 和 href(会重定向到当前页面地址)
使用CDN
减少重绘回流
webpack 打包使用优化插件
参考
闭包
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
缓存
https://github.com/amandakelake/blog/issues/41
https://segmentfault.com/a/1190000021248694
性能优化
https://www.cnblogs.com/xiaohuochai/p/9178390.html