代码方面
不管用哪种框架或者是原生js生态,给代码瘦身都是必要的,减少重复性代码,比如:
给公共的功能进行封装实现一对多的调用,重复的样式封装成公共的,重复的方法进行封装挂在到vue原型上或者按需加载包括路由的懒加载。然后把主组件的代码进行分离,css和js都用外联,这会比内置要快,因为浏览器在首次打开页面的时候会把外链的文件给下载缓存下来,这样二次进入的时候就会顺畅和快很多。
托管平台cdn
使用cdn加速也是可以对整个项目有很大的优化,用cdn就可以把路由、axios。vuex等等引入全部给干掉去cdn平台上直接复制相对应的连接引入就可以了
HTTP缓存
HTTP 有一系列的规范来规定哪些情况下需要缓存请求信息、缓存多久,而哪些情况下不能进行信息的缓存。我们可以通过相关的 HTTP 请求头来实现缓存。HTTP 缓存大致可以分为强缓存与协商缓存。
强缓存
在强缓存的情况下,浏览器不会向服务器发送请求,而是直接从本地缓存中读取内容,这个“本地”一般就是来源于硬盘。这也就是我们在 Chrome DevTools 上经常看到的「disk cache」。在 Expires 上可以设置一个过期时间,浏览器通过将其与当前本地时间对比,判断资源是否过期,未过期则直接从本地取即可。而 Cache-Control 则可以通过给它设置一个 max-age,来控制过期时间。例如,max-age=300 就是表示在响应成功后 300 秒内,资源请求会走强缓存。
协商缓存
协商缓存是为了解决这样的问题:如果服务器在300秒内更新了资源,需要怎么让客户端知道并更新。
一种协商缓存的方式是:服务器第一次响应时返回Last-Modified,而浏览器在后续请求时带上其值作为If-Modified-Since,相当于问服务端:XX 时间点之后,这个资源更新了么?服务器根据实际情况回答即可:更新了(状态码 200)或没更新(状态码 304)。
上面是通过时间来判断是否更新,如果更新时间间隔过短,例如 1秒 一下,那么使用更新时间的方式精度就不够了。所以还有一种是通过标识 —— ETag。服务器第一次响应时返回ETag,而浏览器在后续请求时带上其值作为If-None-Match。一般会用文件的 MD5 作为 ETag。
浏览器缓存
当所有缓存都没有命中时候则会进入浏览器缓存,浏览器缓存主要分为
Service Worker
Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的
Memory Cache
内存中的缓存,内存缓存在缓存资源时并不关心返回资源的HTTP缓存头Cache-Control是什么值,同时资源的匹配也并非仅仅是对URL做匹配,还可能会对Content-Type,CORS等其他特征做校验。
Disk Cache
存储在硬盘中的缓存,它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。并且即使在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据
Push Cache
推送缓存当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂,在Chrome浏览器中只有5分钟左右,同时它也并非严格执行HTTP头中的缓存指令。
minifest(离线缓存)
不建议使用
发送请求
避免不必要的重定向
在一些情况下,你可能进行了服务迁移,修改了原有的 url。这时候就可以使用重定向,把访问原网址的用户重定向到新的 url。还有是在一些登录场景下,会使用到重定向技术。
重定向分为 301 的永久重定向和 302 的临时重定向
但是不要滥用重定向,每次重定向都是有请求耗时的,建议避免过多的重定向
在定义链接地址的href属性的时候,尽量使用最完整的、直接的地址 例如: 错误示范 | 正确示范 :-: | :-: http://baidu.com | http://www.baidu.com | http://www.a.com/a | http://www.a.com/a/|
DNS预解析
基本我们访问远程服务的时候,不会直接使用服务的出口 IP,而是使用域名。所以请求的一个重要环节就是域名解析。这是一个比较耗时的过程,我们可以通过以下手段进行加速
DNS Prefetch
提前解析将要使用的DNS
<link rel="dns-prefetch" href="//m1.lefile.com">
preconnect
不仅要求浏览器预解析指定域名的DNS,还需要预先链接
<link rel="preconnect" href="//m1.lefile.cn/" crossorigin="anonymous" />
prefetch
要求浏览器获取整个的指定资源但是不允许浏览器对资源做预处理和执行(告诉浏览器页面可能需要的资源,浏览器不一定会加载这些资源)
<link rel="prefetch" href="//p1.lefile.cn/fes/cms/2018/11/23/4tz6y9vx1ktskvw86pxr56uw8bu7gx527894.png" crossorigin as="image" />
preload
与prefetch差不多,但它会告诉浏览器页面必定需要的资源,浏览器一定会加载这些资源
<link rel="preload"" href="https://p1.lefile.cn/fes/cms/2018/11/23/4tz6y9vx1ktskvw86pxr56uw8bu7gx527894.png" crossorigin as="image" />
prerender
允许浏览器对资源做预处理和执行
<link rel="prerender" href="https://m2.lefile.cn/global/js/jquery-1.11.1.min.js" />
上面的方法需要在head里面添加:
减少网络发送的数据量
- 部分资源可考虑采用内联
- 静态资源采用浏览器缓存,时间要长
- 删除无用的代码
减少关键资源的数量,移除非关键渲染资源
- css默认会生成cssom。通过非关键资源拆出来,单独外联引入,增加media,则浏览器只会下载,不会解析(用到的时候解析)。但是此时额外增加了网络请求,需要权衡
- js执行会等待cssom构建完毕,并且会阻塞dom的构建。动态引入js