目录

前言

前不久看过掘金小册《前端性能优化原理与实践》,受益匪浅。“我深感性能优化实在是前端知识树中特别的一环——当你需要学习前端框架时,文档和源码几乎可以告诉你所有问题的答案,当你需要学习 Git 时,你也可以找到放之四海皆准的实践方案。但性能优化却不一样,它好像只能是一个摸索的过程。” 前端的性能优化一直是困扰我的一个问题, 我不知道哪些问题需要优化,这些问题又应该用什么方式和方法优化?即使知道却总感觉知之甚少,自己项目真正去做优化的却不多。“任何技术的掌握,都离不开一定比例的理论基础和实际操作的支撑。” 通过这个专题,记录自己了解的前端性能优化以及在自己的项目中去做优化。

webpack 的性能瓶颈

webpack 的构建过程太花时间

webpack 打包的结果体积太大

webpack 优化方案

优化Loader

优化 Loader 的文件搜索范围

module.exports = {

module: {

rules: [

{

// js 文件才使用 babel

test: /\.js$/,

loader: 'babel-loader',

// 只在 src 文件夹下查找

include: [resolve('src')],

// 不会去查找的路径

exclude: /node_modules/

}

]

}

}

将 Babel 编译过的文件缓存起来

loader: 'babel-loader?cacheDirectory=true'

DllPlugin 打包第三方库

DllPlugin 是基于 Windows 动态链接库(dll)的思想被创作出来的。这个插件会把第三方库单独打包到一个文件中,这个文件就是一个单纯的依赖库。这个依赖库不会跟着你的业务代码一起被重新打包,只有当依赖自身发生版本变化时才会重新打包。

用 DllPlugin 处理文件,要分两步走:

基于 dll 专属的配置文件,打包 dll 库

基于 webpack.config.js 文件,打包业务代码

以自己的vue项目为例,我的dll配置文件如下:

新建webpack.dll.config.js文件

const path = require('path')

const webpack = require('webpack')

const CleanWebpackPlugin = require('clean-webpack-plugin')

// dll文件存放的目录

const dllPath = 'public/vendor'

module.exports = {

entry: {

// 需要提取的库文件

vendor: ['vue', 'vue-router', 'vuex', 'axios', 'element-ui']

},

output: {

path: path.join(__dirname, dllPath),

filename: '[name].dll.js',

// vendor.dll.js中暴露出的全局变量名

// 保持与 webpack.DllPlugin 中名称一致

library: '[name]_[hash]'

},

plugins: [

// 清除之前的dll文件

new CleanWebpackPlugin(['*.*'], {

root: path.join(__dirname, dllPath)

}),

// 设置环境变量

new webpack.DefinePlugin({

'process.env': {

NODE_ENV: 'production'

}

}),

// manifest.json 描述动态链接库包含了哪些内容

new webpack.DllPlugin({

path: path.join(__dirname, dllPath, '[name]-manifest.json'),

// 保持与 output.library 中名称一致

name: '[name]_[hash]',

context: process.cwd()

})

]

}

在vue.config.js中配置dll

plugins: [

new webpack.DllReferencePlugin({

context: process.cwd(),

manifest: require('./public/vendor/vendor-manifest.json')

}),

// 将 dll 注入到 生成的 html 模板中

new AddAssetHtmlPlugin({

// dll文件位置

filepath: path.resolve(__dirname, './public/vendor/*.js'),

// dll 引用路径

publicPath: './vendor',

// dll最终输出的目录

outputPath: './vendor'

}),

]

HappyPack 并行打包

受限于 Node 是单线程运行的,所以 Webpack 在打包的过程中也是单线程的,特别是在执行 Loader 的时候,长时间编译的任务很多,这样就会导致等待的情况。

HappyPack 可以将 Loader 的同步执行转换为并行的,这样就能充分利用系统资源来加快打包效率了

module: {

loaders: [

{

test: /\.js$/,

include: [resolve('src')],

exclude: /node_modules/,

// id 后面的内容对应下面

loader: 'happypack/loader?id=happybabel'

}

]

},

plugins: [

new HappyPack({

id: 'happybabel',

loaders: ['babel-loader?cacheDirectory'],

// 开启 4 个线程

threads: 4

})

]

Tree Shaking 删除冗余代码

从 webpack2 开始,webpack 原生支持了 ES6 的模块系统,并基于此推出了 Tree-Shaking。webpack 官方是这样介绍它的:

Tree shaking is a term commonly used in the JavaScript context for dead-code elimination,

or more precisely, live-code import. It relies on ES2015 module import/export for the static

structure of its module system.

意思是基于 import/export 语法,Tree-Shaking 可以在编译的过程中获悉哪些模块并没有真正被使用,这些没用的代码,在最后打包的时候会被去除。

