网站首页 > 技术文章 正文
作者: 山月行
转发链接:https://mp.weixin.qq.com/s/aPVVtoUGFYVYsOIIg2Fhlw
前言
随着前端的发展,特别是 React,Vue 等构造产业应用的兴起,前端的能力得以很大提升,随之而来的是项目的复杂度越来越大。此时的前端的静态资源也越来越庞大,而毫无疑问 javascript 资源也是前端的主体资源,对于压缩它的体积至为重要。
为什么说更小的体积很重要呢:更小的体积对于用户体验来说意味着更快的加载速度以及更好的用户体验,这也能造就企业更大的利润。另外,更小的体积对于服务器来说也意味更小的带宽以及更少的服务器费用。
前端构建编译代码时,可以使用 webpack 中的 optimization.minimizer 来对代码进行压缩优化。但是我们也需要了解如何它是压缩代码的,这样当在生产环境的控制台调试代码时对它也有更深刻的理解。
如何查看资源的体积
对于我们所编写的代码,它在操作系统中是一个文件,根据文件系统中的 stat 信息我们可以查看该文件的大小。
stat 命令用来打印文件系统的信息:
$ stat config.js
File: ‘config.js’
Size: 3663 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 806060 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-02-13 13:43:54.851381702 +0800
Modify: 2020-02-13 13:43:52.668417641 +0800
Change: 2020-02-13 13:43:52.691417262 +0800
Birth: -
stat 打印的信息过大,如果只用来衡量体积,可以使用 wc -c
$ wc -c config.js
3663 config.js
如何压缩代码体积?
去除多余字符: 空格,换行及注释
// 对两个数求和
function sum (a, b) {
return a + b;
}
先把一个抽象的问题给具体化,如果是以上一段代码,那如何压缩它的体积呢:
此时文件大小是 62 Byte, 一般来说中文会占用更大的空间。
多余的空白字符会占用大量的体积,如空格,换行符,另外注释也会占用文件体积。当我们把所有的空白符合注释都去掉之后,代码体积会得到减少。
去掉多余字符之后,文件大小已经变为 30 Byte。 压缩后代码如下:
function sum(a,b){return a+b}
替换掉多余字符后会有什么问题产生呢?
有,比如多行代码压缩到一行时要注意行尾分号。 这就需要通过以下介绍的 AST 来解决。
压缩变量名:变量名,函数名及属性名
function sum (first, second) {
return first + second;
}
如以上 first 与 second 在函数的作用域中,在作用域外不会引用它,此时可以让它们的变量名称更短。但是如果这是一个 module 中,sum 这个函数也不会被导出呢?那可以把这个函数名也缩短。
// 压缩: 缩短变量名
function sum (x, y) {
return x + y;
}
// 再压缩: 去除空余字符
function s(x,y){return a+b}
在这个示例中,当完成代码压缩 (compress) 时,代码的混淆 (mangle) 也捎带完成。但此时缩短变量的命名也需要 AST 支持,不至于在作用域中造成命名冲突。
更简单的表达:合并声明以及布尔值简化
合并声明的示例如下:
// 压缩前
const a = 3;
const b = 4;
// 压缩后
const a = 3, b = 4;
布尔值简化的示例如下:
// 压缩前
!b && !c && !d && !e
// 压缩后
b||c||d||e
这个示例更是需要解析 AST 了
AST
AST,抽象语法树,js 代码解析后的最小词法单元,而这个过程就是通过 Parser 来完成的。
那么 AST 可以做什么呢?
- eslint: 校验你的代码风格
- babel: 编译代码到 ES 低版本
- taro/mpvue: 各种可以多端运行的小程序框架
- GraphQL: 解析客户端查询
我们在日常工作中经常会不经意间与它打交道,如 eslint 与 babel,都会涉及到 js 与代码中游走。不同的解析器会生成不同的 AST,司空见惯的是 babel 使用的解析器 babylon,而uglify 在代码压缩中使用到的解析器是 UglifyJS。
你可以在 AST Explorer[3] 中直观感受到,如下图:
那压缩代码的过程:code -> AST -> (transform)一颗更小的 AST -> code,这与 babel 和 eslint 的流程一模一样。
UglifyJS
不要重复造轮子!
于是我找了一个久负盛名的关于代码压缩的库: UglifyJS3[4],一个用于代码压缩混淆的库。那它是如何完成一些压缩功能的,比如替换空白符,答案是 AST。
webpack 中内置的代码压缩插件就是使用了它,它的工作流程大致如下:
// 原始代码
const code = `const a = 3;`
// 通过 UglifyJS 把代码解析为 AST
const ast = UglifyJS.parse(code);
ast.figure_out_scope();
// 转化为一颗更小的 AST 树
compressor = UglifyJS.Compressor();
ast = ast.transform(compressor);
// 再把 AST 转化为代码
code = ast.print_to_string();
而当你真正使用它来压缩代码时,你只需要面向配置编程即可,文档参考 uglify 官方文档[5]
{
{
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
comparisons: false,
inline: 2,
},
output: {
ecma: 5,
comments: false,
ascii_only: true,
}
}
在 webpack 中压缩代码
在知道代码压缩是怎么完成的之后,我们终于可以把它搬到生产环境中去压缩代码。终于到了实践的时候了,虽然它只是简单的调用 API 并且调调参数。
一切与性能优化相关的都可以在 optimization 中找到,TerserPlugin 是一个底层基于 uglifyjs 的用来压缩 JS 的插件。
optimization: {
minimize: isEnvProduction,
minimizer: [
new TerserPlugin({
terserOptions: {
parse: {
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
comparisons: false,
inline: 2,
},
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
},
sourceMap: true
})
]
}
推荐JavaScript经典实例学习资料文章
《前端开发规范:命名规范、html规范、css规范、js规范》
《100个原生JavaScript代码片段知识点详细汇总【实践】》
《手把手教你深入巩固JavaScript知识体系【思维导图】》
《一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧》
《身份证号码的正则表达式及验证详解(JavaScript,Regex)》
《127个常用的JS代码片段,每段代码花30秒就能看懂-【上】》
《深入浅出讲解JS中this/apply/call/bind巧妙用法【实践】》
《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》
《面试中教你绕过关于 JavaScript 作用域的 5 个坑》
作者: 山月行
转发链接:https://mp.weixin.qq.com/s/aPVVtoUGFYVYsOIIg2Fhlw
猜你喜欢
- 2025-05-28 想高效办公畅饮下午茶?这些显示器你肯定需要
- 2025-05-28 这样优化项目, 让公司的网站直接秒开,老板说给我加奖金
- 2025-05-28 我做了个 AI 神器,模糊图片变清晰,4倍无损放大,极简且好用
- 2025-05-28 「前端纯干货」原来TinyPNG可以这样玩
- 2025-05-28 前端面试-Web Worker:让你的网页不再“卡到崩溃”的秘诀
- 2025-05-28 Tinypng - 比ps更厉害的免费图片压缩神器
- 2025-05-28 深入JavaScript教你内存泄漏如何防范
- 2025-05-28 推荐三款正则可视化工具「JS篇」
- 2025-05-28 从零到一:小程序设计新手如何快速上手?
- 2025-05-28 PHP(gzdeflate/gzinflate)+JS(pako)前后端数据压缩
你 发表评论:
欢迎- 05-30为什么说网上的md5加密解密站都是通过彩虹表解密的?
- 05-30一文读懂md5,md5有什么用,什么是md5加盐
- 05-30Java md5加密解密数据
- 05-30MD5是什么?如何进行MD5校验?
- 05-30专家教你简单又轻松的MD5解密方法,一看就会
- 05-30多学习才能多赚钱之:vscode怎么安装插件
- 05-30VSCode无限画布模式(可能会惊艳到你的一个小功能)
- 05-30VSCode神级Ai插件Cline:从安装到实战【创建微信小程序扫雷】
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)