位置:石家庄网页制作 > 新闻中心 > seo知识 >

石家庄制作网站知识
2020-12-12 展为网络
处理Sass中未使用的CSS以提高性能
23分钟阅读
CSS, 浏览器, 性能
在Twitter或 LinkedIn上分享
保存以供离线阅读
有了Smashing Newsletter,总感觉像家一样。 一只猫,拖鞋读新闻通讯。
粉碎通讯
每周,我们都会发布有用的前端和UX技术。订阅并将Smart Interface Design Checklists PDF发送到收件箱。

您的(粉碎)电子邮件
订阅→ 
立即创建您的网站
立即创建您的网站
不再向CSV发送电子邮件
不再向CSV发送电子邮件
您知道未使用的CSS对性能的影响吗?剧透:很多!在本文中,我们将探索一种面向Sass的解决方案,用于处理未使用的CSS,从而避免了涉及无头浏览器和DOM仿真的复杂Node.js依赖关系。
在现代的前端开发中,开发人员应致力于编写可扩展和可维护的CSS。否则,随着代码库的增长和更多开发人员的贡献,他们冒着失去对特定细节(如级联和选择器特殊性)的控制的风险。

实现此目标的一种方法是使用面向对象CSS(OOCSS)之类的方法,该方法不是围绕页面上下文组织CSS,而是鼓励将结构(网格系统,间距,宽度等)与装饰(字体,品牌,颜色等)。

因此CSS类名称如下:

.blog-right-column
.latest_topics_list
.job-vacancy-ad
被更可重用的替代品替代,这些替代品应用相同的CSS样式,但不依赖于任何特定的上下文:

.col-md-4
.list-group
.card
通常在诸如Bootstrap,Foundation之类的Sass框架的帮助下实现此方法,或者越来越多地使用定制框架,该框架的形状可以更好地适合项目。

网站制作表单是每个有意义的交互的中心,因此值得牢记处理。认识Adam Silver的Form Design Patterns,这是设计和构建网站制作表单的实用指南。

跳转到目录↬
功能面板
因此,现在我们使用从模式,UI组件和实用程序类框架中精选的CSS类。下面的示例说明了使用Bootstrap构建的常见网格系统,该系统垂直堆叠,然后在到达md断点时切换到3列布局。

<div class="container">
   <div class="row">
      <div class="col-12 col-md-4">Column 1</div>
      <div class="col-12 col-md-4">Column 2</div>
      <div class="col-12 col-md-4">Column 3</div>
   </div>
</div>
复制
以编程方式生成的类(例如.col-12和).col-md-4在此处用于创建此模式。但是,我们.col-1通过.col-11,.col-lg-4,.col-md-6或.col-sm-12?这些都是所有类的示例,这些类将包含在已编译的CSS样式表中,并由浏览器下载和解析,即使它们没有使用。

在本文中,我们将从探讨未使用的CSS对页面加载速度的影响开始。然后,我们将介绍一些现有的解决方案,以将其从样式表中删除,然后再执行我自己的面向Sass的解决方案。

评估未使用的CSS类的影响
当我崇拜强大的刀片Sheffield United时,他们网站的CSS捆绑成一个568kb的缩小文件,即使压缩后也达到105kb。好像很多。


这是谢菲尔德联队的网站,是我当地的足球队(在殖民地,足球就是您的over)。(大型预览)
我们可以在他们的首页上看到多少CSS实际被使用吗?Google的快速搜索显示了可以完成工作的大量在线工具,但是我更喜欢使用Chrome中的coverage工具,该工具可以直接从Chrome的DevTools中运行。让我们旋转一下。


在开发人员工具中访问覆盖率工具的更快方法是使用键盘快捷键Control + Shift + P或Command + Shift + P(Mac)打开命令菜单。在其中输入coverage,然后选择“显示覆盖率”选项。(大型预览)
结果表明,该网页仅使用568kb样式表中的30kb CSS,其余538kb与网站其余部分所需的样式有关。这意味着高达94.8%的CSS未使用。


