ลดขนาดส่วนหน้า

วิธีใช้ webpack เพื่อทำให้แอปมีขนาดเล็กที่สุด

สิ่งแรกที่ต้องทำเมื่อเพิ่มประสิทธิภาพแอปพลิเคชันคือการทำให้แอปพลิเคชันมีขนาดเล็กที่สุด วิธีดำเนินการโดยใช้ Webpack มีดังนี้

Webpack 4 เปิดตัวFlag mode ใหม่ คุณสามารถตั้งค่า Flag นี้เป็น 'development' หรือ 'production' เพื่อบอก webpack ว่าคุณกําลังสร้างแอปพลิเคชันสําหรับสภาพแวดล้อมที่เฉพาะเจาะจง

// webpack.config.js
module.exports = {
  mode: 'production',
};

อย่าลืมเปิดใช้โหมด production เมื่อสร้างแอปสำหรับเวอร์ชันที่ใช้งานจริง ซึ่งจะทำให้ webpack ใช้การเพิ่มประสิทธิภาพ เช่น การทำให้ไฟล์เล็กลง การนำโค้ดสำหรับการพัฒนาเท่านั้นออกจากไลบรารี และอื่นๆ

อ่านเพิ่มเติม

เปิดใช้การลดขนาด

การลดขนาดลงเมื่อคุณบีบอัดโค้ดด้วยการนำช่องว่างส่วนเกินออก ย่อชื่อตัวแปรให้สั้นลง และอื่นๆ ดังนี้

// Original code
function map(array, iteratee) {
  let index = -1;
  const length = array == null ? 0 : array.length;
  const result = new Array(length);

  while (++index < length) {
    result[index] = iteratee(array[index], index, array);
  }
  return result;
}

// Minified code
function map(n,r){let t=-1;for(const a=null==n?0:n.length,l=Array(a);++t<a;)l[t]=r(n[t],t,n);return l}

Webpack รองรับการลดขนาดโค้ด 2 วิธี ได้แก่ การลดขนาดระดับแพ็กเกจและตัวเลือกเฉพาะของตัวโหลด ควรใช้พร้อมกัน

การลดขนาดระดับชุด

การทำให้ไฟล์เล็กลงระดับแพ็กเกจจะบีบอัดทั้งแพ็กเกจหลังจากการคอมไพล์ โดยมีวิธีการทำงานดังนี้

  1. คุณเขียนโค้ดดังนี้

    // comments.js
    import './comments.css';
    export function render(data, target) {
      console.log('Rendered!');
    }
    
  2. Webpack จะรวบรวมข้อมูลต่อไปนี้โดยประมาณ

    // bundle.js (part of)
    "use strict";
    Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
    /* harmony export (immutable) */ __webpack_exports__["render"] = render;
    /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__comments_css__ = __webpack_require__(1);
    /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__comments_css_js___default =
    __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__comments_css__);
    
    function render(data, target) {
    console.log('Rendered!');
    }
    
  3. ตัวลดขนาดจะบีบอัดรายการดังกล่าวเป็นค่าต่อไปนี้โดยประมาณ

    // minified bundle.js (part of)
    "use strict";function t(e,n){console.log("Rendered!")}
    Object.defineProperty(n,"__esModule",{value:!0}),n.render=t;var o=r(1);r.n(o)
    

ใน Webpack 4 การลดขนาดระดับแพ็กเกจจะเปิดใช้โดยอัตโนมัติทั้งในโหมดการใช้งานจริงและโดยไม่ต้องมีการเข้ารหัส โดยใช้โปรแกรมลดขนาด UglifyJS ขั้นสูง (หากต้องการปิดใช้การลดขนาด ให้ใช้โหมดการพัฒนาหรือส่ง false ไปยังตัวเลือก optimization.minimize)

ใน Webpack 3 คุณต้องใช้ปลั๊กอิน UglifyJS โดยตรง ปลั๊กอินมาพร้อมกับ Webpack หากต้องการเปิดใช้ ให้เพิ่มปลั๊กอินลงในส่วน plugins ของการกำหนดค่า ดังนี้

// webpack.config.js
const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
  ],
};

ตัวเลือกเฉพาะของตัวโหลด

