网站性能优化是必须的技能,并且须要长期积累,如下是我本身总结的一些性能优化的策略,主要分为几个方面:javascript
浏览器在向服务器发起请求前,会先查询本地是否有相同的文件,若是有,就会直接拉取本地缓存,这和咱们在后台部署的Redis、Memcache相似,都是起到了中间缓冲的做用,咱们先看看浏览器处理缓存的策略:php
浏览器默认的缓存是放在内存内的,内存里的缓存会由于进程的结束或者说浏览器的关闭而被清除,而存在硬盘里的缓存才可以被长期保留下去。不少时候,咱们在network面板中各请求的size项里,会看到两种不一样的状态:from memory cache 和 from disk cache,前者指缓存来自内存,后者指缓存来自硬盘。而控制缓存存放位置的,不是别人,就是咱们在服务器上设置的Etag字段。在浏览器接收到服务器响应后,会检测响应头部(Header),若是有Etag字段,那么浏览器就会将本次缓存写入硬盘中。css
以Nginx为例,设置Etaghtml
etag on; //开启etag验证
expires 14d; //设置缓存过时时间为14天
复制代码
打开咱们的网站,在chrome devtools的network面板中观察咱们的请求资源,若是在响应头部看见Etag和Expires字段,就说明咱们的缓存配置成功了。java
在咱们配置缓存时必定要切记,浏览器在处理用户请求时,若是命中强缓存,浏览器会直接拉取本地缓存,不会与服务器发生任何通讯,也就是说,若是咱们在服务器端更新了文件,并不会被浏览器得知,就没法替换失效的缓存。因此咱们在构建阶段,须要为咱们的静态资源添加md5 hash后缀,避免资源更新而引发的先后端文件没法同步的问题。webpack
咱们以前所做的浏览器缓存工做,只有在用户第二次访问咱们的页面才能起到效果,若是要在用户首次打开页面就实现优良的性能,必须对资源进行优化。咱们常将网络性能优化措施归结为三大方面:减小请求数、减少请求资源体积、提高网络传输速率。如今,让咱们逐个击破:nginx
以Webpack为例web
new webpack.optimize.UglifyJsPlugin()
复制代码
new HtmlWebpackPlugin({
template: __dirname + '/views/index.html', // new 一个这个插件的实例,并传入相关的参数
filename: '../index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
chunksSortMode: 'dependency'
})
复制代码
咱们在使用html-webpack-plugin 自动化注入JS、CSS打包HTML文件时,不多会为其添加配置项,这里我给出样例,你们直接复制就行。chrome
PS:这里有一个技巧,在咱们书写HTML元素的src 或 href 属性时,能够省略协议部分,这样也能简单起到节省资源的目的。后端
在使用webpack的过程当中,咱们一般会以模块的形式引入css文件(webpack的思想不就是万物皆模块嘛),可是在上线的时候,咱们还须要将这些css提取出来,而且压缩,这些看似复杂的过程只须要简单的几行配置就行
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module: {
rules: [..., {
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: {
loader: 'css-loader',
options: {
minimize: true
}
}
})
}]
}
复制代码
new webpack.optimize.ModuleConcatenationPlugin()
复制代码
devtool: shouldUseSourceMap ? 'source-map' : false,
复制代码
最后,咱们还应该在服务器上开启Gzip传输压缩,它能将咱们的文本类文件体积压缩至原先的四分之一,效果立竿见影,仍是切换到咱们的nginx配置文档,添加以下两项配置项目:
gzip on;
gzip_types text/plain application/javascriptapplication/x-javascripttext/css application/xml text/javascriptapplication/x-httpd-php application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
复制代码
若是你在网站请求的响应头里看到这样的字段,那么就说明我们的Gzip压缩配置成功啦:
【!!!特别注意!!!】不要对图片文件进行Gzip压缩!不要对图片文件进行Gzip压缩!不要对图片文件进行Gzip压缩!我只会告诉你效果拔苗助长,至于具体缘由,还得考虑服务器压缩过程当中的CPU占用还有压缩率等指标,对图片进行压缩不但会占用后台大量资源,压缩效果其实并不可观,能够说是“弊大于利”,因此请在gzip_types 把图片的相关项去掉。针对图片的相关处理,咱们接下来会更加具体地介绍。
使用CDN存放静态资源,避免带宽爆炸以及加快资源下载.
函数防抖:将几回操做合并为一此操做进行。原理是维护一个计时器,规定在delay时间后触发函数,可是在delay时间内再次触发的话,就会取消以前的计时器而从新设置。这样一来,只有最后一次操做能被触发。
function debounce(fn, wait) {
var timeout = null;
return function() {
if(timeout !== null)
clearTimeout(timeout);
timeout = setTimeout(fn, wait);
}
}
复制代码
函数节流:使得必定时间内只触发一次函数。原理是经过判断是否到达必定时间来触发函数。
var throttle = function(func, delay) {
var prev = Date.now();
return function() {
var context = this;
var args = arguments;
var now = Date.now();
if (now - prev >= delay) {
func.apply(context, args);
prev = Date.now();
}
}
}
复制代码
区别: 函数节流无论事件触发有多频繁,都会保证在规定时间内必定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 好比在页面的无限加载场景下,咱们须要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操做时才去请求数据。这样的场景,就适合用节流技术来实现。