侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

优化(Vue)Javascript文件体积

前端  /  管理员 发布于 6年前   184

优化前

先感受下优化前编译好的JavaScript文件及其大小:

❯ ll ../static/js/admin/total 15M-rw-r--r-- 1 dongwm staff 388K Aug 17 14:00 app.js-rw-r--r-- 1 dongwm staff  77K Aug 17 14:00 chunk-01433734.js-rw-r--r-- 1 dongwm staff  77K Aug 17 14:00 chunk-0b283872.js-rw-r--r-- 1 dongwm staff 323K Aug 17 14:00 chunk-20f6014c.js-rw-r--r-- 1 dongwm staff 5.1K Aug 17 14:00 chunk-2d0ac00f.js-rw-r--r-- 1 dongwm staff 5.1K Aug 17 14:00 chunk-2d0b1605.js-rw-r--r-- 1 dongwm staff  13K Aug 17 14:00 chunk-2d0babdf.js-rw-r--r-- 1 dongwm staff 3.1K Aug 17 14:00 chunk-2d0cfa15.js-rw-r--r-- 1 dongwm staff 4.5K Aug 17 12:30 chunk-2d230fe7.js-rw-r--r-- 1 dongwm staff 2.8K Aug 17 14:00 chunk-2d2382a4.js-rw-r--r-- 1 dongwm staff 8.0M Aug 17 14:00 chunk-378562d0.js-rw-r--r-- 1 dongwm staff  28K Aug 17 14:00 chunk-4ee4a833.js-rw-r--r-- 1 dongwm staff  48K Aug 17 14:00 chunk-ecbac3dc.js-rw-r--r-- 1 dongwm staff 5.3M Aug 17 14:00 chunk-vendors.js

可以看到竟然有8M和5.3M这么大的文件!在本地开发时由于本地网络打开文件很快感受不明显,但当把这些文件部署到服务器上,能明显感觉首屏打开时间是非常慢的。

好,看到了问题,我们来优化~


减小chunk-vendors.js体积

挨个来解决,首先看 chunk-vendors.js 。博客管理后台项目是基于vue-CLI 3 搭建的,所以可以通过 yarn build --report 查看打包的内容中各库文件体积的占比(背后用了webpack-bundle-analyzer)。build成功后在dist目录下有个report.html文件,你可以再浏览器打开它:

这个项目的报告是这样的:


里面会列出全部编译文件,占的区域越大说明文件越大,鼠标点到某个区域都可以看到对应区域代表文件的相关信息。 chunk-vendors.js 在右上角,大小仅次于 chunk-378562d0.js 。往区域里面看,可以看到 chunk-vendors.js 中主要是element-ui,其次是vue.runtime.esm.js,其余的文件都比较小。

想要减少chunk-vendors.js体积,思路有2个:

使用公共CDN。最彻底的方案,把ui库抽离出来。当然还可以「更彻底」,把vue、vuex、vue-router、axios等等依赖都剥离出去。对element-ui中用的组件按需引入。虽然用了element-ui,但是只用了其中一部分常用组件,但是在编译时把全部ui库都引入了,所以优化思路是: 只包含需要的那部分。

要注意,企业开发和开源项目是否决定用公共CDN是有不同的考量的:

服务的重要性。凡是服务就可能会不稳定,如果你依赖外部的CDN提供服务,它挂了就直接影响你的企业服务,用户体验。除了问题你没有办法只能看着等着它解决。尤其是这种非营利性的CDN,很多开发者会比较担心它的服务质量。所以服务越重要你对里面用的东西的掌控度就要越高,在企业里面一般都要做到完全可控。用户体验。对于我们这个项目来说,管理后台部分只有有限的几个人可以选择,不影响全部用户,且使用者是「自己人」时,访问速度并不是最重要的标准,再说精简后速度是可接受的。

在element-ui官网中对于2种方案都有说明,有兴趣的可以去了解。在这里我选择了「使用公共CDN」:

具体做法如下:


1. 把vue和element-ui从构建中剥离出来

直接在页面上引入 js 和 css 文件即可开始使用。看一下修改后的 public/index.html