วิธีที่สองในการย่อโค้ดคือตัวเลือกเฉพาะสำหรับโปรแกรมโหลด (ความหมายของโปรแกรมโหลด) ตัวเลือกโปรแกรมโหลดช่วยให้คุณบีบอัดสิ่งที่เครื่องมือลดขนาดไม่สามารถลดขนาดได้ ตัวอย่างเช่น เมื่อคุณนําเข้าไฟล์ CSS ด้วย css-loader ระบบจะคอมไพล์ไฟล์เป็นสตริง

/* comments.css */
.comment {
  color: black;
}
// minified bundle.js (part of)
exports=module.exports=__webpack_require__(1)(),
exports.push([module.i,".comment {\r\n  color: black;\r\n}",""]);

ตัวบีบอัดไม่สามารถบีบอัดโค้ดนี้เนื่องจากเป็นสตริง ในการลดเนื้อหาไฟล์ เราต้อง กำหนดค่าตัวโหลดเพื่อดำเนินการดังต่อไปนี้

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { minimize: true } },
        ],
      },
    ],
  },
};

อ่านเพิ่มเติม

ระบุ NODE_ENV=production

วิธีลดขนาดของส่วนหน้าอีกวิธีหนึ่งคือการกำหนดตัวแปรสภาพแวดล้อม NODE_ENV ในโค้ดเป็นค่า production

ไลบรารีจะอ่านตัวแปร NODE_ENV เพื่อตรวจหาว่าควรทํางานในโหมดใดระหว่างโหมดการพัฒนาหรือโหมดที่ใช้งานจริง ไลบรารีบางรายการจะทํางานแตกต่างกันไปตามตัวแปรนี้ ตัวอย่างเช่น เมื่อไม่ได้ตั้งค่า NODE_ENV เป็น production Vue.js จะตรวจสอบเพิ่มเติมและพิมพ์คำเตือนดังนี้

// vue/dist/vue.runtime.esm.js
// …
if (process.env.NODE_ENV !== 'production') {
  warn('props must be strings when using array syntax.');
}
// …

React ทํางานคล้ายกัน โดยจะโหลดบิลด์สำหรับนักพัฒนาซอฟต์แวร์ที่มีคำเตือนดังต่อไปนี้

// react/index.js
if (process.env.NODE_ENV === 'production') {
  module.exports = require('./cjs/react.production.min.js');
} else {
  module.exports = require('./cjs/react.development.js');
}

// react/cjs/react.development.js
// …
warning$3(
    componentClass.getDefaultProps.isReactClassApproved,
    'getDefaultProps is only used on classic React.createClass ' +
    'definitions. Use a static property named `defaultProps` instead.'
);
// …

โดยปกติแล้ว การตรวจสอบและคำเตือนดังกล่าวไม่จำเป็นในเวอร์ชันที่ใช้งานจริง แต่ยังคงอยู่ในโค้ดและทำให้ขนาดของไลบรารีเพิ่มขึ้น ใน webpack 4 ให้นำออกโดยเพิ่มตัวเลือก optimization.nodeEnv: 'production' ดังนี้

// webpack.config.js (for webpack 4)
module.exports = {
  optimization: {
    nodeEnv: 'production',
    minimize: true,
  },
};

ใน webpack 3 ให้ใช้ DefinePlugin แทน

// webpack.config.js (for webpack 3)
const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"production"'
    }),
    new webpack.optimize.UglifyJsPlugin()
  ]
};

