简介 网站加载的速度取决于浏览器必须下载的所有文件的大小。减少要传输的文件的大小可以使网站不仅加载更快,而且对于那些宽带是按量计费的人来说也更友好。
gzip是一种流行的数据压缩程序。您可以使用gzip压缩Nginx实时文件。这些文件在检索时由支持它的浏览器解压缩,好处是web服务器和浏览器之间传输的数据量更小,速度更快。
gzip不一定适用于所有文件的压缩。例如,文本文件压缩得非常好,通常会缩小两倍以上。另一方面,诸如JPEG或PNG文件之类的图像已经按其性质进行压缩,使用gzip压缩很难有好的压缩效果或者甚至没有效果。压缩文件会占用服务器资源,因此最好只压缩那些压缩效果好的文件。
在本指南中,我们将讨论如何配置安装在Ubuntu 16.04服务器上的Nginx,以利用gzip压缩,来减少发送给网站访问者的文件的大小。
vue-cli 打包vendor大如何处理 在写admin的时候项目地址 打包发现vendor.js特别大 如何提高用户体验呢
接下来我们看看怎么做
定位 webpack 大的原因 1 "analyz": "NODE_ENV=production npm_config_report=true npm run build"
尽量使用模块化引入 如果说 jQuery 确实没有引入必要,很多人会同意;但对于 lodash 这类依赖的工具,并不是所有人都会去造一发轮子的。然而全包引入 400kb 的体量,可否有让你心肝一颤?幸好的是,lodash 提供了模块化的引入方式;可按需引入,快哉快哉:
1 2 3 4 5 6 7 import { debounce } from 'lodash' import { throttle } from 'lodash' // 改成如下写法 import debounce from 'lodash/debounce' import throttle from 'lodash/throttle'
擅懒如你的优秀程序员,是否也发现这样写颇为麻烦?那么恭喜你,这个问题已经被解决;lodash-webpack-plugin 和 babel-plugin-lodash 的存在(组合使用),即是解决这问题的。它可将全路径引用的 lodash, 自动转变为模块化按使用引入(如下例示);并且所需配置也十分简单,就不在此赘述(温馨提示:当涉及些特殊方法时,尚需些留意)。
1 2 3 4 // 引入组件,自动转换 import _ from 'lodash' _.debounce() _.throttle()
额外补充的是,即便采用如上写法,还是不够快捷,每个用到的文件,都写一遍 import,实在多有不便。更可取的是,将项目所需的方法,统一引入,按需添加,组建出本地 lodash 类库,然后 export 给框架层(比如 Vue.prototype),以便全局使用;详情可参见:vue-modular-import-lodash。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // helper 文件夹下 lodash,统一引入你需要的方法 import _ from 'lodash' export default { cloneDeep: _.cloneDeep, debounce: _.debounce, throttle: _.throttle, size: _.size, pick: _.pick, isEmpty: _.isEmpty } // 注入到全局 import _ from '@helper/lodash.js' Vue.prototype.$_ = _ // vue 组件内运用 this.$_.debounce()
按需异步加载模块 关于前端开发优化,重要的一条是,尽可能合并请求及资源,如常用的请求数据合并,压缩合并 js,构造雪碧图诸此等等(当然得适当,注意体积,过大不宜);但,同时也当因需制宜,根据需要去异步加载,避免无端就引入早成的浪费。webpack 也是内置对这方面的支持; 假如,你使用的是 Vue,将一个组件(以及其所有依赖)改为异步加载,所需要的只是把:
1 import Foo from './Foo.vue'
改写成
1 const Foo = () => import('./Foo.vue')
如此分割之时,该组件所依赖的其他组件或其他模块,都会自动被分割进对应的 chunk 里,实现异步加载,当然也支持把组件按组分块,将同组中组件,打包在同个异步 chunk 中。如此能够非常有效的抑制 Javascript 包过大,同时也使得资源的利用更加合理化。
生产环境,压缩混淆并移除console 现代化中等规模以上的开发中,区分开发环境、测试环境和生产环境,并根据需要予以区别对待,已然成为行业共识;可能的话,还会有预发布环境。对待生产环境,压缩混淆可以很有效的减小包的体积;同时,如果能够移除使用比较频繁的 console,而不是简单的替换为空方法,也是精彩的一笔小优化。如果使用 UglifyJsPlugin 插件来压缩代码,加入如下配置,即可移除掉代码中的 console:
1 2 3 4 5 6 7 8 new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, drop_console: true, pure_funcs: ['console.log'] }, sourceMap: false })
依赖包 很多人发现自己引用的第三方依赖包特别多的时候vendor.js会打包的特别大
解决方法:
在config/index.js 中找到productionGzip 设置为true 并且安装 npm install –save-dev compression-webpack-plugin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 const path = require('path') module.exports = { build: { env: require('./prod.env'), index: path.resolve(__dirname, '../dist/index.html'), assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: '/', productionSourceMap: true, // Gzip off by default as many popular static hosts such as // Surge or Netlify already gzip all static assets for you. // Before setting to `true`, make sure to: // npm install --save-dev compression-webpack-plugin productionGzip: true, productionGzipExtensions: ['js', 'css'], // Run the build command with an extra argument to // View the bundle analyzer report after build finishes: // `npm run build --report` // Set to `true` or `false` to always turn it on or off bundleAnalyzerReport: process.env.npm_config_report }, dev: { env: require('./dev.env'), port: process.env.PORT || 8080, autoOpenBrowser: true, assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: {}, // CSS Sourcemaps off by default because relative paths are "buggy" // with this option, according to the CSS-Loader README // (https://github.com/webpack/css-loader#sourcemaps) // In our experience, they generally work as expected, // just be aware of this issue when enabling this option. cssSourceMap: false } }
接下来我们看看webpack.prod.conf 这里做了什么,会生成gz文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8 }) ) }
这样做就可以了吗,然而并不是 配合nginx
没有设置的效果Nginx响应头
1 2 3 4 5 6 7 HTTP/1.1 200 OK Server: nginx/1.4.6 (Ubuntu) Date: Tue, 19 Jan 2016 20:04:12 GMT Content-Type: text/html Last-Modified: Tue, 04 Mar 2014 11:46:45 GMT Connection: keep-alive Content-Encoding: gzip
在最后一行中,您可以看到Content-Encoding: gzip。这告诉我们gzip压缩已用于发送此文件。这是因为在Ubuntu 16.04上,Nginx的 gzip在安装后使用默认设置自动启用了压缩。
但是,默认情况下,Nginx仅压缩HTML文件。新安装中的每个其他文件都将以未压缩的形式提供。要验证这一点,您可以请求以test.jpg相同方式命名的测试图像。
1 curl -H "Accept-Encoding: gzip" -I http://localhost/test.jpg
结果应该与以前略有不同:
Nginx响应头
1 2 3 4 5 6 7 8 9 HTTP/1.1 200 OK Server: nginx/1.4.6 (Ubuntu) Date: Tue, 19 Jan 2016 20:10:34 GMT Content-Type: image/jpeg Content-Length: 0 Last-Modified: Tue, 19 Jan 2016 20:06:22 GMT Connection: keep-alive ETag: "569e973e-0" Accept-Ranges: bytes
Content-Encoding: gzip没有输出,这意味着文件是在没有压缩的情况下提供。
您可以使用测试CSS样式表重复测试。
1 curl -H "Accept-Encoding: gzip" -I http://localhost/test.css
再一次,输出中没有提到压缩。
CSS文件的Nginx响应头
1 2 3 4 5 6 7 8 9 HTTP/1.1 200 OK Server: nginx/1.4.6 (Ubuntu) Date: Tue, 19 Jan 2016 20:20:33 GMT Content-Type: text/css Content-Length: 0 Last-Modified: Tue, 19 Jan 2016 20:20:33 GMT Connection: keep-alive ETag: "569e9a91-0" Accept-Ranges: bytes
下一步是将Nginx配置支持其他类型文件的压缩。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 server { listen 80; server_name vue.phalcon.app; root /Users/limx/Applications/vue/dist; index index.html index.htm; client_max_body_size 8M; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-PORT $remote_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; gzip on; gzip_static on; gzip_min_length 1k; gzip_buffers 16 64k; gzip_http_version 1.1; gzip_comp_level 9; gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; gzip_vary on; #charset koi8-r; #access_log /var/log/nginx/log/host.access.log main; location / { try_files $uri $uri/ /index.html$is_args$args; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} }