<!DOCTYPE html><html lang="en">  <head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width,initial-scale=1.0">    <link rel="icon" href="http://www.fly63.com/article/detial/4841/<%= BASE_URL %>favicon.ico">    <link rel="stylesheet" href="https://unpkg.com/[email protected]/lib/theme-chalk/index.css">    <title>blog</title>  </head>  <body>    <noscript>      <strong>We're sorry but blog doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>    </noscript>    <div id="app"></div>    <script src="https://unpkg.com/[email protected]/dist/vue.runtime.min.js"></script>    <script src="https://unpkg.com/[email protected]/lib/index.js"></script>    <!-- built files will be auto injected -->  </body></html>

使用unpkg.com这个CDN服务中对应的vue和element-ui,但是应该制定要使用的版本


2. 修改vue.config.js配置

在configurewebpack键中使用 externals :

module.exports = {  ...  configureWebpack: {    devtool: 'eval-source-map',    output: {      filename: 'static/js/admin/[name].js',      chunkFilename: 'static/js/admin/[name].js'    },    externals: {  // 新加这部分      'vue': 'Vue',      'element-ui': 'ELEMENT'    }  },  ...}

这样在编译时就不会把这2个库打包进来了


3. 去掉src/main.js部分逻辑

把原来的对应用法去掉(下面展示git diff的效果):

diff --git a/admin/src/main.js b/admin/src/main.jsindex cdc8eb9..165c77e 100644--- a/admin/src/main.js+++ b/admin/src/main.js@@ -4,9 +4,6 @@ import Cookies from 'js-cookie' import 'normalize.css/normalize.css' // A modern alternative to CSS resets-import Element from 'element-ui'-import 'element-ui/lib/theme-chalk/index.css'- import '@/styles/index.scss' // global css import App from './App'@@ -17,9 +14,7 @@ import './icons' // icon import * as filters from './filters' // global filters-Vue.use(Element, {-    size: Cookies.get('size') || 'medium', // set element-ui default size-})+Vue.prototype.$ELEMENT = { size: Cookies.get('size') || 'medium' };
验证效果

现在重新build就可以看到 chunk-vendors.js 文件的变化:

❯ ll dist/static/js/admin/ |grep chunk-vendors.js-rw-r--r-- 1 dongwm staff 1.1M Aug 17 14:26 chunk-vendors.js

从5.3M -> 1.1M,降了约80%,而且在线上Nginx配置了Gzip压缩,文件会更小,优化完成~

另外也解释下没把vuex、vue-router、axios等库也拆出来。优化的起因是库体积大,而这些库都比较小,没有强烈优化的意愿。另外在我的项目经验中,拆了之后用CDN会让请求数会变多,非常容易让整体CDN服务变慢。大家可以试试,如果页面外链的资源太多反而速度更慢,还不如现在这些都压缩在一个文件中来的速度快呢。


减少chunk-378562d0.js体积

如果你细心可能会觉得编译后的文件名字很奇怪,有很多chunk-开头的文件:

❯ ll dist/static/js/admin/ |grep chunk-rw-r--r-- 1 dongwm staff 323K Aug 17 14:26 chunk-20f6014c.js-rw-r--r-- 1 dongwm staff 5.1K Aug 17 14:26 chunk-2d0ac00f.js-rw-r--r-- 1 dongwm staff 5.1K Aug 17 14:26 chunk-2d0b1605.js-rw-r--r-- 1 dongwm staff  13K Aug 17 14:26 chunk-2d0babdf.js-rw-r--r-- 1 dongwm staff 3.1K Aug 17 14:26 chunk-2d0cfa15.js-rw-r--r-- 1 dongwm staff 4.5K Aug 17 14:26 chunk-2d230fe7.js-rw-r--r-- 1 dongwm staff 2.8K Aug 17 14:26 chunk-2d2382a4.js-rw-r--r-- 1 dongwm staff  28K Aug 17 14:26 chunk-4ee4a833.js-rw-r--r-- 1 dongwm staff  77K Aug 17 14:26 chunk-685bad3f.js-rw-r--r-- 1 dongwm staff 8.0M Aug 17 14:26 chunk-6fdb661a.js-rw-r--r-- 1 dongwm staff  77K Aug 17 14:26 chunk-7425814b.js-rw-r--r-- 1 dongwm staff  48K Aug 17 14:26 chunk-ecbac3dc.js-rw-r--r-- 1 dongwm staff 1.1M Aug 17 14:26 chunk-vendors.js

为什么要这么搞呢?其实这是当时写代码时候就做过得一个优化「按需加载」,我们回忆一下router.js文件中的路由的写法,就拿登录页举例吧:

{  name: 'login',  path: '/login',  component: () => import('@/views/login'),  hidden: true},

代码分离(Code Splitting)是Webpack 中最引人注目的特性之一。此特性能够把代码分离到不同的bundle 中,然后可以按需加载或并行加载这些文件。 () => import('@/views/login') 就是一种按需加载的写法,我最喜欢这么用。其他的代码分离方案我这里就不介绍了,大家有兴趣可以去了解。

这样用户就不用一次加载整个大文件,而是把每个页面路由对应的模块分离成不同的chunk文件,按需加载。

PS: 当然对于我们这个管理后台的例子,除了CreatePost页复杂一些,其他的都算简单,所以不用代码分离文件总体也很小,另外代码分离是每个chunk文件还包含了一部分重复的代码,所以不拆也可以接受。

好,说回来。其实如果你用心想一下,就知道上面那个 chunk-6fdb661a.js 是指的那个页面。想想那个页面逻辑最复杂?对,就是CreatePost页面,因为里面有tui-editor,它用到了highlight.js、codemirror等等。

当然,看report.html文件也能看到,大家可以翻到前面看看那张截图。里面占用空间大的包含tui-editor-Editor.js、highlight.js、codemirror.js和jQuery等。

一开始我的思路也是 拆 ,但是拆完之后发现,由于页面上unpkg网站请求太多,这些文件加载时间都很长,反而更慢了。后来又试了下「组件按需引入」,发现成本高收益很低,最终文件没怎么降下来。

其实一开始用tui-editor是一个无奈之举,我本来不喜欢它的理由之一正是现在它暴露出来的缺点: 依赖太多,文件太大。

怎么办呢?换。改用其他Markdown编辑器方案!然后搜索了一下,从官网找到了一个简单的例子,把它改造了一下,够用。

我把 src/components/MarkdownEditor/index.vue 改成了如下:

<template>  <div id="editor">    <textarea v-model="value" @input="update" v-bind:style="{ height: editorHeight}" @keyup="$emit('update:value', value);"></textarea>    <div v-html="compiledMarkdown"></div>  </div></template><script>// import _ from 'lodash'import marked from 'marked'import debounce from 'lodash/debounce'export default {  name: 'MarddownEditor',  props: {    value: {      type: String,      default: ''    },    height: {      type: String,      required: false,      default: '300px'    }  },  computed: {    compiledMarkdown() {      return marked(this.value)    },    editorHeight() {      return this.height    },  },  methods: {    update() {      debounce((e) => {        this.value = e.target.value      }, 300)    }  }}</script>

其中debounce可以直接import的,没有把lodash库都引入。这点也要注意:按需,按需,按需!

这样就换了编辑器效果了(当然也要安装marked和lodash)。和之前的tui-editor方案相比,是有一些缺点的:

没有菜单栏。我觉得大家都会Markdown语法,菜单栏本来也比较鸡肋预览方式不一样。原来是用鼠标切换编辑和预览模式,现在是分了左右2栏,左面是编辑,右面是直接显示Markdown渲染后的效果。当然这部分花点时间也能实现原来的切换编辑/预览的效果,不会对编译后的文件体积产生什么影响。

当然优点也非常明显:文件很小。编译后再看一下:

❯ ll ../static/js/admin/total 2.3M-rw-r--r-- 1 dongwm staff 388K Aug 17 14:56 app.js-rw-r--r-- 1 dongwm staff 323K Aug 17 14:56 chunk-20f6014c.js-rw-r--r-- 1 dongwm staff 5.1K Aug 17 14:56 chunk-2d0ac00f.js-rw-r--r-- 1 dongwm staff 5.1K Aug 17 14:56 chunk-2d0b1605.js-rw-r--r-- 1 dongwm staff  13K Aug 17 14:56 chunk-2d0babdf.js-rw-r--r-- 1 dongwm staff 3.1K Aug 17 14:56 chunk-2d0cfa15.js-rw-r--r-- 1 dongwm staff 4.5K Aug 17 14:56 chunk-2d230fe7.js-rw-r--r-- 1 dongwm staff 2.8K Aug 17 14:56 chunk-2d2382a4.js-rw-r--r-- 1 dongwm staff  28K Aug 17 14:56 chunk-4ee4a833.js-rw-r--r-- 1 dongwm staff  77K Aug 17 14:56 chunk-685bad3f.js-rw-r--r-- 1 dongwm staff  77K Aug 17 14:56 chunk-7425814b.js-rw-r--r-- 1 dongwm staff 259K Aug 17 14:56 chunk-a1deec84.js-rw-r--r-- 1 dongwm staff  48K Aug 17 14:56 chunk-ecbac3dc.js-rw-r--r-- 1 dongwm staff 1.1M Aug 17 14:56 chunk-vendors.js

现在全部文件加起来才2.3M,比一开始的15M降了约85%!


减少Chunk文件数量

对于我们这个管理后台项目,除了CreatePost页复杂一些,其他的页面都算简单,前面我们看到一大堆chunk-前缀的js和css的文件,其中很多文件很小。大家想想,打开一个页面时要访问很多静态文件势必影响加载静态资源的时间。

之前已经说过了,这是为了做代码分离(Code Splitting)。但是当我们优化之后,「文件多且每个文件小」就成了一个问题。怎么做呢?就是「合」。也就是修改src/router.js中的路由,直接import。比如Home,原来这么写:

{    path: '/',    component: Layout,    redirect: '/home',    children: [        {            path: 'home',            component: component: () => import('@/views/home'), // 注意这句            name: 'Home',            meta: { title: 'Home', icon: 'dashboard', affix: true }        }    ]},

现在这么写:

import Home from '@/views/home'{    path: '/',    component: Layout,    redirect: '/home',    children: [        {            path: 'home',            component: Home, // 直接写引入的模块            name: 'Home',            meta: { title: 'Home', icon: 'dashboard', affix: true }        }    ]},

不过我只把User/Post相关的逻辑改成上面这样用,但是也能极大的减少了文件的数量,且总文件大小也可接受:

❯ ll dist/static/*/admin/dist/static/css/admin/:total 44K-rw-r--r-- 1 dongwm staff  34K Aug 17 16:50 app.css-rw-r--r-- 1 dongwm staff 1.5K Aug 17 16:50 chunk-45698e1a.css-rw-r--r-- 1 dongwm staff 1.9K Aug 17 16:50 chunk-vendors.cssdist/static/js/admin/:total 2.1M-rw-r--r-- 1 dongwm staff 761K Aug 17 16:50 app.js-rw-r--r-- 1 dongwm staff 4.5K Aug 17 16:50 chunk-2d230fe7.js-rw-r--r-- 1 dongwm staff 2.8K Aug 17 16:50 chunk-2d2382a4.js-rw-r--r-- 1 dongwm staff  28K Aug 17 16:50 chunk-45698e1a.js-rw-r--r-- 1 dongwm staff 1.3M Aug 17 16:50 chunk-vendors.js

细心的话,可以看到文件变得更小了(原来2.3,现在2.1), 这是因为chunk文件中会有一部分重复代码,节省文件数量也达到了减少总体积的目的。

PS: 如果希望编译时取消Splitchunks,也就是合并chunk-vendors.XX到app.XX(JS或者CSS),可以在chainWebpack里加这么一段:

...chainWebpack: config => {  config.optimization    .splitChunks({      cacheGroups: {}    })...

好啦,就优化到这里了~

原文 http://dongwm.com/post/152/


  • 上一条:
    React的export default和export不一样的地方
    下一条:
    Vue实现吸顶效果
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 使用 Alpine.js 排序插件对元素进行排序(0个评论)
    • 在js中使用jszip + file-saver实现批量下载OSS文件功能示例(0个评论)
    • 在vue中实现父页面按钮显示子组件中的el-dialog效果(0个评论)
    • 使用mock-server实现模拟接口对接流程步骤(0个评论)
    • vue项目打包程序实现把项目打包成一个exe可执行程序(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-03
    • 2018-04
    • 2018-05
    • 2018-06
    • 2018-09
    • 2018-11
    • 2018-12
    • 2019-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2021-04
    • 2021-05
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客