在 Webpack3 中,我们一般使用 UglifyJS 来删除压缩代码,我们可以使用 uglifyjs-webpack-plugin 来并行运行 UglifyJsPlugin,从而提高效率。

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {

plugins: [

new UglifyJsPlugin({

// 允许并发

parallel: true,

// 开启缓存

cache: true,

compress: {

// 删除所有的console语句

drop_console: true,

// 把使用多次的静态值自动定义为变量

reduce_vars: true,

},

output: {

// 不保留注释

comment: false,

// 使输出的代码尽可能紧凑

beautify: false

}

})

]

}

手动引入 UglifyJsPlugin 的代码其实是 webpack3 的用法,webpack4 现在已经默认使用 uglifyjs-webpack-plugin 对代码做压缩了——在 webpack4 中,我们是通过配置 optimization.minimize 与 optimization.minimizer 来自定义压缩相关的操作的。

按需加载

思想:

一次不加载完所有的文件内容,只加载此刻需要用到的那部分(会提前做拆分)

当需要更多内容时,再对用到的内容进行即时加载

已vue路由为例,把路由引入方式改为下面方式:

{

name: 'login',

path: '/login',

component: () => import('@/views/login/login.vue') // 按需加载

}

Gzip 压缩原理

摘自《前端性能优化原理与实践》

说到压缩,可不只是构建工具的专利。我们日常开发中,其实还有一个便宜又好用的压缩操作:开启 Gzip。

具体的做法非常简单,只需要你在你的 request headers 中加上这么一句:

accept-encoding:gzip

HTTP 压缩:

HTTP 压缩是一种内置到网页服务器和网页客户端中以改进传输速度和带宽利用率的方式。

在使用 HTTP 压缩的情况下,HTTP 数据在从服务器发送前就已压缩:兼容的浏览器将在下

载所需的格式前宣告支持何种方法给服务器;不支持压缩方法的浏览器将下载未经压缩的数据。

最常见的压缩方案包括 Gzip 和 Deflate。

以上是摘自百科的解释,事实上,大家可以这么理解:

HTTP 压缩就是以缩小体积为目的,对 HTTP 内容进行重新编码的过程

Gzip 的内核就是 Deflate,目前我们压缩文件用得最多的就是 Gzip。可以说,Gzip 就是 HTTP 压缩的经典例题。

该不该用 Gzip

如果你的项目不是极端迷你的超小型文件,我都建议你试试 Gzip。

有的同学或许存在这样的疑问:压缩 Gzip,服务端要花时间;解压 Gzip,浏览器要花时间。中间节省出来的传输时间,真的那么可观吗?

答案是肯定的。如果你手上的项目是 1k、2k 的小文件,那确实有点高射炮打蚊子的意思,不值当。但更多的时候,我们处理的都是具备一定规模的项目文件。实践证明,这种情况下压缩和解压带来的时间开销相对于传输过程中节省下的时间开销来说,可以说是微不足道的。

Gzip 是万能的吗

首先要承认 Gzip 是高效的,压缩后通常能帮我们减少响应 70% 左右的大小。

但它并非万能。Gzip 并不保证针对每一个文件的压缩都会使其变小。

Gzip 压缩背后的原理,是在一个文本文件中找出一些重复出现的字符串、临时替换它们,从而使整个文件变小。根据这个原理,文件中代码的重复率越高,那么压缩的效率就越高,使用 Gzip 的收益也就越大。反之亦然。

webpack 的 Gzip 和服务端的 Gzip

一般来说,Gzip 压缩是服务器的活儿:服务器了解到我们这边有一个 Gzip 压缩的需求,它会启动自己的 CPU 去为我们完成这个任务。而压缩文件这个过程本身是需要耗费时间的,大家可以理解为我们以服务器压缩的时间开销和 CPU 开销(以及浏览器解析压缩文件的开销)为代价,省下了一些传输过程中的时间开销。

既然存在着这样的交换,那么就要求我们学会权衡。服务器的 CPU 性能不是无限的,如果存在大量的压缩需求,服务器也扛不住的。服务器一旦因此慢下来了,用户还是要等。Webpack 中 Gzip 压缩操作的存在,事实上就是为了在构建过程中去做一部分服务器的工作,为服务器分压。

因此,这两个地方的 Gzip 压缩,谁也不能替代谁。它们必须和平共处,好好合作。作为开发者,我们也应该结合业务压力的实际强度情况,去做好这其中的权衡。

原文:https://www.cnblogs.com/shengmo/p/11816929.html