您可以在开发人员工具中通过网络->单击资产->“时间”标签在Chrome浏览器中查看任何资产的类似时间。(大型预览)
CSS是网页关键渲染路径的一部分,CSS涉及浏览器在开始页面渲染之前必须完成的所有不同步骤。这使CSS成为阻止渲染的资产。

因此,考虑到这一点,当使用良好的3G连接加载Sheffield United的网站时,下载CSS并开始页面渲染需要花费整个1.15秒的时间。这是个问题。

Google也已经意识到这一点。在线或通过浏览器运行Lighthouse审核时,突出显示了通过删除未使用的CSS可以节省的潜在加载时间和文件大小。


在Chrome(和Chromium Edge)中,您可以通过单击开发人员工具中的“审核”标签来对Google Lighthouse审核进行审核。(大型预览)
现有解决方案
目的是确定不需要哪些CSS类,并将其从样式表中删除。现有的解决方案可以尝试自动执行此过程。通常可以通过Node.js构建脚本或任务运行器(例如Gulp)使用它们。这些包括:

联合国CSS
净化CSS
清除CSS
这些通常以类似的方式工作:

:在bulld,该网站是通过模拟浏览器(如访问的木偶或DOM仿真(如:)jsdom)。
根据页面的HTML元素,可以识别任何未使用的CSS。
这将从样式表中删除,仅保留所需的内容。
尽管这些自动化工具非常有效,并且我已经在许多商业项目中成功使用了其中的许多工具,但是在此过程中我遇到了一些值得分享的缺点:

如果类名包含特殊字符,例如'@'或'/',则在不编写一些自定义代码的情况下可能无法识别它们。我使用的是Harry Roberts的BEM-IT,它涉及使用响应后缀(如:)来构造类名u-width-6/12@lg,因此我以前遇到过这个问题。
如果网站使用自动部署,则可能会减慢构建过程,尤其是在您有大量页面和CSS的情况下。
需要在团队之间共享有关这些工具的知识,否则当生产样式表中神秘地缺少CSS时,可能会感到困惑和沮丧。
如果您的网站上运行着许多第三方脚本,有时在无头浏览器中打开它们,它们将无法很好地发挥作用,并且会导致过滤过程出错。因此,通常,当检测到无头浏览器时,您必须编写自定义代码以排除任何第三方脚本,这取决于您的设置,可能会很棘手。
通常,这些工具很复杂,并且在构建过程中引入了很多额外的依赖关系。与所有第三方依赖关系一样,这意味着依赖于其他人的代码。
考虑到这些要点,我向自己提出了一个问题:

仅使用Sass,是否可以更好地处理我们编译的Sass,以便可以排除任何未使用的CSS,而无需完全删除Sass中的源类?
剧透警报: 答案是肯定的。这是我想出的。

Shopify合作伙伴
赚取设计和开发电子商务商店的经常性收入
立即注册
面向Sass的解决方案
该解决方案需要提供一种快速简便的方法来挑选Sass应该编译的内容,同时又要足够简单以至于不会给开发过程增加任何复杂性或阻止开发人员利用以编程方式生成CSS之类的东西。类。

首先,有一个包含构建脚本的仓库和一些示例样式,您可以从此处克隆它们。

提示:如果遇到困难,可以随时在master分支上与完整版本进行交叉引用。

cd进入仓库,运行npm install,然后npm run build根据需要将任何Sass编译为CSS。这应该在dist目录中创建一个55kb的CSS文件。

如果然后/dist/index.html在网站制作浏览器中打开,则应该看到一个相当标准的组件,单击该组件会展开以显示一些内容。您也可以在此处查看,此处将应用实际的网络条件,因此您可以运行自己的测试。


在开发面向Sass的解决方案以处理未使用的CSS时,我们将使用此扩展器UI组件作为测试主题。(大型预览)
在部分级别过滤
在一个典型的SCSS设置,你可能将有一个清单文件(例如:main.scss在回购),或每一个页面(如:index.scss,products.scss,contact.scss),其中框架的谐音是进口的。遵循OOCSS原则,这些导入可能看起来像这样:

