1. 1. 资源压缩合并,减少HTTP请求
  2. 2. 非核心代码异步加载
    1. 2.1. 异步加载的方式
    2. 2.2. 异步加载的区别
  3. 3. 浏览器缓存
    1. 3.1. 强缓存的响应头多了
    2. 3.2. 协商缓存的响应头
    3. 3.3. 协商缓存的请求头
  4. 4. 使用CDN
  5. 5. DNS预解析
  6. 6. 使用GZip压缩
  7. 7. 其他

如果遇到这题,需要明白,面试官实质要问的就是前端性能优化

前端性能优化可以分为执行性能加载性能

执行性能 即代码运行过程中的性能优化,常见的如:避免不必要的DOM操作,避免深层次的html元素嵌套,图片懒加载,CSS的代码顺序,减少冗余的js代码……执行性能与每个开发者的技能水平相关,也需要开发者提高对自身的要求。更重要的是执行性能并非本文关注的重点。

加载性能 即在相同的网络环境下,使资源更快的加载回来。接下来介绍一些可以明显提升加载性能的方法。

资源压缩合并,减少HTTP请求

  • 雪碧图,图片整合
  • JS资源合并
  • CSS合并

非核心代码异步加载

常规的html解析执行顺序是,当html解析碰到script 标签或者link 标签,它会去加载js 文件,文件加载回来之后会立即开始执行,等到 JS 执行完成,才会接着继续往下解析HTML (CSS加载回来后不会阻塞后续执行,可以查看”在浏览器输入一个地址发生了什么“的流程图)。也就是说JS 的加载执行会阻塞页面渲染,所以这也就是我们倡导将JS 的加载放在body 之后。

什么是异步加载呢,也就是当碰到需要加载JS 文件时,你去加载,但不阻塞HTML的后续解析。

异步加载的方式

  1. 动态脚本加载 :使用JS去创建Script节点
  2. defer<script src="defer.js" defer></script>
  3. async<script src="async.js" async></script>

异步加载的区别

  1. defer 是在HTML解析完成之后才会执行;async 是在加载完成之后立即执行。
  2. 如果是异步加载多个JS文件,defer 会按照加载的顺序依次执行,async 会根据JS文件的加载完成顺序执行。

如果一个页面异步加载了多个JS文件,使用defer 的话,它会根据加载顺序[1,2,3,4]来执行,也就是如果2,3,4已经加载完成,但1还没有加载完成,它会等1加载完成之后,按照1,2,3,4顺序执行。

使用async 它会根据加载完成的顺序来执行,例如加载顺序是[1,2,3,4],但加载完成顺序和网络与文件大小相关,有可能加载完成顺序是[2,1,3,4]也有可能是[4,2,3,1],他根据加载完成顺序执行

浏览器缓存

浏览器缓存分为 强缓存协商缓存

强缓存的响应头多了

  • Expires 过期时间,服务器的绝对时间
  • cache-Control 缓存时间,相对于浏览器,默认3600秒

协商缓存的响应头

  • Last-Modified 资源最后修改时间
  • Etag 资源的hash值(文件内容不变,hash不会变)

协商缓存的请求头

  • If-modified-Since 资源最后修改时间
  • If-None-Match 资源的hash值

协商缓存只有文件的hash值改变才能确定文件真的更新了;最后更新时间改了,但资源内容不变,依旧使用缓存

使用CDN

使用CDN是可以很明显提升页面性能的,但现在的前端项目大多数人习惯了使用npm install ,然后import 导入,反而不太熟悉怎么怎么在现代前端项目中使用CDN了。

关于怎么在现代工程化的项目中使用CDN可以看我这篇文章https://juejin.im/post/5d46378a5188255d845fff71

DNS预解析

”在浏览器输入一个地址发生了什么“ 一文中,我们说了,输入地址后第一步就是进行DNS解析,如果一个页面加载了n多资源,n多 a 标签,这些内容也是需要进行DNS解析的,提前进行DNS解析,也是可以很大程度提高前端性能的。

DNS预解析就两行代码。

强制打开DNS

1
<meta http-equiv="x-dns-prefetch-control" content="on">

预解析特定域名,href 填写你要预解析的域名

1
<link rel="dns-prefetch" href="//hm.baidu.com">

使用GZip压缩

启用GZip压缩可以非常明显看到速度提升,关于如何开启GZip压缩可以看 恰运维一口饭之启用GZIP压缩

其他

更多的性能优化内容可以看看雅虎军规