html压缩原理,webpack--前端性能优化与Gzip原理相关推荐

  1. 从渲染原理谈前端性能优化

    前言 合格的开发者知道怎么做,而优秀的开发者知道为什么这么做. 这句话来自<web性能权威指南>,我一直很喜欢,而本文尝试从浏览器渲染原理探讨如何进行性能提升. 全文将从网络通信以及页面渲 ...

  2. 前端性能优化之gzip压缩(压缩js、css、HTML,千万不能压缩图片!)

    gzip主要用来压缩html,css,javascript等静态文本文件,gzip 压缩的比率通常在3~10 倍之间,压缩后的体积能达到只有原本的30%左右,这样就能大大节省服务器的网络带宽和大大提升 ...

  3. 前端性能优化之gzip

    gzip是GNUzip的缩写,它是一个GNU自由软件的文件压缩程序.它最早由Jean-loup Gailly和Mark Adler创建,用于UNⅨ系统的文件压缩.我们在Linux中经常会用到后缀为.g ...

  4. 前端性能优化之 gzip+cache-control

    刚刚在Node.js环境下使用gzippo模块进行了测试. 使用gzip的压缩率惊人的好,达到了50%以上. 再加上express的staticCache,配合cache-control max-ag ...

  5. 前端性能优化——从 10 多秒到 1.05 秒

    https://lishaoy.net 关于 性能优化 是个大的面,这篇文章主要涉及到 前端 的几个点,如 前端性能优化 的流程.常见技术手段.工具等. 提及 前端性能优化 ,大家应该都会想到 雅虎军 ...

  6. 前端性能优化 -- 从 10 多秒到 1.05 秒

    关于 性能优化 是个大的面,这篇文章主要涉及到 前端 的几个点,如 前端性能优化 的流程.常见技术手段.工具等. 提及 前端性能优化 ,大家应该都会想到 雅虎军规,本文会结合 雅虎军规 融入自己的了解 ...

  7. 【前端性能优化实践】手把手教你实现webpack图片压缩插件

    前言 我想写一个系列:前端性能优化实践方案.网上虽然一搜一大把这样的文章,但大多缺乏体系化.也有很多讲性能优化的书籍,但其实想照着书上的知识进行实践,还是挺难的一件事. 这是该系列的第一篇文章 由于自 ...

  8. 前端性能优化之图像优化原理

    前端性能优化中,图像的优化是非常重要的一环,为什么要说图像的优化呢,而不是我们常见的图片优化?因为这里的图像包括矢量图和位图,我们常说的图片优化是指位图的优化.这篇文章转载至奇舞周刊,大佬总结的非常好 ...

  9. 【前端性能优化】浏览器渲染原理与性能优化

    目录 1. 浏览器渲染基本步骤 2. 构建DOM树.CSSOM树 3. 构建渲染树 4. 计算渲染树的布局 5. 将布局渲染到屏幕上 6. 渲染优化 1. 浏览器渲染基本步骤 浏览器主要有以下步骤: ...

最新文章

  1. Unity3d连接SQL Server数据库出现SocketException: 使用了与请求的协议不兼容的地址错误...
  2. 页面金额显示两位小数点问题
  3. [na][tools]快速ping网段工具-QuickPing
  4. session,cookie和token,以及负载均衡
  5. educoder 使用线程锁(lock)实现线程同步_线程间的通信(一)
  6. ActiveMQ性能测试
  7. Android File.listFiles()返回null问题
  8. 华为交换机telnet和ftp服务开启/关闭命令
  9. Hybrid A*论文解析(3)
  10. Android P (1)---开发指南
  11. VB 6.0使用api
  12. 学习Java,真的可以月薪过万嘛?真实个人经历告诉你,记录了平时学习的内容以及学习过程中最真实的感受(四)
  13. 把网络图片URL转化为流
  14. 区块链技术介绍PPT
  15. DS18B20调试总结
  16. 【PS功能学习】10:蒙版带你领略台前幕后的故事
  17. Ghost之远程终端管理
  18. 《论程序员与老板之间的道德问题》
  19. Spring缺少aspectjweaver.jar异常
  20. PC 时代 Office 的仇,WPS 在 24 年后有机会报了

热门文章

  1. senborn绘制混淆矩阵
  2. Graft货币(GRFT)结点搭建
  3. SentOS 7防火墙配置与端口增删改查的命令
  4. 单片机中如何将BCD码拆开_单片机bcd码转换
  5. php strncmp,PHP中strncmp()函数比较两个字符串前2个字符是否相等的方法
  6. Ping突然出现请求超时的问题
  7. 课后作业-阅读任务3
  8. [Logstash]使用详解
  9. 翻译:重载解决和Null
  10. 一加6手机突然没信号没服务器,如何从技术上解决手机信号问题?一加6替你想到了...