当前位置: 首页 > article >正文

通过 Lighthouse 和 speed-measure-webpack 插件分析优化构建速度与体积

一、Lighthouse
Lighthouse是 Google Chrome 推出的一款开源自动化工具,谷歌浏览器中已经集成,它可以搜集多个现代网页性能指标,分析 Web 应用的性能并生成报告,为开发人员进行性能优化的提供了参考方向。

Lighthouse会生成一份报告,会给你的页面跑出一个分数来。 分别是页面性能(performance)、Progressive(渐进式 Web 应用)、Accessibility(可访问性)、Best Practices(最佳实践)、SEO 五项指标的跑分。甚至针对我们的性能问题给出了可行的建议、以及每一项优化操作预期会帮我们节省的时间。

Lighthouse 几个比较重要的性能指标项:

首次内容绘制(First Contentful Paint):即浏览器首次将任意内容(如文字、图像、canvas 等)绘制到屏幕上的时间点。简单来说就是用户导航到访问页面后浏览器呈现第一段 DOM 内容所需的时间。1.8 秒内达到快速级别。
可交互时间(Time to Interactive):指的是所有的页面内容都已经成功加载,且能够快速地对用户的操作做出反应的时间点。
速度指标(Speed Index):衡量了首屏可见内容绘制在屏幕上的速度。在首次加载页面的过程中尽量展现更多的内容,往往能给用户带来更好的体验,所以速度指标的值约小越好。
总阻塞时间(Total Blocking Time):指First Contentful Paint 首次内容绘制 (FCP)与Time to Interactive 可交互时间 (TTI)之间的总时间
最大内容绘制(Largest Contentful Paint):度量标准报告视口内可见的最大图像或文本块的呈现时间
累积布局偏移(Cumulative Layout Shift):衡量的是页面整个生命周期中每次元素发生的非预期布局偏移得分的总和。每次可视元素在两次渲染帧中的起始位置不同时,就说是发生了LS(Layout Shift)、
二、speed-measure-webpack-plugin
2.1 使用
借助 speed-measure-webpack-plugin 插件,分析 webpack 的总打包耗时以及每个 plugin 和 loader 的打包耗时,从而让我们对打包时间较长的部分进行针对性优化。
安装

yarn add speed-measure-webpack-plugin -D

vue.config.js配置

// 导入速度分析插件
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
module.exports = {

  configureWebpack: (config) => {
    config.plugins.push(new SpeedMeasurePlugin())
    ...

  }
}

配置完成之后,执行打包指令的时候会看到详细的每个loaders和plugins的构建时间,这样就能够对构建时间进行一个量化。

2.2 优化
2.2.1 缩小文件的搜索范围(配置include 、exclude、alias)

通过配置include exclude也可以减少webpack loader的搜索转换时间。

module.exports = {
    chainWebpack: (config) => {
    config.module
      .rule('js')
      .test(/\.js[x]?$/)
      .include.add(path.resolve(__dirname, 'src'))
      .end()
    config.resolve.alias.set('@/', resolve('src/'))
    config.resolve.alias.set('@test', resolve('src/views/test/'))
  }
}

2.2.2 Happypack多进程构建
在使用 Webpack 对项目进行构建时,会对大量文件进行解析和处理。当文件数量变多之后,Webpack 构件速度就会变慢。由于运行在 Node.js 之上的 Webpack 是单线程模型的,所以 Webpack 需要处理的任务要一个一个进行操作。

而 Happypack 的作用就是将文件解析任务分解成多个子进程并发执行。子进程处理完任务后再将结果发送给主进程。所以可以大大提升 Webpack 的项目构件速度。

HappyPack的原理就是每次webpack解析一个模块,HappyPack会将它及它的依赖分配给worker进程中; HappyPack会将模块进行一个划分,比如我们有多个模块,这些模块交给HappyPack,首先在webpack compiler(钩子)的run方法之后,进程就会到达HappyPack,HappyPack会做一些初始化,初始化之后会创建一个线程池,线程池会将构建任务里面的模块进行一个分配,比如会将某个模块以及它的一些依赖分配给其中的一个HappyPack线程,以此类推,那么一个HappyPack的一个线程池会包括多个线程,这时候线程池的这些线程会各自去处理其中的模块以及它的依赖,处理完成之后会有一个通信的过程,会将处理好的资源传输给HappyPack的一个主进程,完成整个的一个构建过程。

安装

yarn add happypack  -D

vue.config.js配置


const Happypack = require('happypack')
module.exports = {
    configureWebpack: (config) => {
     // 多线程优化构建速度
     config.plugins.push(
      new Happypack({
        loaders: ['babel-loader', 'vue-loader', 'url-loader'],
        cache: true,
        threads: 3 // 线程数取决于你电脑性能的好坏,好的电脑建议开更多线程
      })
    )
  }
}

2.2.3 通过缓存提升二次打包速度(HardSourceWebpackPlugin)
HardSourceWebpackPlugin是 webpack 的插件,用于为模块提供中间缓存步骤。,缓存默认的存放路径是: node_modules/.cache/hard-source。配置 HardSourceWebpackPlugin,首次构建时间没有太大变化,但是第二次开始,构建时间大约可以节约 80%。
安装

