网络层面的优化
1.webpack 性能调化与 Gzip 原理。
webpack 的优化的瓶颈:构建时间长,打包体积大。
构建时间长的
方案
:
不要让loader作太多事情,用include或exclude避免不须要的转译(node_modules);开启缓存将转译结果缓存至文件系统
(
loader:
'babel-loader?
cacheDirectory
=true'
)。
不要放过第三方库,
DllPlugin这个插件会把第三方库单独打包到一个单纯的依赖库的文件中。这个依赖库不会跟着你的业务代码一块儿被从新打包,只有当依赖自身发生版本变化时才会从新打包。
将loader由单进程转为多进程,
Happypack
把任务分解给多个子进程去并发执行。
(
手动建立进程池,问号后面的查询参数指定了处理这类文件的HappyPack实例的名字,
new
HappyPack id 和 threadPool指定进程池
)
打包体积大的
方案
:
webpack-bundle-analyzer 文件结构可视化,找到致使体积大的缘由。
删除冗余代码,webpack4中配置 optimization.minimize 和 minimizer 字定义压缩删除相关操做。
按需加载
,
require
.ensure(dependencies, callback, chunkName)
Gzip
压缩
开启 Gzip,在 request hheaders中加上:
accept-encoding:gzip
原理:找出重复出现的字符串、临时替换它们从而使整个文件变小。
2.图片优化
不一样场景
选择不一样类型的图片
JPEG/JPG - 有损压缩,背景图、轮播图、Banner图。
PNG - 支持透明,体积大。色彩表现力强,对线条的处理更加细腻。小Logo、颜色简单对比度强的透明小图。
SVG - 文本文件、不失真、体积小。写入HTML、写入独立文件引入HTML。
Base64 - 文本文件、依赖编码、小图标解决方案。很是小的Logo。
CSS Sprites - 将小图标和背景合并到一张图片上,利用背景定位显示其中的部分。
WebP - 旨在加快图片加载速度的图片格式。
.jpg_.webp 格式来匹配不支持的状况。
3.浏览器缓存
浏览器缓存机制由四个方面,按照获取资源请求的优先级一次排列:
1.
Memory Cache
内存中的缓存。Base64 格式的图片。几乎永远能够被塞进去。可视做浏览器为了节省开销的“自保行为”。
2.
Service Worker Cache
独立于主线程以外的js线程。有install、active、working 三个阶段。一旦Service Worker被install,它将始终存在,只会在active与working之间切换,除非咱们主动终止它。
必须以 https 协议为前提。
3.
HTTP Cache
强缓存:
在缓存时间内不向服务器发起请求,过时以后才会发起请求。
cache-control :max-age=31536000
max-age 控制资源的有效期,时间长度内是有效的,单位是秒。
Cache-Control 的 max-age 比 expires 优先级更高。
no-cache 绕开浏览器,直接去向服务器确认该资源是否过时。
no-store 不使用任何缓存策略,只容许你直接向服务器发送请求、并下载完整的响应。
协商缓存:浏览器和服务器合做之下的缓存策略
若是服务器端提示缓存资源未改动(Not Modified),资源会被重定向到浏览器缓存,这种状况下网络请求对应的状态码是 304。
首次请求随着 Response Headers返回Last-Modified,随后请求会带上 If-Moodified-Since 的时间戳字段,比较二者的时间去执行对应的操做。变了会发起一个完整的响应内容,并在Response Headers返回新的Last-Modified值;不然返回304响应,不添加Last-Modified字段。弊端:内容没变也会从新请求;修改文件过快没发起请求。
Etag是由服务器未每一个资源生成的惟一的
标识字符串(基于文件内容编码的),Etag可以精准感知文件的变化。
首次请求能够在Response Headers得到一个最初的标识符字符串,下次请求在请求头带上值相同的、名为 if-None-Match 的字符串供服务端对比。
4.
Push Cache
HTTP2 在 server push 阶段存在的缓存。
在以上都没有命中才会去询问 Push Cache;
它存在于会话阶段的缓存,当session终止时,缓存也随之释放;
不一样页面只要共享了同一个 HTTP2 链接,那么他们就能够共享一个 Push Cache
4.本地储存
Cookie
为了维持状态;附着在 HTTP 请求上,在浏览器和服务器之间传输。
劣势:Cookie 不够大,只有 4KB;过量的 Cookie 会带来巨大的性能浪费,同一域名下的全部请求,都会写到Cookie。
Local Storage
持久化的本地储存,使其消失的惟一办法手动删除。
储存 Base64 格式的图片字符串;不常更新的 CSS、JS 等资源。
Session Storage
会话结束时,内存内容被释放。
储存上次访问的 URL 地址。
Web Storage
特性:
存储量5-10M。
位于浏览器端,不与服务端发生通讯。
API:
储存:setItem()
读取:getItem()
删除:removeItem()
清空:clear()
IndexedDB
一个运行在浏览器上的非关系型数据库。>250M 能够存储字符串、二进制数据。
能够看作是LocalStorage的一个升级。
5.CDN 缓存与回源
CDN 指的是一组分布在各个地区的服务器。这些服务器储存着数据的副本,所以服务器能够根据哪些服务器与用户距离最近,来知足数据的请求。CDN 提供快速服务,较少受高流量影响。
核心:
缓存 回源。
“缓存”就是咱们把资源 copy 一份到 CDN 服务器上这个过程,“回源”就是CDN发现本身没有这个资源(通常是缓存数据过时了),转头向根服务器去要这个资源的过程。
CDN 每每被用来存放静态资源。(CSS、JS、Image)
CDN 域名和服务器域名不一样。
渲染层面
1.服务端渲染
SSR 主要用于解决单页应用首屏渲染慢以及SEO问题,但同时:提升了服务器压力,吃CPU,内存等资源,优化很差提升成本。
Vue是如何实现
服务端渲染
的呢?
一是这个
renderToString
() 方法(把Vue实例转化为真实DOM的关键方法);
二是把转化结果“塞”进模板里。(res.end 把渲染出来的真实DOM字符串插入HTML模板中)
2.浏览器渲染 - CSS、JS性能方案
每一个页面首次渲染都经历了 解析HTML - 计算样式 - 计算图层布局 - 绘制图层 - 整合图层获得页面。HTML构建DOM树,CSS构建CSSOM树,CSSOM与DOM结合获得渲染树,最后浏览器以布局渲染树去计算布局,绘制图像。
CSS 选择器是从右到左进行匹配的。(避免使用通配符;用类选择器代替标签选择器;不要多此一举用id和class选择器;减小嵌套)。
CSS 的阻塞
,须要尽早(放在
head
标签里)和尽快(启用
CDN
实现静态资源加载速度优化)地下载到客户端,以便缩短首次渲染的实践。
JS 的阻塞
,JS 引擎抢走了渲染引擎的控制权。
async
和
defer
模式加载都是异步的,async 是当即执行的(用于DOM和脚本依赖不强),defer 是推迟执行的(等整个文档解析完成时,用于脚本依赖DOM和其余脚本的执行结果)。
3.DOM优化原理与基本思路
当咱们用JS操做DOM时,本质上时JS引擎和渲染引擎之间进行了“跨界交流”,依赖了桥接接口做为“桥梁”。减小DOM操做。
咱们对DOM修改会引起它外观上的改变时,就会出发回流(几何尺寸变化)或重绘(样式变化)。
减小DOM操做
:缓存变量;DOM Fragment。
4.事件循环和异步更新策略
事件循环优化:当咱们须要在异步任务中实现
DOM修改
时,把它包装成
micro
任务时相对明智的选择(不须要多消耗一次渲染,不须要等待下一事件循环)。macro - mincro - render。
异步更新:把任务塞到异步任务队列里,在JS层面被批量执行完毕。到渲染时,它仅仅须要针对有意义的计算结果操做一次DOM。(
避免过分渲染
)
使用Vue.nextTick()是为了能够获取更新后的DOM。在同一事件循环中的数据变化后,DOM完成更新,就会执行Vue.nextTick()的回调。过程是同一事件循环中的代码执行完毕 -> DOM 更新 -> nextTick callback触发。
5.回流和重绘
触发回流:改变DOM元素的几何属性;改变DOM树的结构;获取特定的值(即时计算获得)。
JS变量的形式缓存起来。
避免逐条改变样式,使用类名去合并样式(
el.classList.add(
'basic_style'
)
)。
将DOM离线(
display =
'none' ..添加样式..
display =
'block'
)
Flush队列(本身缓存一个flush队列,把任务塞进去,到必定时间再出队)。
应用篇
1.优化首屏体验 - Lazy-Load
图片懒加载
<img class="pic" alt="加载中" data-src="./images/1.png"> // 当前可视区域的高度 window.innerHeight || document.documentElement.clientHeight // 元素距离可视区域顶部的高度 getBoundingClientRect().top // 若是可视区域高度大于等于元素顶部距离可视区域顶部的高度,说明元素露出 imgs[i].src = imgs[i].getAttribute('data-src') num = i + 1
2.事件的节流和防抖
这两个东西都以
闭包
的形式存在。
它们经过对事件对应的回调函数进行包裹、以自由变量的形式缓存时间信息,最后用 setTimeout 来控制事件的触发频率。
节流的中心思想:在某段时间内,无论你触发了多少次回调,我都只认第一次,并在计时结束时给予响应。(
本次触发的时间-上次触发的时间 >= 设定的时间间隔阈值则执行回调
)
防抖的中心思想:我会等你到底。在某段时间内,无论你触发了多少次回调,我都只认最后一次。(
每次事件被触发时,都去清除以前的旧定时器,设立新定时器
)
性能检测
Performance
LightHouse
W3C性能API
缓存解决方案
强缓存
协商缓存
http缓存流程图
当咱们的资源内容不可复用时,直接为 Cache-Control 设置 no-store,拒绝一切形式的缓存;不然考虑是否每次都须要向服务器进行缓存有效确认,若是须要,那么设 Cache-control 的值为 no-cache;
不然考虑该资源是否能够被代理服务器缓存,根据其结果决定时设置为 private 仍是 public;而后考虑该资源的过时时间,设置对应的 max-age 和 s-maxage 值;最后,配置协商缓存须要用到的 Etag、Last-Modified 等参数。