网络相关优化
dns预解析
dns解析也是需要时间的, 可以通过预解析的方式来预先获得域名所对应的ip
<link rel="dns-prefetch" href="//baidu.com"></link>
缓存
强缓存
实现强缓存可以通过响应头实现: Expires
和 Cache-Control
强缓存表示在缓存期间不需要请求, state code
为200
Expires: Wed, 22 Oct 2019 09:41:00 GMT
Expires
是http1.0的产物, 表示资源会在Wed, 22 Oct 2019 09:41:00 GMT
后过期, 需要再次请求, 并且Expires
受限于本地时间,如果修改了本地时间, 可能会造成缓存失效
Cache-control: max-age=30
Cache-Control
出现于http1.1 优先级高于Expires
, 该属性表示资源会在30秒后过期, 需要再次请求
协商缓存
如果缓存过期了,我们就可以使用协商缓存来解决问题。协商缓存需要请求,如果缓存有效会返回 304。
协商缓存需要客户端和服务端共同实现,和强缓存一样,也有两种实现方式。
Last-Modified 和 If-Modified-Since
Last-Modified
表示本地文件最后修改日期, If-Modified-Since
会将 Last-Modified
的值发送给服务器, 询问服务器在该日期后资源是否跟新,有更新的花就将新的资源发送过来.
但是如果在本地打开缓存文件, 就会造成Last-Modified
被修改, 所以在http1.1出现了ETag
Etag 和 If-None-Match
ETag
类似与文指纹, If-None-Matc
会将当前ETag
发送给服务器,询问该资源ETag
是否变动,有变动的话就把新的资源发送过来, 并且ETag
优先级高于Last-Modified
选择合适的缓存策略
对于大部分的场景都可以使用强缓存配合协商缓存解决,但是在一些特殊的地方可能需要选择特殊的缓存策略
- 对于某些不需要缓存的资源,可以使用 Cache-control: no-store ,表示该资源不需要缓存
- 对于频繁变动的资源,可以使用 Cache-Control: no-cache 并配合 ETag 使用,表示该资源已被缓存,但是每次都会发送请求询问资源是否更新。
- 对于代码文件来说,通常使用 Cache-Control: max-age=31536000 并配合策略缓存使用,然后对文件进行指纹处理,一旦文件名变动就会立刻下载新的文件。
预加载
有些资源不需要马上用到,但是希望今早获取, 这时候就可以使用预加载
预加载是声明式的fetch
, 强制浏览器请求资源, 并且不会阻塞window.onload
事件
script async defer
- script: 当浏览器执行html的时候如果遇到一个没有任何属性的script标签, 就会暂停解析, 先发送网络请求,获取该js脚本, 然后执行js代码, 当代码执行完毕后回复解析.
- async: 表示异步,当浏览器遇到带有async属性的script时, 请求该脚本的网络请求是异步的,不会阻塞浏览器解析html, 一旦网络请求回来之后, 如果html没有解析完, 浏览器会暂停解析,先让js引擎执行代码, 执行完毕后在进行解析html, 当然如果js脚本请求回来之前html, 解析完毕了 , 就立即执行js代码, 所以async 是不可控的,完全依赖网络传输结果,谁先到,谁先执行.
- defer:表示延迟, 当浏览器遇到defer属性, 获取该脚本的网络请求也是异步的, 不会阻塞浏览器解析html, 一旦网络请求回来后, 如果此时html,没有解析完, 会等待html解析完毕后,执行js脚本. 如果存在多个defer script ,会保证他们按照html中出现的顺序, 不会破坏js脚本之间的依赖关系