zoukankan      html  css  js  c++  java
  • webpack打包速度和性能再次优化

    一. 改单dll为双dll

    因为上图原因,使用CommonsChunkPlugin时,导致其打包出来的vendors.js内的模块ID会因为其他文件引用模块数量的变化而变化。

    所以现利用DllPlugin打包原vendors.js打包的文件,命名依然为vendor,文件名:vendor.js。


    二. 利用cache和多线程提高编译速度:
     

    时间(s) 优化前 优化后
    webpack cach:true 55 54
    babel-loader?cacheDirectory=true 54 35
    webpack-parallel-uglify-plugin 36.7 27.98
     happypack  36 34.33
    uglifyjs-webpack-plugin 39 21.20

    三. 更换js压缩插件为:uglifyjs-webpack-plugin

    可以使用多线程加速,但有一个问题,目前使用版本是:1.1.8

    此插件压缩功能只支持如下配置:

    output: {
            filename: 'js/[name].[chunkhash:8].js'
        }
    
    或
    
    output: {
            filename: 'js/[name].js'
        }

    不支持:

    output: {
            filename: 'js/[name].js?v=[chunkhash:8]'
        }

    相关issue:  https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues/220

    基于以上原因,更改覆盖式发布为非覆盖式发布方式 js/[name].[chunkhash:8].js , 这时你可能会用到如下插件来动态插入css和js:

    功能对比 add-asset-html-webpack-plugin html-webpack-include-assets-plugin 备注
    hash 

    根据具体文件内容计算哈希值

    自动加在文件名后:xxx?as68d7

    webpack编译环境hash值,所有文件的hash值统一,且一旦编译环境有改动,hash即变化

    自动加在文件名后:xxx?as68d7

     
    待插入文件 filepath字段,支持glob assets字段,支持glob  
    插入html的位置 head或body最后,其他引用资源的前面,不可选择位置 可选择插入在其他引用资源的前面或后面

    其他引用资源值htmlWebpackPlugin

    插入的资源

    copy文件 会把filepath文件copy到publicPath下 不会copy文件  

     

     

     

     

     

     

     

     

     

     

    举例如下:

    new AddAssetHtmlPlugin([
              { 
                  filepath: outDir + '/js/lib/dll.js',
                  publicPath: outPublicDir + 'js/lib/',
                  outputPath: './js/lib',
                  hash: true,
                  includeSourcemap: false
              },
              { 
                  filepath: outDir + '/js/vendor.js',
                  publicPath: outPublicDir + 'js/',
                  outputPath: './js',    
                  hash: true,
                  includeSourcemap: false
              },
              { 
                  filepath: outDir + '/css/vendor.css',
                  publicPath: outPublicDir + 'css/',
                  outputPath: './css',
                  hash: true,
                  includeSourcemap: false,
                  typeOfAsset:'css'
              }
            ])
    new HtmlWebpackIncludeAssetsPlugin({
        assets: [getLatestFile('js/lib/dll.js')],
        append: false
    }),
    new HtmlWebpackIncludeAssetsPlugin({
        assets: [getLatestFile('js/vendor.js')],
        append: false
    }),
    new HtmlWebpackIncludeAssetsPlugin({
        assets: [getLatestFile('css/vendor.css')],
        append: false
    })

    对比后选择:html-webpack-include-assets-plugin,动态顺序插入dll.js, vendor.js, manifest.js和页面功能js由htmlWebpackPlugin插入到最后。

    再此基础上,需要手动检索最新的dll.xxx.js 和vendor.xxx.js文件:

    getLatestFile('js/vendor.js')
    
    function getLatestFile(path){
        let new_path = path.replace(/./g, '.**.');
        let latest_file = '';
        let latest_file_mtime = 0;
    
        glob.sync(outDir + '/' + new_path).forEach(function(file){
            let fileInfo = fs.statSync(file);
            let file_mtime = +new Date(fileInfo.mtime);
    
            latest_file = file_mtime > latest_file_mtime ? file : latest_file;
            latest_file_mtime = file_mtime > latest_file_mtime ? file_mtime : latest_file_mtime;
    
        })
    
        return latest_file.replace(/^.*/(js/|css/)/ig, "$1");
    }

    有个问题即,如果你是本地编译后上传发布编译后的代码,那么因为是非覆盖式发布,manifest.js内的runtime一直变化导致所有引入manifest的html 都会变化。这个问题目前解决方案是把编译部署这两步移到服务器进行,我们只关注并提交源码即可。比如可以利用gitlab+jenkins的方式。

     

    附:nodejs一些常用方法简介

    glob:

    基于javascript, 使用 minimatch 库(各种正则)来进行匹配获取文件路径

    var glob = require("glob")
    
    // options 是可选的
    glob("**/*.js", options, function (er, files) {
      // files 是匹配到的文件的数组.
      // 如果 `nonull` 选项被设置为true, 而且没有找到任何文件,那么files就是glob规则本身,而不是空数组
      // er是当寻找的过程中遇的错误
    })

    glob.sync() 同步获取

    var files = glob.sync(pattern, [options])

     

    fs:

    Node.js内置的fs模块就是文件系统模块,负责读写文件。和所有其它JavaScript模块不同的是,fs模块同时提供了异步和同步的方法。

    fs异步:
    
    'use strict';
    
    var fs = require('fs');
    
    fs.readFile('sample.txt', 'utf-8', function (err, data) {
        if (err) {
            console.log(err);
        } else {
            console.log(data);
        }
    });
    
    fs同步:
    
    try {
        var data = fs.readFileSync('sample.txt', 'utf-8');
        console.log(data);
    } catch (err) {
        // 出错了
    }

     

    path.resolve:  相对路径转绝对路径

    path.stat: 获取文件属性比如大小,时间等

     

    附2:自己根据文件内容计算文件hash值方法:

    
    

     const fs = require('fs');
     const crypto = require('crypto');

    function getFileHash(path){
        let file = fs.readFileSync(path);
        let hash = crypto.createHash('md5');
        hash.update(file);
    
        return hash.digest('hex');
    }

     

  • 相关阅读:
    jQuerychicun
    css3动画
    app开发,H5+CSS3页面布局小tips
    函数基础
    函数
    冒泡排序
    关于Vue+iview的前端简单的导入数据(excel)
    关于Vue+iview的简单下拉框滚动加载
    ES6中set的用法回顾
    百度地图api设置点的自定义图标不显示
  • 原文地址:https://www.cnblogs.com/saysmy/p/8349975.html
Copyright © 2011-2022 走看看