zoukankan      html  css  js  c++  java
  • Vue项目性能优化整理

     以下方式基于 @vue/cli 快速搭建的交互式项目脚手架

    1. 路由懒加载

    当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

    结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

     1 import Vue from 'vue'
     2 import Router from 'vue-router'
     3 import store from './store'
     4 import Home from './views/Home.vue'
     5 
     6 Vue.use(Router)
     7 
     8 const router = new Router({
     9   routes: [
    10     {
    11       path: '/',
    12       name: 'home',
    13       component: Home,
    14     },
    15     {
    16       path: '/make',
    17       name: 'make',
    18       component: () => import(/* webpackChunkName: "make" */ './views/Make.vue'),
    19     }
    20   ],
    21 })

    2. webpack动态导入

    将statically import(静态导入) 改为 dynamic import(动态导入)进行代码拆分

     1 import(/* webpackChunkName: "html2canvas" */ 'html2canvas').then(
     2   ({ default: html2canvas }) => {
     3     html2canvas(document.querySelector('.container'), {
     4       scale: window.devicePixelRatio,
     5       allowTaint: false,
     6       useCORS: true,
     7     }).then(canvas => {
     8       console.log(canvas.toDataURL('image/jpeg', 0.9))
     9     })
    10   }
    11 )

    3. 预取/预加载模块(prefetch/preload module)

    在声明 import 时,使用下面这些内置指令,可以让 webpack 输出 "resource hint(资源提示)",来告知浏览器:

      prefetch(预取):将来某些导航下可能需要的资源
      preload(预加载):当前导航下可能需要资源

    import(/* webpackPrefetch: true */ 'LoginModal');
    
    import(/* webpackPreload: true */ 'ChartingLibrary');

    这会生成 <link rel="prefetch" href="login-modal-chunk.js"> 并追加到页面头部,指示着浏览器在闲置时间预取 login-modal-chunk.js 文件。

    只要父 chunk 完成加载,webpack 就会添加 prefetch hint(预取提示)。

    与 prefetch 指令相比,preload 指令有许多不同之处:

    • preload chunk 会在父 chunk 加载时,以并行方式开始加载。prefetch chunk 会在父 chunk 加载结束后开始加载。
    • preload chunk 具有中等优先级,并立即下载。prefetch chunk 在浏览器闲置时下载。
    • preload chunk 会在父 chunk 中立即请求,用于当下时刻。prefetch chunk 会用于未来的某个时刻。
    • 浏览器支持程度不同。

    vue默认开启,可在vue.config.js中全局禁用prefetch,再针对指定模块开启。

    chainWebpack: config => {
      config.plugins.delete('prefetch')
    },

    4. 添加Gzip打包配置(compression-webpack-plugin)

      yarn add compression-webpack-plugin -D

    configureWebpack: config => {
      const CompressionPlugin = require('compression-webpack-plugin')
      config.plugins.push(new CompressionPlugin())
    }

    5. 添加页面预渲染(prerender-spa-plugin)

    在单页应用程序中预呈现静态HTML,可以极大的提高网页访问速度,而且配合一些meat插件,基本可以满足SEO需求。

    预渲染基本上是在启动无头浏览器,加载应用程序的路由并将结果保存到静态HTML文件中。然后将其与以前使用的任何静态文件服务解决方案一起使用,是无需更改代码或添加服务器端渲染的解决方法。

    不过,它仅适用于HTML5 history,因为每个预渲染的路由都会生成一个对应的HTML,在hash模式下使用只会有一个HTML。

      yarn add prerender-spa-plugin -D

     1 configureWebpack: config => {
     2   const path = require('path')
     3   const PrerenderSPAPlugin = require('prerender-spa-plugin')
     4   config.plugins.push(
     5     new PrerenderSPAPlugin({
     6       staticDir: path.join(__dirname, 'dist'),
     7       routes: ['/'],
     8       minify: {
     9         collapseBooleanAttributes: true,
    10         collapseWhitespace: true,
    11         keepClosingSlash: true,
    12         decodeEntities: true,
    13         sortAttributes: true,
    14       },
    15       renderer: new PrerenderSPAPlugin.PuppeteerRenderer({
    16         renderAfterDocumentEvent: 'render-event',
    17         renderAfterTime: 5000,
    18         // headless: false,
    19       }),
    20     })
    21   )
    22 }
    23 
    24 new Vue({
    25   router,
    26   store,
    27   render: h => h(App),
    28   mounted() {
    29     // 预渲染 renderAfterDocumentEvent.
    30     document.dispatchEvent(new Event('render-event'))
    31   },
    32 }).$mount('#app')

    prerender-spa-plugin 利用了 Puppeteer 的爬取页面的功能。 Puppeteer 是一个 Chrome官方出品的 headlessChromenode 库。它提供了一系列的 API, 可以在无 UI 的情况下调用 Chrome 的功能, 适用于爬虫、自动化处理等各种场景。它很强大,所以很简单就能将运行时的 HTML 打包到文件中。原理是在 Webpack 构建阶段的最后,在本地启动一个 Puppeteer 的服务,访问配置了预渲染的路由,然后将 Puppeteer 中渲染的页面输出到 HTML 文件中,并建立路由对应的目录。

    6. 压缩js,删除console(terser-webpack-plugin)

      yarn add terser-webpack-plugin -D

    1 configureWebpack: config => {
    2   const TerserPlugin = require('terser-webpack-plugin')
    3   config.optimization.minimizer.push(
    4     new TerserPlugin({
    5       extractComments: false,
    6       terserOptions: { compress: { drop_console: true } },
    7     })
    8   )
    9 }

    7. bundle 分析(webpack-bundle-analyzer)

    将 bundle 内容展示为便捷的、交互式、可缩放的树状图形式。

      yarn add -D webpack-bundle-analyzer

    1 configureWebpack: config => {
    2   const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
    3     .BundleAnalyzerPlugin
    4   config.plugins.push(new BundleAnalyzerPlugin())
    5 }

    8. WebP

    WebP(发音 weppy),是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28% 的文件大小。

    不过WebP目前在IOS上兼容性不好,可以使用JavaScript进行检测,对支持 WebP 的用户输出 WebP 图片。

     1 created() {
     2   const htmlClass = document.documentElement.classList
     3   this.checkWebpSupport() ? htmlClass.add('webps') : htmlClass.remove('webps')
     4 }
     5 
     6 checkWebpSupport() {
     7   try {
     8     return (
     9       document
    10         .createElement('canvas')
    11         .toDataURL('image/webp')
    12         .indexOf('data:image/webp') === 0
    13     )
    14   } catch (err) {
    15     return false
    16   }
    17 }

    记一次BUG:

      在默认情况下,页面加载完成执行 this.checkWebpSupport() && document.documentElement.classList.add('webps'),没有问题。

      但使用了prerender-spa-plugin进行预渲染后,因为执行预渲染的浏览器是支持WebP的,所有会直接在页面中加上'webps'类,所以即使浏览器不支持WebP,不执行此方法也会有该类名。

    9. 网页性能优化测试(googlespeed)

    进行网页测试,根据优化建议针对性的修改,提高网页加载速度。

      https://www.googlespeed.cn/

  • 相关阅读:
    iOS 3DTouch 的开发套路大全
    启动图后面 添加有倒计时的广告图
    激光推送报错:APNs is not available,please check your provisioning profile and certification 和 设置别名问题 app not registed, give up set tag:
    iOS 微信和支付宝关于回调处理
    Android 开机自启动应用
    android快捷键
    如何让Eclipse的智能提示像VS一样霸气
    Win7下Eclipse中文字体太小
    Android的SharedPreferences实用技巧
    Java基础知识总结
  • 原文地址:https://www.cnblogs.com/huliang56/p/11887957.html
Copyright © 2011-2022 走看看