本系列目录:【前端八股文】目录总结
是以《代码随想录》八股文为主的笔记。详情参考在文末。
代码随想录的博客_CSDN博客-leecode题解,ACM题目讲解,代码随想录领域博主
具体可以看:【JavaScript高级】浏览器原理:渲染引擎解析页面步骤、回流和重绘、composite合成、defer与async_karshey的博客
用户看到的页面分为两个阶段:页面内容加载完成DOMContentLoaded
和 页面资源加载完成Load
阶段。
DOMContentLoaded
事件触发时,仅DOM加载完成load
事件触发时,页面上所有DOM、样式、脚本、图片都加载完成渲染步骤大致分为以下6步:
注意:以上步骤不一定一次性顺序完成。比如DOM树或CSS树被修改时,这些操作会重复执行。
DOM树与render树不完全对应:
display:none
的元素在DOM树中,但不在render树中visibility:hidden
的元素在render树中回流reflow:浏览器布局发生变化后,要倒回去重新渲染。这个回退过程为回流。
重绘repaint:改变某个元素的背景色、文字颜色等不影响周围和内部布局的属性时,会引发重绘。
注意:
display:none
会触发回流,因为它不在render树中,改变了render布局visibility:hidden
只会触发重绘,它的语义是隐藏元素,元素仍然占据布局空间,只是渲染成一个空框。此属性的改变不会改变布局,因此只触发重绘。引起回流
现代浏览器会对回流做优化,它会等到足够数量的变化发生,再做一次批处理回流。
浏览器为了获得正确的值也会提前触发回流,这样就使得浏览器的优化失效了,这些属性包括offsetLeft、offsetTop、offsetWidth、offsetHeight、 scrollTop/Left/Width/Height、clientTop/Left/Width/Height、调用了getComputedStyle()。
引起重绘
减少回流与重绘
display:none
,操作完再显示(display:none
不再render树内,则render不会发生改变,不会引发回流重绘)路由:根据不同的URL展示不同的页面。
单页面应用中的路由分为hash
和history
模式。
#
拼接在真实URL后面的模式#
后的路径发生变化时,浏览器不会重新发起请求,而会触发hashchange
事件优点:
缺点:
#
符号,略丑在H5之前,已经有history对象了,只能用于多个页面的跳转:
history.go(n) // n>0前进n页;n<0后退n页
history.forward() // 前进一页
history.back() // 后退一页
H5新增了两个API:
/*
参数说明:
state:合法的JavaScript对象,可以用在popstate对象中
title:标题,基本忽略,用null
url: 任意有效的url,将要跳转的新地址
*/
history.pushState(state, title, url) // 保留现有记录的同时,将url加到历史记录中
history.replaceState(state, title, url) // 将历史记录中的当前页面替换成url
history.state // 返回当前状态对象
pushState
和replaceState
可以改变URL,但不会刷新页面,浏览器也不会向服务器发送请求。
对于单页面的history模式,URL的改变只能由一下情况引起:
history.pushState
或history.replaceState
onhashchange()
事件,查找对应路由规则;history利用H5新增的pushState()
和replaceState()
方法改变url讲的很清晰:前端缓存(浏览器缓存和http缓存)详解_前端浏览器缓存_hyupeng1006的博客-CSDN博客
前端缓存技术方法主要分为http缓存和浏览器缓存。
http缓存:
浏览器缓存:
主要内容是HTTP缓存。
HTTP缓存是:可以自动保存常见文档副本的HTTP设备。当web请求抵达缓存时,若本地有“已缓存”的副本,则可以从本地存储设备提取这个文档,而非原始服务器。
HTTP缓存的优缺点:
优点
缺点
HTTP缓存分为:
不需要发送请求到服务器,直接读取浏览器本地缓存。 是否强缓存由Expires
、Cache-Control
、Pragma
这3个Header属性控制。
Expires
Expires 的值是一个 HTTP 日期,在浏览器发起请求时,会根据系统时间和 Expires的值进行比较,如果系统时间超过了 Expires的值,缓存失效。由于和系统时间进行比较,所以当系统时间和服务器时间不一致的时候,会有缓存有效期不准的问题。Expires的优先级在三个 Header 属性中是最低的。
在Cache-Control
可以用的时候,Expires
属性被废弃。
Cache-Control
Cache-Control 是 HTTP/1.1 中新增的属性,在请求头和响应头中都可以使用,常用的属性值如下:
max-age
:单位是秒,缓存时间计算的方式是距离发起的时间的秒数,超过间隔的秒数缓存失效no-cache
:不使用强缓存,需要与服务器验证缓存是否新鲜no-store
:禁止使用缓存(包括协商缓存),每次都向服务器请求最新的资源private
:专用于个人的缓存,中间代理、CDN 等不能缓存此响应public
:响应可以被中间代理、CDN 等缓存must-revalidate
:在缓存过期前可以使用,过期后必须向服务器验证Pragma
Pragma 只有一个属性值,就是
no-cache
,效果和 Cache-Control 中的 no-cache一致,不使用强缓存,需要与服务器验证缓存是否新鲜,在 3 个头部属性中的优先级最高。
协商缓存,就是与服务端协商后,通过协商结果来判断是否使用本地缓存。
当浏览器的强缓存失效的时候或者请求头中设置了不走强缓存,并且在请求头中设置了
If-Modified-Since
或者If-None-Match
的时候,会将这两个属性值到服务端去验证是否命中协商缓存,如果命中了协商缓存,会返回 304 状态,加载浏览器缓存,并且响应头会设置Last-Modified
或者ETag
属性。
Last-Modified/If-Modified-Since
Last-Modified/If-Modified-Since
的值代表的是文件的最后修改时间。
第一次请求服务端会把资源的最后修改时间放到Last-Modified
响应头中。
第二次发起请求的时候,请求头会带上上一次响应头中的 Last-Modified 的时间,并放到If-Modified-Since
请求头属性中。
服务端根据文件最后一次修改时间和 If-Modified-Since的值进行比较,如果相等,返回 304 ,并加载浏览器缓存。
Last-Modified/If-Modified-Since的缺点:
ETag/If-None-Match
Last-Modified/If-Modified-Since的上述缺陷,可以用ETag/If-None-Match来弥补。
ETag:就是将原先协商缓存的比较时间戳改为比较文件指纹。文件指纹:根据文件内容计算出的唯一哈希值。文件内容改变则文件指纹改变。
ETag/If-None-Match 的值是一串
hash
码,代表的是一个资源的标识符,当服务端的文件变化的时候,它的hash码会随之改变,通过请求头中的 If-None-Match 和当前文件的 hash 值进行比较,如果相等则表示命中协商缓存。
关于ETag:
Last-Modified/If-Modified-Since
与ETag/If-None-Match
的关系:
不同于cache-control是expires的完全替代方案(翻译:能用cache-control就不要用expiress)。ETag并不是last-modified的完全替代方案,而是last-modified的补充方案(翻译:项目中到底是用ETag还是last-modified完全取决于业务场景,这两个没有谁更好谁更坏)。
先说结论:有哈希值的文件名设置强缓存,没有哈希值的文件(比如index.html)设置协商缓存。
哈希值,如红色划线部分:
原因:一般来说,文件名中的哈希值是由webpack等工具打包完成后自动生成的。若对相同的文件再打包一次,文件名会生成不同的哈希值。不同的文件名对协商缓存来说是不同的文件。因此文件名中有哈希值的要用强缓存。
当然,文件名是否生成哈希值是可以配置的,也因不同的框架而已。
Pragma
>cache-control
>Expires
Etag
或last-modified
,根据业务场景选择适合的方案详情查看:前端缓存与本地存储_前端本地储存是缓存吗_dayTimeAffect的博客-CSDN博客
缓存在如下四个地方,查找缓存的优先级会依次从上到下匹配,若都没命中就会去请求网络资源。
service worker
Memory Cache
Disk Cache
使用哪个?
常用的有:
存储大小
数据有效性
作用域
通信
浏览器渲染原理与过程 - 简书 (jianshu.com)
浏览器的渲染:过程与原理 - 知乎 (zhihu.com)
10分钟看懂浏览器的渲染过程及优化 - 掘金 (juejin.cn)
【JavaScript高级】浏览器原理:渲染引擎解析页面步骤、回流和重绘、composite合成、defer与async_karshey的博客-CSDN博客
前端路由模式详解(hash和history) - 掘金 (juejin.cn)
hash和history两种模式的区别 - 琴时 - 博客园 (cnblogs.com)
【面试】前端路由hash和history的区别_sqwu的博客-CSDN博客
hash模式和history模式浅识_spark-chen的博客-CSDN博客
前端缓存详解 - 简书 (jianshu.com)
彻底弄懂前端缓存 - 掘金 (juejin.cn)
前端缓存(浏览器缓存和http缓存)详解_前端浏览器缓存_hyupeng1006的博客-CSDN博客
图解 HTTP 缓存 - 掘金 (juejin.cn)
彻底弄懂前端缓存 - 掘金 (juejin.cn)
前端缓存与本地存储 - 掘金 (juejin.cn)