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

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

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

ใช้โหมดที่ใช้งานจริง (Webpack 4 เท่านั้น)

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

// 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 วิธี ได้แก่ การลดขนาดระดับแพ็กเกจและตัวเลือกเฉพาะสำหรับตัวโหลด ควรใช้ทั้ง 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(),
  ],
};

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

วิธีที่ 2 ในการลดขนาดโค้ดคือตัวเลือกเฉพาะสำหรับตัวโหลด (ตัวโหลดคืออะไร) ตัวเลือกตัวโหลดช่วยบีบอัดสิ่งที่ตัวลดขนาด ไม่สามารถลดขนาดได้ เช่น เมื่อนำเข้าไฟล์ 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. จากนั้นตัวลดขนาดจะนำสาขา if ดังกล่าวออกทั้งหมด เนื่องจาก "production" !== 'production' เป็นเท็จเสมอ และปลั๊กอินจะเข้าใจว่าโค้ดภายในสาขาเหล่านี้จะไม่ทำงานเลย

    // 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 เว็บแพ็คจะสามารถทำการเขย่าต้นไม้ได้ การสั่นสะเทือนเกิดขึ้นเมื่อ Bundler ข้ามผ่านทรัพยากร Dependency ทั้งหมด ตรวจสอบว่ามีการใช้ทรัพยากร Dependency ใดบ้าง และนำทรัพยากร Dependency ที่ไม่ได้ใช้ออก ดังนั้น หากคุณใช้ไวยากรณ์โมดูล ES โปรแกรม WebP จะช่วยลดโค้ดที่ไม่ได้ใช้ได้ ดังนี้

  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 (ตั้งแต่ v4.17.4) เพิ่มโค้ดที่มีการลดขนาด 72 KB ลงในแพ็กเกจ แต่ถ้าคุณใช้เฉพาะ เช่น 20 เมธอด โค้ดที่ลดขนาดขนาดประมาณ 65 KB ก็จะไม่ช่วยอะไรเลย

อีกตัวอย่างหนึ่งคือ Moment.js เวอร์ชัน 2.19.1 นี้ใช้โค้ดที่มีการลดขนาด 223 KB ซึ่งถือว่าใหญ่มาก เมื่อเดือนตุลาคม 2017 ขนาด JavaScript เฉลี่ยในหน้าหนึ่งคือ 452 KB ในเดือนตุลาคม 2017 อย่างไรก็ตาม ขนาด 170 KB จะเป็นไฟล์การแปล หากไม่ได้ใช้ Time.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 และหน้าโดยรอบอาจไม่มีลักษณะดังนี้

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

หากโค้ดทั้ง 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

หากโค้ดที่ไม่ใช่ WebP ไม่แสดงทรัพยากร 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 เดียวกันในการโหลดทรัพยากร Dependency ไฟล์ดังกล่าวจะโหลดเพียงครั้งเดียว คำขอเพิ่มเติมจะใช้แคชของตัวโหลด

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

สรุป

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