ทั้งตัวเลือก optimization.nodeEnv และ DefinePlugin จะทำงานในลักษณะเดียวกัน คือจะแทนที่ process.env.NODE_ENV ทั้งหมดด้วยค่าที่ระบุ เมื่อใช้การกําหนดค่าจากด้านบน

  1. Webpack จะแทนที่ process.env.NODE_ENV ทั้งหมดด้วย "production":

    // vue/dist/vue.runtime.esm.js
    if (typeof val === 'string') {
      name = camelize(val);
      res[name] = { type: null };
    } else if (process.env.NODE_ENV !== 'production') {
      warn('props must be strings when using array syntax.');
    }
    

    // vue/dist/vue.runtime.esm.js
    if (typeof val === 'string') {
      name = camelize(val);
      res[name] = { type: null };
    } else if ("production" !== 'production') {
      warn('props must be strings when using array syntax.');
    }
    
  2. จากนั้น ตัวลดขนาดจะนำ Branch ของ if ดังกล่าวออกทั้งหมด เนื่องจาก "production" !== 'production' มีค่าเป็น false เสมอ และปลั๊กอินเข้าใจว่าโค้ดภายใน Branch เหล่านี้จะไม่สั่งการ

    // vue/dist/vue.runtime.esm.js
    if (typeof val === 'string') {
      name = camelize(val);
      res[name] = { type: null };
    } else if ("production" !== 'production') {
      warn('props must be strings when using array syntax.');
    }
    

    // vue/dist/vue.runtime.esm.js (without minification)
    if (typeof val === 'string') {
      name = camelize(val);
      res[name] = { type: null };
    }
    

อ่านเพิ่มเติม

ใช้โมดูล ES

วิธีถัดไปในการลดขนาดหน้าเว็บคือการใช้โมดูล ES

เมื่อคุณใช้โมดูล ES webpack จะทํา Tree Shaking ได้ การแยกไฟล์ที่ไม่จำเป็นคือเมื่อเครื่องมือรวมไฟล์จะเรียกใช้ทั้งต้นไม้ของข้อกําหนด ตรวจสอบว่าใช้ข้อกําหนดใดบ้าง และนําข้อกําหนดที่ไม่ได้ใช้ออก ดังนั้น หากคุณใช้ไวยากรณ์โมดูล ES webpack จะกำจัดโค้ดที่ไม่ได้ใช้ได้ ดังนี้

  1. คุณเขียนไฟล์ที่มีการส่งออกหลายรายการ แต่แอปใช้เพียงรายการเดียว

    // comments.js
    export const render = () => { return 'Rendered!'; };
    export const commentRestEndpoint = '/rest/comments';
    
    // index.js
    import { render } from './comments.js';
    render();
    
  2. Webpack เข้าใจว่าไม่ได้ใช้ commentRestEndpoint และจะไม่สร้างจุดส่งออกแยกต่างหากในแพ็กเกจ

    // bundle.js (part that corresponds to comments.js)
    (function(module, __webpack_exports__, __webpack_require__) {
    "use strict";
    const render = () => { return 'Rendered!'; };
    /* harmony export (immutable) */ __webpack_exports__["a"] = render;
    
    const commentRestEndpoint = '/rest/comments';
    /* unused harmony export commentRestEndpoint */
    })
    
  3. ตัวลดขนาดจะนำตัวแปรที่ไม่ได้ใช้ออก

    // bundle.js (part that corresponds to comments.js)
    (function(n,e){"use strict";var r=function(){return"Rendered!"};e.b=r})
    

ซึ่งจะใช้กับไลบรารีได้หากเขียนด้วยโมดูล ES

แต่คุณไม่จำเป็นต้องใช้ตัวลดขนาดในตัวของ Webpack (UglifyJsPlugin) ที่แน่นอน เครื่องมือลดขนาดที่รองรับการนำโค้ดที่ใช้งานไม่ได้ออก (เช่น ปลั๊กอิน Babel Minify หรือปลั๊กอิน Google Closure Compiler)

อ่านเพิ่มเติม

ปรับขนาดภาพให้เหมาะสม

รูปภาพมีขนาดใหญ่มากกว่าครึ่งของหน้าเว็บ แม้ว่าเครื่องมือจะไม่สำคัญเท่า JavaScript (เช่น ไม่บล็อกการแสดงผล) แต่ก็ใช้แบนด์วิดท์ปริมาณมาก ใช้ url-loader, svg-url-loader และ image-webpack-loader เพื่อเพิ่มประสิทธิภาพใน webpack

