前端文件打包优化

前端开发除了 HTML 模板外最重要的就是 JS/CSS 文件了,现今开发者都是本地书写 ES6/Stylus/Sass 然后经打包发布至 CDN 等环境,于此带来的问题是一些不需要的代码被打包了进来,甚至更严重的是一份代码被打包几遍。当然,Webpack 这样的工具出现就是为了解决这些问题,不过考虑到打包过程是一次性的编译,运行时代码的区别仍然需要开发者手动对待。

JavaScript

1. 重复打包了类库文件

backbone、underscore 被同时打包进了 vendor 和 setup 入口文件

上图中可以看到 vendor 和 setup 里都有 backbone、underscore 和 zepto 等库文件,这是为什么呢?

原因是当我们引入 splitChunksPlugin 时仅将 /node_modules/ 下的文件纳入 vendor 范围,但在 entry 处又定义了包含通过 bower 安装的 backbone、underscore 等类库的 vendor,见下面两图。

mobile config 中定义了 vendor

base config 中定义了 cacheGroup.vendor.test 为 /node_modules/

如图所示将 /public/js/lib 写入 optimization.splitChunks.cacheGroups.vendor.test 就可以了,结果如下图。

backbone、underscore 等库乖乖地呆在了 vendor 里面

2. 类库文件无法自动剔除无用代码

date-fnsRxJS 这样 battle tested 的库,从早期原型链(prototype)实现到现在拥抱函数式的历史进程中无可避免地引入了很多历史负担,比如下图中 date-fns/esm 就非常巨大,里面很多都是我们暂时不需要的功能。

date-fns/esm

好在它们文档都比较全:

如下图一顿修改。
import function from 'date-fns/function' directly

见证奇迹的时刻!
date-fns/esm mini

3. 运行时才能确认使用的重依赖模块

membership app 内出现了 jQuery 等依赖

一个 React App 内竟然出现了 jQuery 依赖 …… 一定是哪里出了问题,经过不懈的努力,终于找到了是在 web 和 mobile 公用的组件里用了微信支付的 module,而这个 module 开头就直接引入了 backbone/underscore/zepto 三大金刚 ……

weixin_wap_payment 依赖了 backbone 等库

Webpack 编译时并不能知道运行时究竟在不在手机环境,怎么办呢?我们可以通过 webpack require AMD 模式 来拆分代码。

AMD require weixin_wap_payment

其实这个打出来的 34 号包永远也不会被 import ……
jQuery/backbone/underscore 等都被打包出去了

CSS

1. 重复 CSS Variables 定义

开发小王接到了一个任务,改进项目 css 代码以支持当下新出的黑夜模式(Dare Mode),小王犯了愁,一个个颜色变量替换也太苦逼了,小王挠挠头想出了一个在 source 文件定义 CSS Variables 的方法。

duplicate CSS Variables

看起来非常完美,但不足之处是这堆 CSS Variables 每次 import 都会被定义一遍,结果就是有多少 stylus 文件就被重复定义了多少遍 …… 不要问我为什么要用 import 而不是 require ……

我们知道 Stylus 是一种 css 的预编译器,它的变量和 CSS Variables 是不一样的,CSS Variables 是会编译到生成的 CSS 文件里,而 Stylus 变量则会在编译中承担一次桥梁的作用之后悄悄消失。可以通过比对 Stylus 变量是否已经赋值 var(--css-variable) 来判断是否需要定义 CSS Variables。

is css variables defined?

成果就是从有多少 stylus 文件就有多少次 CSS Variables 定义缩减到入口文件那么多个数的定义,足足降低了一个数量级,打开 Chrome DevTools > Elements > Styles 终于不卡了!

注意观察右侧滚动条的宽度!

排序

算法中的排序算是老生常谈的问题了,不过我的问题是生活中真的有那么简单只需要按照一个值从小到大排列的需求吗?

如下图
web
在 App 端变成了这样
App

显然这些已注销用户是在不同时间关注的,web 上将他们混排了,App 上则是单列在最后,前一种强调了关注顺序,后一种强调了社交性(注销账号当然再也没有了社交价值)。并且 App 理论上不太会有用户真的去翻到最后一条,Elastic Search 默认最大条数是 10000,恐怕意义也是如此。

当然排序在程序上而言也就一行代码的区别,不过在产品上区别可是很大,是在从一个笔记本在向电话簿转变。

这一切是否预示着我们每个人之间的关系都是从路人成为朋友,然而最终将深埋通讯录底不见天日,直到天人永隔。

谁都只能陪谁走一段路,但这条路毕竟是要靠自己走完。

行色秋将晚,交情老更亲。

媒介即是信息

Twitter 决定了信息的载体只有 140 个字与 9 张图片,大部分人的思维方式也就停留在此,但抖音等短视频跳了出来,表示 15 秒钟的短视频能传递更准确的信息。