兔大妈:
「百货公司在跳楼...大!拍!卖!!!(口水)」
「赶快来去抢!!!」
(兔大妈掏出了小卡进行一番热血的战斗)
兔大妈:
「哇,害啊,买太多提不回家了...」
「打电话叫鹅籽来帮我提好了」
(十分钟後...)
兔鹅籽:
「吼! 妈 啊你买那麽多东西,最後还不是放到过期!」
「买有需要的就好了啦~趁现在才刚买,还能退货」
「我们,该来帮这购物袋大减肥了!」
今天一样还是要用到我们之前在本地端安装的 Tailwind 专案。
不过今天的生产环境优化的操作是无法在 Playground 中完成
的。
因为 Playground 就是让你操作新功能,以及示范、还有发问时用的,而不是用来完成你专案中实际使用的项目。
如果你的购物袋还是空的,在这里把它装满:专案范本
(这专案的内容与 Day 14 完成後的内容相同)
可以齁,要开始退货罗!
因为啊,Tailwind 编译出来的 css 档实在太大太大了! 这如果在正式环境上线的话,每次浏览一来一回造成的流量不小,而且正因为 css 档太大,所以也会拖垮了整个页面载入的速度。
如果你去仔细观察,不难发现编译完的 style.css ...
对,就是这麽胖这麽肥,高达 4 MB
!
这个在正式环境上使用的浏览速度 ...
嗯 ... 真的慢的很可怕。
所以我们要来了解一下 Tailwind 原本的设计意图
。
Tailwind 起初的设计概念就是在开发阶段提供完整
的所有可用的 class,让你开发方便不需一直重新编译。
然後到了要正式上线前,再透过 Tree-Shake
把未用到的样式移除。
所谓 Tree-Shake 的概念就是去用力的摇晃一棵树使其震动,而这时候会因为树的摇晃而飘落下来的树叶就是已经没有生命力、原本就该掉的树叶。
你可以把 Tailwind 想像成一大箱乐高,将其倾倒至地上後取出需要的部分来组合,完成後再将没有用到的积木通通放回去箱子里。
如此一来就可以完全理解一开始档案这麽大的目的了。
接着我们来实际的操作一遍!
一开始的配置档 tailwind.config.js
中,我们可以看到 purge 的设定是空的:
module.exports = {
purge: [],
...
}
这个 purge 的阵列之中,要加上我们想要检查的档案,那麽在 Tailwind 编译时,就会去检查档案之中所用到的 class。
而目前我们也只有 index.html 一个页面,所以我们可以这麽做就好:
module.exports = {
purge: ["./index.html"],
...
}
但为了以防我们之後会有其他的页面
或资料夹,也可以选择这样设定。
module.exports = {
purge: [
"./*.html",
"./**/*.html",
],
...
}
如果你会在 js 中使用到 Tailwind 的 class,那也请把 js 加入 purge 的监听列表。 我们可以一次设定多个
副档名:
module.exports = {
purge: [
"./*.{html,js}",
"./**/*.{html,js}",
],
...
}
其实应该
根据专案结构
做细部的设定,但这边不多加赘述;但不论是怎麽样的结构,要给 purge 选项监听的路径格式都应该要符合规范
。
既然有设定 purge 要清除的档案范围,我们就来重新编译试试看效果吧! 一样是这行执行过很多次的指令:
npm run build
编译完後会发现,大小根本完全都没有改变
!
「兔兔!哩喜咧装肖维吗!」
没事,不要着急,一切都在我的掌控之中。 ?
我们刚刚也说过,
这是原本就是预计在正式环境
上线才会使用的。
所以啊~现在没有任何反应是正常的!
因为现在专案本身的环境还不是 production
呀,
所以若是把专案的 NODE_ENV 设定为 production,
在编译 Tailwind 时,purge 选项就会自动生效
罗!
不过我们这边不设定 NODE_ENV,我们来改用别的方式达成。
purge 选项要生效,不仅可以透过专案的环境状态来选择是否要 Tree-Shake,也能够设定手动开启。
我们把 purge 选项改成这个样子:
module.exports = {
purge: {
enabled: true, // true: 开启 / false: 关闭
content: [
"./*.{html,js}",
"./**/*.{html,js}",
]
},
...
}
这麽一来,我们在编译时,purge 若是设定为开启,就会进行 Tree-Shake。
我们再来重新编译一次试试看。
npm run build
编译完之後 ... 档案大小 降到 33KB
了,
而实际上速度也会比编译完整档案再更快一些。
「杰克!」
不对 ... 是 「兔兔!这真是太神奇了」
不过,兔兔其实想跟你们说声不好意思,因为啊上次专案结尾是新增了一个新的、套用 box 元件样式的方块,可是颜色都没有调整,所以我们就来对那个方块做细部设定吧!
让我们把场景快速切换到 index.html
,来帮第三个方块新增颜色。依照前两个方块以此类推,把第三个方块设定为黄色的:
<div class="flex justify-evenly p-10 focus-within:bg-green-100 group">
<box class="box bg-red-500 hover:bg-red-400 ring-red-300" tabindex="0">
1
</box>
<box class="box bg-blue-500 hover:bg-blue-400 ring-blue-300" tabindex="1">
2
</box>
<box class="box bg-yellow-500 hover:bg-yellow-400 ring-yellow-300" tabindex="2">
3
</box>
</div>
有规范过的 class 样式改起来就是如此的轻松简单,
我们来看看画面吧:
「... 兔兔 ...!又是你的锅吗!?」
ㄟ,这你可就误会大罗!
枉费我用心良苦铺陈到这里,哼哼~~
为什麽样式没有上去呢?
因为我们在编译前没有用到这个颜色,所以被移除了呀!
前面说过,Tailwind 一开始的设计理念就是样式全部编译,到了要上线时再减少样式,那当然你现在多写什麽,就没有什麽,因为你必须重新编译!
不过就可以趁机会提到这个有趣的设定。
如果你会需要在生产环境後临时改变颜色间距等等的样式,或是透过 js 动态改变主题颜色的话,接下来要讲的这个设定很适合哦!
看到名字就知道,顾名思义就是设定一个安全名单,让 Tailwind 在移除样式时略过他们,举例:
module.exports = {
purge: {
enabled: true, // true: 开启 / false: 关闭
content: [
"./*.{html,js}",
"./**/*.{html,js}",
],
safelist: [
'bg-blue-500',
'text-center',
'hover:opacity-100',
// ...
'lg:text-right',
]
},
...
}
但是这个方法需要把 class 一个一个定义清楚,如果想要一个范围或大量定义
的话,现在这个 safelist 的写法是不适合
的,我们必须要使用正规表达式来完成。
若把 safelist 直接写在 purge 之中,那麽 safelist 里面只接受字串格式,不接受你在里面写 regex。 如果想要用 regex 必须将 safelist 写在 purge 的 options 参数中。
依照我们的设定,我们希望它之後即使不重新编译仍然也可以临时改变颜色,而我们有用到的颜色种类是背景颜色 bg-*
和外框颜色 ring-*
,所以我们的正规表达式必须包含这两种:
/(bg|ring)-(.*)-(\d{1}0{1,2})/
准备好 Regex,我们就可以把它加到设定中:
module.exports = {
purge: {
enabled: true, // true: 开启 / false: 关闭
content: [
"./*.{html,js}",
"./**/*.{html,js}",
],
options: {
safelist: [/(bg|ring)-(.*)-(\d{1}0{1,2})/]
}
},
...
}
接着再重新编译 ... 编译完马上来看结果
npm run build
现在变成黄色了,那我们不要编译,直接改成绿色呢?
<div class="flex justify-evenly p-10 focus-within:bg-green-100 group">
<box class="box bg-red-500 hover:bg-red-400 ring-red-300" tabindex="0">
1
</box>
<box class="box bg-blue-500 hover:bg-blue-400 ring-blue-300" tabindex="1">
2
</box>
<box class="box bg-green-500 hover:bg-green-400 ring-green-300" tabindex="2">
3
</box>
</div>
直接储存後马上看结果:
OK 的,生效了! 所以未来你也可以透过类似的手法,让特定类别的 class 就算未使用也不要被清除掉。
那这次就是真的完成罗~
这个作业 应该 不会再用到了吧?
兔鹅籽:
「妈~货都退完了」
兔大妈:
「货退完了齁,真的变很小袋馁。」
「啊我看一下还剩什麽...」(翻袋子)
「这个不是说也要退掉,怎麽没退到?」
兔鹅籽:
「哦,爸说那种的都可以留着啦,因为那是消耗品」
兔大妈:
「齁 ... 是这样子喔,好啦那我们可以回家了齁」
兔鹅籽:
「对,可以了。妈我车停那边,我们过去那里」
(渐行渐远)
(兔大妈:「怎麽觉得还是很重馁 ...」)
关於兔兔们:
( # 兔兔小声说 )
兔兔有一天捡到一个神灯 ...
神灯:
「有智慧的兔子啊! 给你实现一个愿望的机会!」
「许愿吧!」兔兔:
「神灯啊神灯!」
「希望我死前,能找到适合自己的红萝卜!」
於是兔兔就获得了永生。
<<: Day 3 | Dart 基本介绍 - Dart vs JS
分散资料库(Distributed Database, DDB) VS 集中式资料库(Central...
您可能会因为错误的点击而意外删除重要的短信,或者在恢复出厂设置、系统崩溃、Android 更新、ro...
前言 今天来学元素的 classList,一口一口吃饼乾 yummy yummy! Codepen ...
DevOps是近几年很热门的关键字和技术,微软在这个部份自然也不会缺席,只是过往的产品名称并不是叫「...
那个 W 开头的 你是不是看我书读得少,想随便拿一串英文符号呼隆我? 这误会可不是普通的小啊!必须...