url-loader แทรกไฟล์คงที่ขนาดเล็กลงในแอป หากไม่มีการกําหนดค่า ระบบจะนําไฟล์ที่ส่งมาวางไว้ข้างพวงมาลัยที่คอมไพล์แล้ว และแสดงผล URL ของไฟล์นั้น อย่างไรก็ตาม หากเราระบุตัวเลือก limit ระบบจะเข้ารหัสไฟล์ที่มีขนาดเล็กกว่าขีดจำกัดนี้เป็น URL ข้อมูล Base64 และแสดงผล URL นี้ บรรทัดนี้ฝังรูปภาพไว้ในโค้ด JavaScript และบันทึกคําขอ HTTP

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif)$/,
        loader: 'url-loader',
        options: {
          // Inline files smaller than 10 kB (10240 bytes)
          limit: 10 * 1024,
        },
      },
    ],
  }
};
// index.js
import imageUrl from './image.png';
// → If image.png is smaller than 10 kB, `imageUrl` will include
// the encoded image: 'data:image/png;base64,iVBORw0KGg…'
// → If image.png is larger than 10 kB, the loader will create a new file,
// and `imageUrl` will include its url: `/2fcd56a1920be.png`

svg-url-loader ทำงานเหมือนกับ url-loader ยกเว้นจะเข้ารหัสไฟล์ด้วยการเข้ารหัส URL แทน Base64 ซึ่งมีประโยชน์สำหรับรูปภาพ SVG เนื่องจากไฟล์ SVG เป็นข้อความธรรมดา การเข้ารหัสนี้จึงมีประสิทธิภาพด้านขนาดมากกว่า

module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/,
        loader: "svg-url-loader",
        options: {
          limit: 10 * 1024,
          noquotes: true
        }
      }
    ]
  }
};

image-webpack-loader จะบีบอัดรูปภาพที่ลากผ่าน โปรแกรมนี้รองรับรูปภาพ JPG, PNG, GIF และ SVG ดังนั้นเราจะใช้กับรูปภาพทุกประเภท

ตัวโหลดนี้จะไม่ฝังรูปภาพลงในแอป ตัวโหลดจึงต้องทำงานร่วมกับ url-loader และ svg-url-loader เพื่อหลีกเลี่ยงการคัดลอกและวางลงในทั้ง 2 กฎ (กฎแรกสำหรับรูปภาพ JPG/PNG/GIF และอีกกฎสำหรับรูปภาพ SVG) เราจะรวมโปรแกรมโหลดนี้ไว้ในกฎแยกต่างหากด้วย enforce: 'pre' ดังนี้

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif|svg)$/,
        loader: 'image-webpack-loader',
        // This will apply the loader before the other ones
        enforce: 'pre'
      }
    ]
  }
};

การตั้งค่าเริ่มต้นของตัวโหลดพร้อมใช้งานแล้ว แต่หากคุณต้องการกำหนดค่าเพิ่มเติม โปรดดูตัวเลือกปลั๊กอิน หากต้องการเลือกตัวเลือกที่ระบุ โปรดดูคู่มือเกี่ยวกับการเพิ่มประสิทธิภาพรูปภาพที่ยอดเยี่ยมของ Addy Osmani

อ่านเพิ่มเติม

เพิ่มประสิทธิภาพทรัพยากร Dependency

มากกว่าครึ่งหนึ่งของขนาด JavaScript เฉลี่ยมาจาก Dependency และขนาดส่วนหนึ่งนั้นอาจไม่จำเป็น

ตัวอย่างเช่น Lodash (ตั้งแต่เวอร์ชัน 4.17.4) จะเพิ่มโค้ดที่ลดขนาดลง 72 KB ลงในแพ็กเกจ แต่ถ้าคุณใช้เพียง 20 วิธี โค้ดที่ถูกลดขนาดลงประมาณ 65 KB ก็ไม่มีประโยชน์อะไรเลย

อีกตัวอย่างหนึ่งคือ Moment.js เวอร์ชัน 2.19.1 ใช้โค้ดที่ผ่านการย่อขนาด 223 KB ซึ่งถือว่ามากทีเดียว ขนาดเฉลี่ยของ JavaScript ในหน้าเว็บคือ 452 KB ในเดือนตุลาคม 2017 อย่างไรก็ตาม 170 KB ของขนาดดังกล่าวเป็นไฟล์แปลภาษา หากไม่ได้ใช้ Moment.js ที่มีหลายภาษา ไฟล์เหล่านี้จะขยายชุดไฟล์โดยไม่มีวัตถุประสงค์

