web性能优化

233 阅读4分钟

not finished

用webpack优化项目

  • 优化图片,对于小图用base64的方式写入文件中

  • 给打包出来的文件名添加哈希,实现浏览器缓存文件

减少Webpack打包时间

优化Loader

Babel将代码转成字符串生成AST,对AST继续转变再生成ES5代码。
可优化Loader的文件搜索范围。

module.exports = {
  module: {
    rules: [
      {
        // js 文件才使用 babel
        test: /\.js$/,
        loader: 'babel-loader',
        // 只在 src 文件夹下查找
        include: [resolve('src')],
        // 不会去查找的路径
        exclude: /node_modules/
      }
    ]
  }
}

还可将Babel编译过的文件缓存起来,下次只需要编译更改过的代码。加快打包时间。

loader: 'babel-loader?cacheDirectory=true'

HappyPack

打包的时候是单线程的,避免长时间等待可将Loader的同步执行转换成并行的。

module: {
  loaders: [
    {
      test: /\.js$/,
      include: [resolve('src')],
      exclude: /node_modules/,
      // id 后面的内容对应下面
      loader: 'happypack/loader?id=happybabel'
    }
  ]
},
plugins: [
  new HappyPack({
    id: 'happybabel',
    loaders: ['babel-loader?cacheDirectory'],
    // 开启 4 个线程
    threads: 4
  })
]

DLLPlugin

将公共代码抽离成单独文件的优化方案。先提前打包,极大的减少打包类库的次数。只有当类库更新版本才有需要重新打包。

// 单独配置在一个文件中
// webpack.dll.conf.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
  entry: {
    // 想统一打包的类库
    vendor: ['react']
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].dll.js',
    library: '[name]-[hash]'
  },
  plugins: [
    new webpack.DllPlugin({
      // name 必须和 output.library 一致
      name: '[name]-[hash]',
      // 该属性需要与 DllReferencePlugin 中一致
      context: __dirname,
      path: path.join(__dirname, 'dist', '[name]-manifest.json')
    })
  ]
}

然后需要执行这个配置文件生成依赖文件,用DllReferencePlugin将依赖文件引入项目中。

// webpack.conf.js
module.exports = {
  // ...省略其他配置
  plugins: [
    new webpack.DllReferencePlugin({
      context: __dirname,
      // manifest 就是之前打包出来的 json 文件
      manifest: require('./dist/vendor-manifest.json'),
    })
  ]
}

代码压缩

webpack3中,用UglifyJS压缩代码,但这个是单线程运行的,为了加快效率,webpack-parallel-uglify-plugin 来并行运行 UglifyJS,从而提高效率。
但在webpack4中,就不需要这些操作,只需将mode设置为production就可默认开启以上功能。
代码压缩还可压缩HTML、CSS代码,在压缩JS代码的时候,还可通过配置实现删除console.log这类代码的功能。

其他

  • resolve.alias:
    通过别名的方式来映射一个路径,能让Webpack更快的找到路径。
  • module.noParse
    若确定一个文件没有其他依赖,就可用该属性让webpack不扫描该文件,这种方式对于大型的类库很有帮助。

减少webpack打包后的文件体积

1 按需加载

开发SPA项目的时候,有很多路由页面,可通过对每个路由页面单独打包成一个文件。
对于loadash这种大型类库也可用这个功能。
原理:当使用的时候再去下载对应文件,返回一个Promise,当Promise成功以后去执行回调。

2 Scope Hoisting

解析出模块之间的依赖关系,尽可能把打包出来的模块合并到一个函数中。

//webpack4 中会自动解析   
module.exports = {
  optimization: {
    concatenateModules: true
  }
}

3 Tree Shaking

删除项目中未被引用的代码。
若用的webpack4,开启生成环境就会自动启动这个功能

lodash

懒加载和懒执行

懒执行

概念:对于某些逻辑延迟到使用再计算。可用于首屏优化。懒执行需要唤醒,一般可通过定时器或者事件的调用来唤醒。

懒加载

概念:将不关键的资源延后加载。
懒加载原理:只加载自定义区域。
比如只加载可视区域和即将进入可视区域。

  • 图片懒加载 可设置src属性先占位,将真实的图片资源放入一个自定义属性中,当进入自定义区域时,将自定义属性替换src属性。这样图片就会去下载资源。
  • 懒加载用于视频 进入可视区域才开始播放视频

缓存

良好的缓存策略可降低资源的重复加载提高网页的整体加载速度。

强缓存

概念:在缓存期间不需要请求。
先看本地缓存有没有过期,如果过期了才请求。
但受限于本地时间,如果修改了本地时间,会造成缓存失效。

协商缓存

浏览器发出请求,若缓存有效返回404,用本地缓存。

文件优化

  • css文件放在head中
  • 将script放在body底部,因为js执行会阻塞渲染。defer属性表并行下载,但会等到html解析完成后顺序执行。对于没有任何依赖的js文件可 加上async。

CDN

CDN

网络内容分发: 目的:将内容缓存在终端用户附近。提高性能、低成本的将网络内容传递给用户。
浏览器发出请求,是向上级请求若有资源就返回,如果没有则在向上级服务器,持续上级,直到找到资源。
可将静态资源尽量使用CDN加载,由于浏览器对于单个域名有并发请求上线,可以考虑使用多个CDN域名。且对于CDN加载资源需要注意CDN域名要与主站不同,否则每次请求都会带上主站的cookie,平白销毁浏览。

HTTP与HTTPS对比

HTTPS比HTTP更安全。
HTTPS需要购买证书,证书需要成本。

摘自