前端的性能优化能够从网络层面和渲染层面两个维度来实现优化,网络层面主要指的是HTTP请求与响应过程,渲染层面指的是浏览器端或者说是客户端(包括浏览器和代理服务器等)。javascript
webpack的性能优化主要从两个方面着手,缩短构建时间和减少打包结果体积,优化方案有配置loader让它忽略掉指定文件夹的打包,将转译结果缓存、使用插件来优化(使用DllPlugin将第三方库单独打包到一个文件中;使用Happypack将loader由单进程转为多进程;使用webpack-bundle-analyzer可视化文件结构,找出致使体积过大的缘由;使用DllPlugin拆分资源;使用Tree-Shaking 和UglifJsPlugin删除冗余代码;使用require.ensure按需加载)。html
图片的优化就是在作权衡,由于咱们作的就是选择质量好的体积又小的图片格式,或者是压缩图片的体积又要保证图片的质量。图片优化咱们须要了解不一样图片格式的优缺点,它们适用的不一样业务场景,不谈业务场景的选型就是流氓。通常来讲,JPG适用于呈现色彩丰富的图片,好比大的背景图、轮播图或者Banner图;PNG适合用来呈现小的Logo,颜色简单且对比强烈的图片;SVG是一种更好的选择方式,它的体积更小,并且能够无限放大而不失真,可是它的渲染成本较高;Base64是做为雪碧图的补充而存在的,它不是图片格式,而是一种编码方式,咱们能够直接将编码结果写入 HTML 或者写入 CSS,从而减小 HTTP 请求的次数,主要用来呈现小图,小的logo;WebP是最年轻的一种图片格式,支持有损压缩和无损压缩,集多种图片的格式的优势于一身,可是的缺点就是兼容性很差,若是要使用WebP,就要作兼容性处理。前端
关于图片的优化有一些建议:vue
HTTP压缩就是以缩小体积为目的 ,对HTTP内容进行从新编码的过程。Gzip 压缩背后的原理,是在一个文本文件中找出一些重复出现的字符串、临时替换它们,从而使整个文件变小。根据这个原理,文件中代码的重复率越高,那么压缩的效率就越高,使用 Gzip 的收益也就越大。咱们知道服务端的Gzip压缩是消耗CPU的,因此咱们须要给服务器分压,咱们能够利用webpack中的gzip压缩来为服务端的gzip分压。java
缓存能够减少网络IO消耗,提升访问速度,通常咱们讲的浏览器能够简单理解为HTTP缓存,可是浏览器的缓存包括四个方面,首先是内存(Memory Cache),而后是Service Worker Cache,再是磁盘(Disk Cache,也就是HTTP Cache),最后是Push Cache。react
本地存储主要是Cookie,Web Storage(Local Storage和Session Storage)和IndexDB。Cookie能够用来存储用户爱好和购买记录,用户浏览过的网站,曾经点击过的广告等信息;Session Storage 更适合用来存储生命周期和它同步的会话级别的信息。这些信息只适用于当前会话,当你开启新的会话时,它也须要相应的更新或释放,好比微博的 Session Storage 就主要是存储你本次会话的浏览足迹;Local Storage 的特色之一是持久,有时咱们更倾向于用它来存储一些内容稳定的资源。好比图片内容丰富的电商网站会用它来存储 Base64 格式的图片字符串;IndexDB 是一个运行在浏览器上的非关系型数据库,IndexDB 能够看作是 LocalStorage 的一个升级,当数据的复杂度和规模上升到了 LocalStorage 没法解决的程度,咱们毫无疑问能够请出 IndexDB 来帮忙。webpack
CDN的核心点有两个,缓存和回源,CDN每每用来存放静态资源,它像一个仓库,而根服务器本质上是业务服务器,它的任务是生成动态页面或返回非纯静态页面,这两种过程都是须要计算的。CSD的效用最大化涉及到服务器自己的性能优化,CDN节点的选址等,另外在CDN的域名选取时要与业务服务器的域名不同,这样小的一个细节也能很大的提升性能。git
服务端渲染的模式下,当用户第一次请求页面时,由服务器把须要的组件或页面渲染成 HTML 字符串,而后把它返回给客户端。客户端拿到手的,是能够直接渲染而后呈现给用户的 HTML 内容,不须要为了生成 DOM 内容本身再去跑一遍 JS 代码。使用服务端渲染的网站,能够说是“所见即所得”,页面上呈现的内容,咱们在 html 源文件里也能找到。不少网站是为了让搜索引擎搜到网站内容才采起服务端渲染的,性能却是其次,而服务端渲染自己解决了一个很是关键的性能问题——首屏加载速度过慢。在react,vue中服务端渲染的实践中,主要在于两点:一是renderToString()方法,而是把转化结果塞进模板里。SSR优化的再好仍是比较消耗CPU的,咱们何不要让服务器去作这件事,一个公司服务器是有限的,公司更愿意让用户的浏览器去跑,因此大部分网站都没有用服务端渲染,另外首屏渲染体验和SEO的优化方案有不少,通常咱们都不会取用服务端渲染。github
DOM的访问和修改所带来的开销都是很大的,并且对DOM的修改会引起它的外观(样式)的改变时,就会触发回流或重绘,实际上是DOM的修改触发了渲染树(render tree)的变化,而后致使回流或重绘。DOM的优化主要就是减小对DOM的访问(少交过路费)和减小对DOM的修改(避免过分渲染,避免过分回流或重绘),咱们常常作的就是让JS给DOM分压,用DOM Fragment来缓存批量化的DOM操做。web
实现异步更新
Vue 和 React 都实现了异步更新策略。虽然实现的方式不尽相同,但都达到了减小 DOM 操做、避免过分渲染的目的。当咱们使用 Vue 或 React 提供的接口去更新数据时,这个更新并不会当即生效,而是会被推入到一个队列里。待到适当的时机,队列中的更新任务会被批量触发,这就是异步更新。异步更新的特性在于它只看结果,所以渲染引擎不须要为过程买单。
避免可能会引起回流与重绘的DOM操做
咱们能够监听滚动事件,懒加载实现是根据若是可视区域高度大于元素顶部距可视区域顶部的高度,说明元素露出,这时给元素写入真实的src,展现图片
<script>
// 获取全部的图片标签
const imgs = document.getElementsByTagName('img')
// 获取可视区域的高度
const viewHeight = window.innerHeight || document.documentElement.clientHeight
// num用于统计当前显示到了哪一张图片,避免每次都从第一张图片开始检查是否露出
let num = 0
function lazyload(){
for(let i=num; i<imgs.length; i++) {
// 用可视区域高度减去元素顶部距离可视区域顶部的高度
let distance = viewHeight - imgs[i].getBoundingClientRect().top
// 若是可视区域高度大于等于元素顶部距离可视区域顶部的高度,说明元素露出
if(distance >= 0 ){
// 给元素写入真实的src,展现图片
imgs[i].src = imgs[i].getAttribute('data-src')
// 前i张图片已经加载完毕,下次从第i+1张开始检查是否露出
num = i + 1
}
}
}
// 监听Scroll事件
window.addEventListener('scroll', lazyload, false);
</script>
复制代码
**scroll 事件,resize 事件、鼠标事件(好比 mousemove、mouseover 等)、键盘事件(keyup、keydown 等)**都存在被频繁触发的风险。频繁触发回调致使的大量计算会引起页面的抖动甚至卡顿。为了规避这种状况,咱们须要一些手段来控制事件被触发的频率。就是在这样的背景下,throttle(事件节流)和 debounce(事件防抖)出现了。它们经过对事件对应的回调函数进行包裹、以自由变量的形式缓存时间信息,最后用 setTimeout 来控制事件的触发频率。
尽量使用外部脚本和样式文本 使用分离的样式表和脚本可使其被浏览器缓存,本站的其余页面可以重用该文件。
将样式表放在顶部 把样式表放在文档底部会致使浏览器阻止页面逐步呈现,这会致使用户看不到页面上内容的,在浏览器等待文档底部的样式表的时候,会延迟显示任何可视化组件。在IE中会致使白屏现象。将样式表放在文档的顶部则能很好地解决白屏现象,使页面逐步呈现。
脚本尽量移到底部
脚本放在顶部带来的问题:
1) 使用脚本时,对于位于脚本如下的内容,逐步呈现将被阻塞 2) 在下载脚本时会阻塞并行下载 放在底部可能会出现JS错误问题,当脚本没加载进来,用户就触发脚本事件。因此要综合考虑状况。
Script延迟加载 defer属性(IE & FF3.1+)、setTimeout
避免CSS表达式对于 IE ,其支持 CSS 表达式,以下:
width:expression(document.body.clientWidth < 600 ? “600px” : “auto”);
复制代码
其余浏览器会忽略该属性,可是 IE 认识。这个写法的性能低下之处,在于其更新频率远远超出你的预估。它不仅仅会在页面大小改变的时候求值,用户滚动页面,鼠标移动这都会进行求值。因此须要避免使用CSS表达式,必要的时候使用JavaScript处理。
优势:能够和主页面并行加载 缺点: iframe会阻塞onload事件 解决:onload事件后设置iframe的src,或者JS建立iframe节点 和主页面使用同一个链接池 避免src为空—为空默认为主页面地址
DOM层级越深会增长 CSS rule Tree 和 Dom Tree 匹配构造的性能
table会影响页面呈现的速度,只有table里的内容所有加载完才会显示
由于在同一域名下,只要有一个请求,cookie都会被传来传去,无论此次请求是否用到,因此须要减少cookie的大小
相关书籍与资料:
《高性能网站建设指南》