คุณสามารถเพิ่มประสิทธิภาพของ Dependency ทั้งหมดเหล่านี้ได้อย่างง่ายดาย เราได้รวบรวมวิธีการเพิ่มประสิทธิภาพไว้ในที่เก็บ GitHub ลองดูเลย!

เปิดใช้การต่อโมดูลสำหรับโมดูล ES (หรือที่เรียกว่าการรอขอบเขต)

เมื่อคุณสร้าง Bundle นั้น Webpack จะรวมแต่ละโมดูลเข้าไว้ด้วยกันเป็นฟังก์ชัน ดังนี้

// index.js
import {render} from './comments.js';
render();

// comments.js
export function render(data, target) {
  console.log('Rendered!');
}

// bundle.js (part  of)
/* 0 */
(function(module, __webpack_exports__, __webpack_require__) {
  "use strict";
  Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
  var __WEBPACK_IMPORTED_MODULE_0__comments_js__ = __webpack_require__(1);
  Object(__WEBPACK_IMPORTED_MODULE_0__comments_js__["a" /* render */])();
}),
/* 1 */
(function(module, __webpack_exports__, __webpack_require__) {
  "use strict";
  __webpack_exports__["a"] = render;
  function render(data, target) {
    console.log('Rendered!');
  }
})

ก่อนหน้านี้ จำเป็นต้องแยกโมดูล CommonJS/AMD ออกจากกัน อย่างไรก็ตาม การดำเนินการนี้จะเพิ่มขนาดและค่าใช้จ่ายเพิ่มเติมด้านประสิทธิภาพสำหรับแต่ละข้อบังคับ

Webpack 2 รองรับโมดูล ES ซึ่งแตกต่างจากโมดูล CommonJS และ AMD ตรงที่สามารถรวมกลุ่มได้โดยไม่ต้องรวมแต่ละรายการไว้ในฟังก์ชัน และ webpack 3 ทำให้การรวมดังกล่าวเป็นไปได้ด้วยการต่อโมดูล การดำเนินการต่อท้ายโมดูลจะทําดังนี้

// index.js
import {render} from './comments.js';
render();

// comments.js
export function render(data, target) {
  console.log('Rendered!');
}

// Unlike the previous snippet, this bundle has only one module
// which includes the code from both files

// bundle.js (part of; compiled with ModuleConcatenationPlugin)
/* 0 */
(function(module, __webpack_exports__, __webpack_require__) {
  "use strict";
  Object.defineProperty(__webpack_exports__, "__esModule", { value: true });

  // CONCATENATED MODULE: ./comments.js
    function render(data, target) {
    console.log('Rendered!');
  }

  // CONCATENATED MODULE: ./index.js
  render();
})

เห็นความแตกต่างไหม ในแพ็กเกจแบบธรรมดา โมดูล 0 ต้องใช้ render จากโมดูล 1 เมื่อใช้การต่อโมดูล require จะแทนที่ด้วยฟังก์ชันที่จำเป็นและระบบจะนำโมดูล 1 ออก แพ็กเกจมีโมดูลน้อยกว่า และค่าใช้จ่ายโมดูลน้อยกว่า

หากต้องการเปิดลักษณะการทำงานนี้ ใน Webpack 4 ให้เปิดใช้ตัวเลือก optimization.concatenateModules ดังนี้

// webpack.config.js (for webpack 4)
module.exports = {
  optimization: {
    concatenateModules: true
  }
};

ใน Webpack 3 ให้ใช้ ModuleConcatenationPlugin:

// webpack.config.js (for webpack 3)
const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.optimize.ModuleConcatenationPlugin()
  ]
};

อ่านเพิ่มเติม

ใช้ externals หากคุณมีทั้งรหัส Webpack และรหัสที่ไม่ใช่ Webpack

คุณอาจมีโปรเจ็กต์ขนาดใหญ่ที่คอมไพล์โค้ดบางอย่างด้วย Webpack แต่บางโค้ดก็ไม่ใช่โค้ดดังกล่าว เช่น เว็บไซต์โฮสติ้งวิดีโอที่วิดเจ็ตโปรแกรมเล่นอาจสร้างขึ้นด้วย webpack และหน้าเว็บรอบข้างอาจไม่ได้สร้างขึ้นด้วย webpack

