diff --git a/lib/builder/builder.js b/lib/builder/builder.js
index 715f10afda..687e59c487 100644
--- a/lib/builder/builder.js
+++ b/lib/builder/builder.js
@@ -72,11 +72,7 @@ export default class Builder extends Tapable {
       'vue',
       'vue-router',
       'vue-meta',
-      'core-js',
-      'regenerator-runtime',
-      'es6-promise',
-      'babel-runtime',
-      'vuex'
+      this.options.store && 'vuex'
     ].concat(this.options.build.vendor).filter(v => v)
   }
 
diff --git a/lib/builder/webpack/client.config.js b/lib/builder/webpack/client.config.js
index c0da2c38ec..87969f9fc8 100644
--- a/lib/builder/webpack/client.config.js
+++ b/lib/builder/webpack/client.config.js
@@ -29,11 +29,20 @@ export default function webpackClientConfig () {
 
   // App entry
   config.entry.app = resolve(this.options.buildDir, 'client.js')
+  config.entry.common = this.vendor()
 
   // Extract vendor chunks for better caching
   const _this = this
   const totalPages = _this.routes ? _this.routes.length : 0
-  const vendor = this.vendor()
+
+  // This well-known vendor may exist as a dependency of other requests.
+  const maybeVendor = [
+    '/core-js/',
+    '/regenerator-runtime/',
+    '/es6-promise/',
+    '/babel-runtime/',
+    '/lodash/'
+  ]
 
   config.plugins.push(
     new webpack.optimize.CommonsChunkPlugin({
@@ -47,9 +56,8 @@ export default function webpackClientConfig () {
           return false
         }
 
-        // Extract all explicit vendor modules
-        // Vendor should explicitly extracted even if not used in 50% of the chunks!
-        if (module.context && vendor.some(v => module.context.includes(v))) {
+        // Detect and externalize well-known vendor if detected
+        if (module.context && maybeVendor.some(v => module.context.includes(v))) {
           return true
         }