例子1
/*
Undecorated design patterns
*/

@import 'objects/box';
@import 'objects/container';
@import 'objects/layout';

/*
UI components
*/

@import 'components/button';
@import 'components/expander';
@import 'components/typography';

/*
Highly specific helper classes
*/

@import 'utilities/alignments';
@import 'utilities/widths';
复制
如果未使用这些部分中的任何一个,则过滤此未使用的CSS的自然方法是仅禁用导入,这将阻止其被编译。

例如,如果仅使用扩展器组件,则清单通常如下所示:

例子2
/*
Undecorated design patterns
*/
// @import 'objects/box';
// @import 'objects/container';
// @import 'objects/layout';

/*
UI components
*/
// @import 'components/button';
@import 'components/expander';
// @import 'components/typography';

/*
Highly specific helper classes
*/
// @import 'utilities/alignments';
// @import 'utilities/widths';
复制
但是,根据OOCSS,我们将装饰与结构分离,以实现更大的可重用性,因此扩展器可能需要其他对象,组件或实用程序类的CSS才能正确呈现。除非开发人员通过检查HTML来了解这些关系,否则他们可能不知道导入这些部分,因此不会编译所有必需的类。

在仓库中,如果您在中查看扩展器的HTML dist/index.html,则可能是这种情况。它使用来自框和布局对象,版式组件以及宽度和对齐工具的样式。

dist/index.html
<div class="c-expander">
   <div class="o-box o-box--spacing-small c-expander__trigger c-expander__header" tabindex="0">
      <div class="o-layout o-layout--fit u-flex-middle">
         <div class="o-layout__item u-width-grow">
            <h2 class="c-type-echo">Toggle Expander</h2>
         </div>
         <div class="o-layout__item u-width-shrink">
            <div class="c-expander__header-icon"></div>
         </div>
      </div>
   </div>
   <div class="c-expander__content">
      <div class="o-box o-box--spacing-small">
       Lorum ipsum
         <p class="u-align-center">
            <button class="c-expander__trigger c-button">Close</button>
         </p>
      </div>
   </div>
</div>
复制
让我们通过在Sass本身内部使这些关系成为正式关系来解决这个等待发生的问题,因此,一旦导入了组件,任何依赖项也将自动导入。这样,开发人员不再具有审核HTML以了解他们还需要导入什么内容的额外开销。

程序化导入地图
为了使此依赖系统起作用,而不是简单地在@import清单文件中的语句中进行注释,Sass逻辑将需要指示是否编译部分文件。

在中src/scss/settings,在中创建一个名为的新部分_imports.scss,@import然后在其中settings/_core.scss创建以下SCSS映射:

src/scss/settings/_core.scss
@import 'breakpoints';
@import 'spacing';
@import 'imports';
复制
src/scss/settings/_imports.scss
$imports: (
   object: (
    'box',
    'container',
    'layout'
   ),
   component: (
    'button',
    'expander',
    'typography'
   ),
   utility: (
    'alignments',
    'widths'
   )
);
复制
该映射将具有与示例1中的导入清单相同的作用。

例子4
$imports: (
   object: (
    //'box',
    //'container',
    //'layout'
   ),
   component: (
    //'button',
    'expander',
    //'typography'
   ),
   utility: (
    //'alignments',
    //'widths'
   )
);
复制
它的行为应该像标准的@importswill那样,因为如果某些部分被注释掉(如上面的注释),则不应在构建时编译该代码。

但是,由于我们要自动导入依赖项,因此我们也应该能够在适当的情况下忽略此映射。

红帽-如果您的组织尚未进行数字化转型,那就必须这样做。
红帽
如果您的组织尚未进行数字化转型,则必须到现在为止。
从你所在的地方开始
渲染混合
让我们开始添加一些Sass逻辑。创建_render.scss的src/scss/tools,然后添加它@import来tools/_core.scss。

在文件中,创建一个名为的空mixin render()。

src/scss/tools/_render.scss
@mixin render() {

}
复制
返回列表

13933871212