ภาพหน้าจอของเว็บไซต์โฮสติ้งวิดีโอ
(เว็บไซต์ที่โฮสต์วิดีโอแบบสุ่มทั้งหมด)

หากโค้ดทั้ง 2 ชุดมีทรัพยากร Dependency เดียวกัน คุณจะแชร์โค้ดได้เพื่อหลีกเลี่ยงการดาวน์โหลดโค้ดหลายครั้ง ซึ่งทำได้ด้วยตัวเลือก externals ของ webpack ซึ่งจะแทนที่โมดูลด้วยตัวแปรหรือการนําเข้าภายนอกอื่นๆ

หากมีทรัพยากร Dependency ใน window

หากโค้ดที่ไม่ใช่ webpack ของคุณใช้ทรัพยากร Dependency ที่พร้อมใช้งานเป็นตัวแปรใน window ให้ตั้งชื่อแทนให้กับชื่อ Dependency เป็นชื่อตัวแปร ดังนี้

// webpack.config.js
module.exports = {
  externals: {
    'react': 'React',
    'react-dom': 'ReactDOM'
  }
};

การกำหนดค่านี้จะทำให้ Webpack ไม่รวมแพ็กเกจ react และ react-dom แต่จะถูกแทนที่ด้วยคำสั่งต่อไปนี้

// bundle.js (part of)
(function(module, exports) {
  // A module that exports `window.React`. Without `externals`,
  // this module would include the whole React bundle
  module.exports = React;
}),
(function(module, exports) {
  // A module that exports `window.ReactDOM`. Without `externals`,
  // this module would include the whole ReactDOM bundle
  module.exports = ReactDOM;
})

หากโหลดทรัพยากร Dependency เป็นแพ็กเกจ AMD

หากโค้ดที่ไม่ใช่ webpack ไม่ได้เปิดเผยข้อมูล Dependency ไปยัง window ปัญหาจะซับซ้อนมากขึ้น อย่างไรก็ตาม คุณยังคงหลีกเลี่ยงการโหลดโค้ดเดียวกัน 2 ครั้งได้หากโค้ดที่ไม่ใช่ Webpack ใช้ทรัพยากร Dependency เหล่านี้ในฐานะแพ็กเกจ AMD

ในการดำเนินการนี้ ให้คอมไพล์โค้ด Webpack เป็นโมดูลและโมดูลชื่อแทนของ AMD ไปยัง URL ของไลบรารี ดังนี้

// webpack.config.js
module.exports = {
  output: {
    libraryTarget: 'amd'
  },
  externals: {
    'react': {
      amd: '/libraries/react.min.js'
    },
    'react-dom': {
      amd: '/libraries/react-dom.min.js'
    }
  }
};

Webpack จะรวมแพ็กเกจไว้ใน define() และทำให้ไฟล์ขึ้นอยู่กับ URL เหล่านี้

// bundle.js (beginning)
define(["/libraries/react.min.js", "/libraries/react-dom.min.js"], function () {  });

หากโค้ดที่ไม่ใช่ webpack ใช้ URL เดียวกันเพื่อโหลดทรัพยากร ไฟล์เหล่านี้จะโหลดเพียงครั้งเดียวเท่านั้น คำขอเพิ่มเติมจะใช้แคชของโปรแกรมโหลด

อ่านเพิ่มเติม

สรุป

  • เปิดใช้โหมดการผลิตหากคุณใช้ webpack 4
  • ย่อขนาดโค้ดด้วยตัวเลือกเครื่องมือบีบอัดและโปรแกรมโหลดระดับกลุ่ม
  • นำโค้ดสําหรับการพัฒนาเท่านั้นออกโดยแทนที่ NODE_ENV ด้วย production
  • ใช้โมดูล ES เพื่อเปิดใช้การเขย่าต้นไม้
  • บีบอัดรูปภาพ
  • ใช้การเพิ่มประสิทธิภาพเฉพาะการอ้างอิง
  • เปิดใช้การต่อโมดูล
  • ใช้ externals หากเหมาะกับคุณ