免责声明:本文主要为讽刺。我不认为我比你更优秀,因为我曾经写过一些TypeScript,也不认为让网页变得更大是一件好事。请随意曲解这些观点以最大化点击量。
你知道,有很多文章告诉你如何减小页面大小:优化图片,删除多余的CSS规则,使用框架集在Dreamweaver中重写整个页面。看,沃尔玛刚刚将其页面大小减少了一些数字,或多或少。
JavaScript 清理
🗑️ 删除旧的和重复的依赖项
🐥 将大型依赖项替换为小型依赖项
🧐 检查您是否过度填充
🧽 清理A/B测试配置
✂️ 代码分割!沃尔玛杂货店对其网站进行了此操作。JS包缩小了69%。互动时间缩短了28%。pic.twitter.com/3kSp7Ssi35
— Addy Osmani (@addyosmani) 2019年5月31日
我们缺少的是足够多的文章向您展示如何*增加*页面大小。事实上,我唯一能找到的文章是来自Geek Squad的这篇文章,结果是关于放大字体大小的。这是一个好的开始,但我认为我们可以做得更好。
增加一些重量
现在,你为什么要增加页面大小?对于低带宽连接的用户来说,这不是一件好事吗?好吧,有几个极好的且绝非牵强的理由,这里列举了三个,因为三个一组的东西更令人满意。
- 您拥有千兆位连接并且住在田纳西州,因此当然其他每个人都比您情况更好。
- 浏览器会进行缓存,这很愚蠢。这意味着您只需下载一次网站。别再抱怨了。这是第一世界的问题。
- 您不在乎是否有人访问您的网站,因为您,“工作是为了生活,而不是为了工作而生活”。
如果这些完全相关的理由中的任何一个引起您的共鸣,我想向您展示我是如何将我的CSS大小增加了1500%——您也可以做到,只需一个简单的webpack技巧。
一个奇怪的技巧
这一切都始于我决定将我的退休计划项目The Urlist重构到Bulma CSS框架。

该网站的原始版本都是手工编写的,我的Sass看起来像一集《囤积者》节目。
“Burke,你不需要13种不同的
.button
样式。为什么不选择一种并删除其他12种,这样你就有地方睡觉了?”
Bulma还包含诸如模态之类的功能,我使用第三方Vue组件来创建这些功能。

它还有一个汉堡菜单,因为众所周知,如果没有汉堡,网站就不可能成功。

听着,我并没有制定规则。这就是商业运作方式。

我对结果非常满意。Bulma样式很犀利,布局系统也很容易学习。就好像某个地方的人了解CSS并且也不讨厌我。如今,这两种情况很难同时出现。
经过几周的重构(在此期间我会问自己,“你在做什么?!网站已经可以工作了!”),我终于完成了。顺便说一句,下次你想重构某些东西时,不要这样做。放着它不管。如果你不为下一代留下任何技术债务,他们会非常无聊,这将归咎于你。
当我构建项目时,我注意到了一些奇怪的事情:我的CSS大小增加了相当多。我手工制作的怪物只有30KB(gzip压缩后),重构后增加到了260KB。

更糟糕的是,Vue CLI一直在教训我……

