最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 不到一秒才叫优化

    正文概述 掘金(道道里)   2021-03-05   547

    之前做完的一个项目,业务逻辑写完之后,首屏渲染能到3~4秒,这对于用户体验是不能接受的,所以忙里偷闲把项目优化完之后:

    不到一秒才叫优化

    http发送到响应时间:705ms,DOM构建完毕:452ms,页面加载完毕:678ms,清爽的感觉很上头~看来优化还是很有必要的!所以本篇记录一下优化过程。

    正文

    1. UglifyJsPlugin

      UglifyJsPlugin 是一个webpack的解析、混淆、压缩JS的工具,低版本的 UglifyJsPlugin 是不支持ES6的,所以在使用的时候要注意要么升级版本,要么添加文件 .bablelrc,在里面添加

      {
        "pressets": ["es2015"]
      }
      
    2. cdn

      cdn 的话,尽可能把所有资源都使用cdn,比如 vuevuexvue-routeraxiosechart,举个例子:

      // cdn链接
      const cdn = {
        externals: {
          echarts: "echarts",
          "ant-design-vue": "AntDesignVue",
          vue: "Vue",
          "vue-router": "VueRouter",
          vuex: "Vuex",
          axios: "axios"
        },
        // cdn的css链接
        css: [],
        // cdn的js链接
        js: [
          "https://cdn.jsdelivr.net/npm/echarts@4/dist/echarts.min.js",
          "https://cdn.bootcss.com/vue/2.6.10/vue.min.js",
          "https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js",
          "https://cdn.bootcss.com/vue-router/3.0.7/vue-router.min.js",
          "https://cdn.bootcss.com/axios/0.18.0/axios.min.js"
        ]
      };
      

      然后在两个地方使用,一个是webpack的 chainWebpack 配置,一个是 configureWebpack 的配置:

      // 是否为生产环境
      const isProduction = process.env.NODE_ENV !== "development";
      // 本地环境是否需要使用cdn
      const devNeedCdn = true;
         
      module.exports = {
        // webpack 配置
        chainWebpack: config => {
          // ...
          config.plugin("html").tap(args => {
            // 生产环境或者本地需要cdn时,才注入cdn
            if (isProduction || devNeedCdn) args[0].cdn = cdn;
            return args;
          });
      	},
        configureWebpack: config => {
          // 用cdn方式引入,则构建时要忽略相关资源
          if (isProduction || devNeedCdn) config.externals = cdn.externals;
        }
      }
         
      

      这样 cdn 就配置好了,如果想在开发环境也使用它的话,需要在入口文件 index.html 中把CSS和JS的资源加载改成:

      <!-- 使用CDN的CSS文件 -->
      <% for (var i in htmlWebpackPlugin.options.cdn &&
         htmlWebpackPlugin.options.cdn.css) { %>
      <link
         href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"
         rel="stylesheet"
      />
      <% } %>
           
      <!-- 使用CDN的JS文件 -->
      <% for (var i in htmlWebpackPlugin.options.cdn &&
        htmlWebpackPlugin.options.cdn.js) { %>
      <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> 
      <% } %>
      

      相当于动态加载了webpack配置里的cdn文件。

    3. CompressionWebpackPlugin

      CompressionWebpackPlugin 是webpack的 Gzip 压缩插件,官方介绍是:提供带 Content-Encoding 编码的压缩版的资源,下面是它的配置项:

      配置项类型默认值描述
      test{RegExp}.处理所有匹配此 {RegExp} 的资源asset{String}[path].gz[query]目标资源名称。[file] 会被替换成原资源。[path] 会被替换成原资源路径, [query] 替换成原查询字符串filename{Function}false一个 (asset) => asset 函数,接收原资源名(通过 asset 选项)返回新资源名algorithm{String|Function}gzip可以是 (buffer, cb) => cb(buffer) 或者是使用 zlib 里面的算法的 {String}threshold{Number}0只处理比这个值大的资源。按字节计算minRatio{Number}0.8只有压缩率比这个值小的资源才会被处理deleteOriginalAssets{Boolean}false是否删除原资源

      这边我用了网上大家常用的配置:

      configureWebpack: config => {
        const productionGzipExtensions = ["html", "js", "css"];
        config.plugins.push(
          new CompressionWebpackPlugin({
            filename: "[path].gz[query]",
            algorithm: "gzip",
            test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"),
            threshold: 10240, // 只有大小大于该值的资源会被处理 10240
            minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
            deleteOriginalAssets: false // 删除原文件
          })
        );
      }
      

      注意,如果使用 Gzip 的话,打包后会出现一个 x.gz 文件,比如 index.html,打包后会多一个 index.html.gz 文件,如果服务器端(nginx等)不开启 gzip 功能,加载的其实还是 index.html,开启之后就会加载 index.html.gz 来替代加载 index.html了。

      在 nginx 中可以这么配置(nginx.conf):

      #gzip  on;
      # 开启gzip
      gzip on;
         
      # 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
      gzip_min_length 1k;
         
      # gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
      gzip_comp_level 2;
         
      # 进行压缩的文件类型。javascript有多种形式,后面的图片压缩不需要的可以自行删除
      gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript ;
         
      # 是否在http header中添加Vary: Accept-Encoding,建议开启
      gzip_vary on;
         
      # 设置压缩所需要的缓冲区大小     
      gzip_buffers 4 16k;
      

      重启之后查看请求接口的响应头的 Content-Encodinggzip 的话说明开启成功。

    4. moment

      由于用到了 moment,所以也得把它压缩一下,它可是贼大的,因为它的npm包里加载了很多的语言版本,所以一般情况下,只需要中文版就可以了,所以在webpack的配置里,把moment的语言包给忽略掉,然后在 main.js 中加载一个语言包 import "moment/locale/zh-cn",这样体积就会小很多。

    5. splitChunks

      splitChunks 可以对大包进行拆分,对小包进行合并,防止模块重复打包,从而减少请求资源的大小和此时,这个要根据实际情况去调整。

    6. 代码逻辑

      加了以上的操作之后,可以使用插件 webpack-bundle-analyzer 来看下优化的效果,如果还有大块的,就把业务继续优化,主要从引用、封装入手,能抽出来的尽量抽出来,把工具和业务分开。以vue为例的话,可以注意以下几点:

      1. v-if 和 v-show

        v-if 适合条件改变很少的情况,v-show 适合频繁切换条件的情况

      2. computed 和 watch

        computed 适合在计算和依赖场景使用,watch 适合数据变化的异步操作

      3. v-for 必须添加 key

        vue的 diff 算法会关联到 key,所以当状态更新时,key的作用很大,为了优化效率,建议添加key(现在开发工具已经做了提醒)

      4. v-for 里不使用 v-if

        v-for 的优先级要比 v-if 高,如果vue的循环节点每次都重新遍历整个数组,就需要花很多时间

      5. event

        在页面上使用了事件之后,离开的时候最好把事件给销毁(全局除外),可以防止内存泄漏(比如图表的加载和重绘)

      6. 图片懒加载

        图片资源懒加载可以使用 vue-lazyload 插件,保证只加可视区域内的图片

      7. 路由懒加载

        如果不用路由懒加载的话,页面访问就会把所有路由都加载完毕之后再加载,如果资源过多,白屏的出现几率就会大大增加,所以路由要改成只在访问的时候加载:component: () => import("./views/Login.vue")

      8. 三方插件按需引入

        很多三方插件包很大,所以它们大部分也都给了按需加载的使用说明

      9. 防抖和节流

        对于触发事件的时间和时机判定,防止用户频繁点击和误操作,它们两个也算优化的一部分


    起源地下载网 » 不到一秒才叫优化

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元