yarn add hard-source-webpack-plugin -D

vue.config.js配置


const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
module.exports = {
    chainWebpack: (config) => {
     // 打包缓存加速
     config.plugin('hardSource').use(HardSourceWebpackPlugin)
  }
}

3. 分析并优化打包体积
3.1 分析打包体积
webpack-bundle-analyzer,这个插件在可视化网页包中输出文件的大小,并且提供了交互式可缩放的树形图。
安装

yarn add webpack-bundle-analyzer -D

vue.config.js配置

在vue.config.js中配置
module.exports = {
    ...,
configureWebpack: () => { 
        config.plugins.push(
            new BundleAnalyzerPlugin()
        )
    }
    
}, // vue-cli3已内置,在package里面的serve代码命令里面加--report即可

3.2 优化打包体积
3.2.1 js文件最小化处理
代码的最优化, 我们会通过chainWebpak来处理,这里使用的是webpack配置中的optimization来处理的。
在vue.config.js中配置

module.exports = {
  chainWebpack: config => {
    config.optimization.minimize(true);
  }
}

3.2.2 splitChunks 分割代码
代码分割,顾名思义就是将某一些相关的文件放入到相应的文件中, 为了优化性能,比如快速打开首屏,利用缓存等,我们需要对bundle进行拆分。
在vue.config.js中配置

module.exports = {
    
    chainWebpack: config => {
        config.optimization.minimize(true);
        config.optimization.splitChunks({
          chunks: 'all'// 表示哪些代码需要优化,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为async
        })
    }
}

splitChunks 插件配置
3.2.3 公用代码提取,使用 CDN 加载
cdn是一套内容分发服务,其本质是将一些公共资源缓存到离用户最近的服务器上,减少直接从数据源服务器获取资源的响应时间。 我们使用vue, vuex, vue-router, element-ui这些公共的cnd资源,可以极大的减轻对服务器的压力,实质是减少了对我们自己服务器的http请求。
在vue.config.js中配置

module.exports = {
    
    chainWebpack: config => {
        config.optimization.minimize(true);
        config.optimization.splitChunks({
          chunks: 'all'
        })
        config.externals({
            vue: 'vue',
            vuex: 'vuex',
            'vue-router': "'vue-router'",
            'element-ui': "'element-ui'"
        })
    }
}

main.js配置

import Vue from 'vue'
import App from './App.vue'

import ELEMENT from 'element-ui'
// 注释,这个已经通过CDN 加载了
// import "element-ui/lib/theme-chalk/index.css";
import axios from 'axios'
import * as echarts from 'echarts';
import VueRouter from 'vue-router'
import Vuex from 'vuex'
 import router from './router'

Vue.use(ELEMENT)

Vue.use(VueRouter)
Vue.use(Vuex)

Vue.prototype.$http = axios
Vue.prototype.$echarts = echarts
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  router
}).$mount('#app')

index.html文件配置

<head> 
    ...
    <!-- element-ui 组件引入样式 -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/element-ui/2.5.4/theme-chalk/index.css">
</head> 
<body> 
    <!-- 引入vue -->
    <script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
    <!-- 引入vuex -->
    <script src="https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
    <!-- 引入vue-router -->
    <script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
    <!-- 引入element-ui组件库 -->
    <script src="https://cdn.bootcss.com/element-ui/2.5.4/index.js"></script>
    <!-- 引入mint-ui组件库 -->
    <script src="https://cdn.bootcss.com/mint-ui/2.2.13/index.js"></script>
    <div id="app"></div> 
</body>

http://www.kler.cn/news/364019.html

相关文章:

  • Spring--4
  • ARM学习(33)英飞凌(infineon)PSOC 6 板子学习
  • Nest.js 实战 (十五):前后端分离项目部署的最佳实践
  • 梳理一下spring中,与message相关的知识点
  • 用户账户与授权UAA与OAuth2
  • 【C++11】右值引用和移动语义
  • 算法通关--单调栈
  • 无废话、光速上手 React-Router
  • Anaconda从旧版本更新
  • 用nginx实现多ip访问多网址
  • Redis缓存实战-使用Spring AOP和Redis实现Dao层查询缓存优化实战
  • 云原生后端概述
  • RabbitMQ 确认模式(Acknowledgements Mode)详解
  • 海外媒体发稿:外媒宣发之《时代》杂志 TIME 的魅力
  • 使用 NumPy 和 Matplotlib 实现交互式数据可视化
  • 【Android】AHandler/AMessage/ALooper机制
  • Java:关于哈希表
  • 2024年808数据结构答案
  • css知识点梳理
  • 如何在服务器上部署开源大模型 GLM-4-9B-Chat 并应用到RAG应用中
  • 【传知代码】机器学习在情绪预测中的应用(论文复现)
  • 虚拟机的 NAT 模式 或 Bridged 模式能够被外界IPping通
  • IDEA无法生成自动化序列serialVersionUID及无法访问8080端口异常的解决方案
  • 计算机毕业设计PySpark+大模型农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop
  • 【亚马逊云】基于 Amazon EKS 搭建开源向量数据库 Milvus
  • 【ArcGIS Pro实操第4期】绘制三维地图