前端性能优化 资源合并与压缩
资源的合并与压缩涉及到的优化点
资源的合并 => 减少http请求数量
资源的压缩 => 减少请求资源的大小。
html压缩
HTML代码压缩就是压缩这些在文本文件中有意义,但是在 HTML 中不显示的字符,包括空格,制表符,换行符等,还有一些其他意义的字符,如 HTML注释 也可以被压缩。
进行html压缩前后效果对比,html压缩的效果不明显?
按照googld的流浪,每次请求 1MB 减少一个字节,每年可以节省流量近 500TB
如何进行 html 压缩:
1、使用在线网站进行压缩
2、nodejs 提供了 html-minifier 工具
3、后端模板引擎渲染压缩
但在真实的开发中一般是通过构建工具进行压缩的,比如 webpack。
css压缩
1、无效代码删除
2、css 语义合并
如何进行 css 压缩
1、使用在线网站进行压缩
2、使用 html-minifier 对 html 中的 css 进行压缩
3、使用 clearn-css 对 css 进行压缩
JS压缩
1、无效字符的删除。回车,空格
2、剔除注释
3、代码语义的缩减和优化。比如一些变量的长度的缩短,对无效代码的优化
4、代码保护。js压缩使代码混乱,不可读
如何进行 js 压缩
1、使用在线网站进行压缩
2、使用 html-minifier 对 html 中的 js 进行压缩
3、使用 uglifyjs2 对 js 进行压缩
所以 css 和 js 压缩的意义比 html 压缩有意义
文件合并
不合并的缺陷:
1、文件与文件之间有插入的上行请求,增加了 n-1 个网络延迟
2、受丢包问题影响更严重
3、经过代理服务器时可能会被断开
文件合并存在的问题
1、首屏渲染问题,合并后的文件显然会比合并前大,如果渲染依赖 js 的话,如果js 请求慢的话,就会有影响。
2、缓存失效问题,a,b,c 中任一一个js有变动,都会导致合并文件有变动,会导致合并 js 失效,前面的可能只会导致a.js失效
=>
1、公共库合并一个文件,业务代码的合并,公共库改动不大
2、不同页面的合并,单页应用,当路由到某个页面的时候,才去加载这个页面
3、同一域名同一时间发出的请求是有限的,从这方面讲合并是有必要的
如何进行文件合并
1、使用在线网站进行文件合并
2、使用 Nodejs 实现文件合并
实战
针对非常老,传统的页面,在没有页面构建工具的情况下,有各种依赖的 js 的情况下。html css 可以通过在线压缩,压缩好复制到原来的地方。js文件压缩也是单个压缩好,然后手动复制到一个文件中。这种在线压缩工具还有一个局限性,就是无法压缩 es6 代码,这是一种压缩方式,但不是我们推崇的压缩方式
2、fis3 自动化构建工具
fis3 是一款百度内部使用的构建工具,会分析 require 预发,得到所有文件的依赖数,建立一个整体的依赖关系,然后对单文件会进行一个单文件的编译,在单文件编译之后,根据打包规则,对打包进行一个升级,从而完成打包的过程
fis-conf.js 就是 fis3 在构建中所依赖的配置文件,这个文件里面就是 fis3 整个构建的构建规则。fis3 支持一个 fis.match 的语法,然后下面这个文件就定义了几条规则
/** * 对于文件夹下所有的 es6 文件,都会走到 babel-5.x 的 fis 的 parser 中。 * 通过这个 parser 去处理 es6 文件,最终输出 es5 的文件 */ fis.match('*.es6', { rExt: '.js', parser: fis.plugin('babel-5.x', { blacklist: ['regenerator'], stage: 3 }), isMod: true, useHash: true, isJsLike: true }) /** * 调用 uglify-js 压缩js * parser optimizer 都是 fis3 构建过程中的不同阶段 */ fis.match('*.{es6,js}', { optimizer: fis.plugin('uglify-js') }) fis.match('*.less', { parser: fis.plugin('less'), rExt: '.css' }) fis.match('*.css', { optimizer: fis.plugin('clean-css') }) fis.match('*.html', { optimizer: fis.plugin('html-minifier') }) /** * 最终打包执行,对于 html 进行分析,对script的静态文件进行打包. * 但 vue.js 除外。 */ fis.match('::package', { postpackager: fis.plugin('loader', { useInlineMap: false, allInOne: { ignore: 'vue.js' }, processor: { '.html': 'html' } }) }) fis.match('yindao.png', { rExt: '.webp', parser: fis.plugin('webp',{ quality: 80 }) })
最后执行
fis3 release -cd output
这个指令。这个指令的意思就是执行 fis3 ,并且输出到 output 这个文件夹下
3、webpack 构建工具
HtmlWebpackPlugin这个插件能干什么呢?HtmlWebpackPlugin会在打包结束后,自动生成一个html文件,并把打包生成的js自动引入到这个html文件中
module.exports = { /** * 打包模式,不配置会警告,但底层还是会去配置默认的,就是production * production: 压缩模式,被压缩的代码 * development: 开发模式,不压缩的代码 * */ mode: 'development', // 这个文件要做打包,从哪一个文件开始打包 entry: './src/index.js', plugins: [new HtmlWebpackPlugin()], // 打包文件要放到哪里去,就配置在output这个对象里 output: { // 打包好的文件名字 filename: 'bundle.js', /** * 打包出的文件要把他放到哪一个文件夹下,path后面要放一个绝对路径 * __dirname指的是webpack.config.js所在的当前目录的这个路径 * 下面这个结合就是一个绝对路径 */ path: path.resolve(__dirname, 'dist') } }