当然,我忽略了它。我不接受机器人的指令。
我所做的是部署它。到生产环境。在互联网上。因为我不会花费所有这些时间进行重构而不进行部署。是的,沉没成本等等,但如果我比你的逻辑谬误海报更务实,请原谅我。我只想说,我参加了派对,我不会在没有欢呼声的情况下回家。
然后我转到Twitter,向漠不关心的群众宣布我的成就。就像人们通常做的那样。
我将https://#/hgGmemoQeX重构到Bulma。整个页面看起来更简洁,样式也大大简化了。干得好,@jgthms。
唯一的缺点是,我的CSS现在变得很大。gzip压缩后约为260kb。之前约为30kb。值得权衡吗?pic.twitter.com/te2DTgknS1
— Burke Holland (@burkeholland) 2019年5月28日
此后不久,创建Bulma(并且显然喜欢龙珠)的Jeremy Thomas做出了回应。而且速度很快。好像每当一个白痴发推文时,就会发出一个蝙蝠信号。
不错!看起来您的CSS变大是因为有很多重复的样式。
例如,“.section.is-medium[data-v-”在CSS中出现了13次,但只需要出现一次。如果您搜索“.hero[data-v-”也是如此。
似乎您在每个组件中都命名空间了整个Bulma。— Jeremy Thomas (@jgthms) 2019年5月28日
重复的样式?13次?什么是命名空间?那是π符号还是Jeremy Thomas的自定义徽标?
就在那一刻,我意识到自己完全不知道自己在做什么。
放下Sass,慢慢后退
我首先承认自己对CSS不太了解,对Sass更是知之甚少。明白了吗?对Sass知之甚少?算了吧。我不想听到你的可怜的笑声。
当我设置我的Vue CLI项目以使用Bulma时,我创建了一个src/styles
文件夹并在其中放置了一个bulma-but-not-all-of-bulma-only-some-of-it.scss
文件。他们说命名很难,但我不知道为什么。
该文件导入我想使用的Bulma部分。它是Bulma,但不是全部。只是一部分。
@import "bulma/sass/utilities/_all.sass";
@import "bulma/sass/base/_all.sass";
@import "bulma/sass/form/shared.sass";
@import "bulma/sass/form/input-textarea.sass";
// etc...
然后我将该文件导入到一个自定义Sass文件中,我将其命名为……site.scss
。我喜欢保持简单。
@import "./bulma-but-not-all-of-bulma-only-some-of-it.scss";
html,
body {
background-color: #f9fafc;
}
// etc...
我想全局导入这些文件,以便可以在每个组件中使用它们。并且我想以正确的方式进行操作;规范的方式。我认为从我愿意将2+MB的CSS部署到生产环境中可以清楚地看出,我喜欢以“正确的方式”做事。
我阅读了Sarah Drasner撰写的这篇优秀的博文,名为“如何在Vue应用程序中的每个组件中导入Sass文件”。她展示了如何通过vue.config.js
文件修改webpack构建过程来实现此目的。
module.exports = {
css: {
loaderOptions: {
sass: {
data: `@import "@/styles/site.scss";`
}
}
}
}
我无法理解的是,这会将Sass导入到Vue应用程序中的每个组件中。你知道,**就像博客文章标题字面上所说的那样**。这也是我最终得到一堆带有data-v-
属性选择器的重复样式的原因。我要感谢作用域样式。
Vue如何处理`scoped`
Vue允许您将样式“作用域”到组件中。这意味着样式仅影响其所在的组件,而不是页面的其余部分。没有可以执行此操作的魔法浏览器API。Vue通过在元素和选择器中动态插入data-
属性来实现此目的。例如,以下内容
<template>
<button class="submit">Submit</button>
<template>
<style lang="scss" scoped>
.submit {
background-color: #20ae96;
}
</style>
…将变成以下内容
<button class="submit" data-v-2929>Submit</button>
<style>
.submit[data-v-2929] {
background-color: #20ae96;
}
</style>
该动态数据标签也会添加到组件中的每个子元素中。因此,此组件的每个元素和每个样式在运行时都将具有data-v-2929
。
如果您将包含实际样式的Sass文件导入到您的组件中,Vue(通过webpack)将提取这些样式并使用该动态data-
属性为其“命名空间”。结果是,如果您在应用程序中包含13次Bulma,并在其前面加上一堆data-v
怪异内容。
但这引发了一个问题:如果webpack在每个组件中呈现CSS,为什么要使用vue.config.js
方法?一句话:**变量**。
变量共享问题
你不能在一个组件中定义一个 Sass 变量,然后在另一个组件中引用它。这样做也很难管理,因为你将在各处定义和使用变量。只有我才会写这样的代码。
而你,另一方面,可能会将所有变量放在一个 variables.scss
文件中。然后,每个组件都会引用这个变量的中心存储库。在每个组件中都导入变量文件是多余的。它也过于繁琐。而且不必要。以及冗长。
这正是 Sarah 的文章要解决的问题:将 Sass 文件导入项目中的每个组件。
将像变量这样的东西导入到每个组件中是可以的,因为变量不会被渲染。如果你导入了 200 个变量,而只引用了其中一个,那又有什么关系呢?这些变量在渲染后的 CSS 中并不存在。
例如,这样
<style lang="scss" scoped>
$primary: #20ae96;
$secondary: #336699;
.submit {
background-color: $primary
}
</style>
…将变成以下内容
<style>
.submit[data-v-2929] {
background-color: #20ae96;
}
</style>
所以,这里实际上有两个问题
- Bulma 需要是全局的。
- Bulma 的变量应该可以从组件中访问。
我们需要巧妙地结合 Sarah 的技术,以及一些关于 Bulma 结构的专有知识。
在 Vue 中使用 Bulma
我们将通过在 src/styles
目录中创建三个文件来实现这一点,并尽可能减少重复。
variables.scss
:此文件将用于引入 Bulma 的变量并覆盖/定义你自己的变量。请注意,你必须包含以下三个文件才能获取 Bulma 的所有变量。并且它们必须按照此顺序排列……
// Your variables customizations go up here
// Include Bulma's variables
@import "bulma/sass/utilities/initial-variables.sass";
@import "bulma/sass/utilities/functions.sass";
@import "bulma/sass/utilities/derived-variables.sass";
bulma-custom.scss
:此文件用于引入你需要的 Bulma 部分。它应该引用 variables.scss
文件。
@import "./variables.scss";
/* UTILTIES */
@import "bulma/sass/utilities/animations.sass";
@import "bulma/sass/utilities/controls.sass";
@import "bulma/sass/utilities/mixins.sass";
// etc...
site.scss
:此文件引入 bulma-custom.scss
文件,并且也是你在整个项目中使用的全局样式的定义位置。
@import url("https://use.fontawesome.com/releases/v5.6.3/css/all.css");
@import "./bulma-custom.scss";
html,
body {
height: 100%;
background-color: #f9fafc;
}
// etc...
将 site.scss
文件导入你的 main.js
文件。或者在我的例子中,是 main.ts
。使用 TypeScript 能让我比你更优秀吗?是的。是的,的确如此。
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
// import styles
import "@/styles/site.scss";
这使得我们使用的所有 Bulma 部分都可以在每个组件中使用。它们是全局的,但只包含一次。
根据 Sarah 的文章,将 variables.scss
文件添加到 vue.config.js
文件中。
module.exports = {
css: {
loaderOptions: {
sass: {
data: `@import "@/styles/variables.scss";`
}
}
}
}
这样一来,你就可以从任何 .vue
组件中引用任何 Bulma 变量或你自己的变量。
现在,你拥有了两个世界中最好的:Bulma 可全局使用,并且你仍然可以在每个组件中访问所有 Bulma 变量。
现在 CSS 的总大小?大约缩小了 1,500%……

去你的,沃尔玛。
通过 PR 赎回
为了赎回我自己,我向 Bulma 文档提交了一个 PR,其中介绍了如何在 Vue CLI 项目中自定义 Bulma。这是我对在 Twitter 上发言并使 Bulma 看起来像是问题(而实际上 Burke 才是问题)的一种悔过行为。
你会认为到目前为止我已经弄清楚了:Burke 永远是问题所在。
我还没有在生产环境中使用 Vue 或 Bulma,但我喜欢这篇文章展示了对应用程序进行清单并尽力而为的需求。幽默也是一个不错的补充!干得好!
谢谢,Jacob!
如果你有机会使用 Bulma,我强烈推荐它。对于那些看起来不像由开发者设计的网站来说,它是我的首选。
我也喜欢 Bulma。只是一个简洁的类名结构,对我来说很有意义。
@import 的性能不是很好。
你应该坚持使用 link 标签,我的朋友。
这篇文章写得非常好。幽默和信息完美平衡。在接下来的五年里,我将反复查看这篇文章,同时鼓起勇气自己写点东西,并希望发生一些渗透现象。
尼古拉斯·凯奇的声音 *
那是很高的赞誉
如果这有帮助的话,我想这可能是我写的第 1000 篇文章了。所以……也许写作的秘诀就是“一直写,直到写出不糟糕的东西”。
最后一段是我自己的声音,只是澄清一下。
太棒了,读完这篇文章后,我确实去搜索了你的一些其他作品,我真的很喜欢(并且从中学习?!)你的风格。你关于三元运算符的文章很有趣,很有道理,并且不久之后我找到了一个很好的使用它们的实例。
有趣且写得非常好的文章。谢谢!
这是一个很好的例子,说明理解我们使用的第三方工具到底在做什么以及如何充分利用它们是多么重要。
哈哈,一个正在学习并犯错的探索者。很高兴我不是唯一一个。好文章,我学习了一些东西,但可能在我需要的时候就忘记了……:)
我和你一样。有时我会搜索一个问题,然后找到我自己的文章。但大多数时候我找到的是 StackOverflow。从好的方面来说,我的复制粘贴技能确实很厉害。
精彩的文章!谢谢!
谢谢 - 阅读起来非常愉快,很有趣。
写得不错的文章,读起来很享受,不禁想知道……Bulma 是什么?看起来也很有趣,直到你在首页上看到推荐的实践方式
$grey-dark: $brown;
也许凭借你的专业技能,你可以帮助他们用稍微不那么糟糕的方式命名它 :)
我的确拥有不可思议的命名技能。还有双节棍技能和计算机黑客技能。
如果你/当你在使用 SSR Vue(Nuxt)时,你可能还想查看“style resources”Nuxt 模块。允许你声明在任何模块中使用的 SCSS 文件。特别警告只包含变量/混合。
我笑得好开心!谢谢
非常好的文章。这正是我们面临的问题。
除了变量之外,还有其他在导入期间使用的实用程序。
例如,使用一些全局类的 @extend。
关于如何处理这些问题,有什么想法吗?