再谈 Retina 下 1px 的解决方案

2017/07/25 · CSS ·
1px

原文出处: 大漠   

在互联网上有关于1px边框的解决方案已经有很多种了,自从使用Flexible库之后,再也没有纠结有关于1px相关的问题。由于最近在考虑新的移动端适配方案,也就是放弃Flexible库,我不得不考虑重新处理1px的方案。为此为我自己也重撸了一些1px的解决方案,整理出来,希望对有需要的同学有帮助。

什么是关键 CSS

2017/10/05 · CSS ·
CSS

原文出处: Dean
Hume   译文出处:众成翻译   

网络速度很慢,但是有一些简单的策略可以使网站变快。其中之一就是将关键的css内联插入到网页的“标签,
但是,如果您的网站包含数百页,甚至更糟糕的是包含数百种不同的模板,那么你该怎么做呢?
你不能手动做这件事。 Dean
Hume解释了一个简单的方法来完成它。如果您是经验丰富的网页开发人员,您可能会发现这篇文章显而易见,并且不言而喻,但对于您的客户和初级开发人员来说,这是一个很好的选择。—
Ed.

提供快速,流畅的网络体验是如今构建网站的重要部分。
大多数情况下,我们开发网站,而不去理解浏览器实际在做什么。
浏览器是如何从我们创建的HTML,CSS和JavaScript渲染我们的网页?
我们如何使用这些知识来加速我们网页的渲染

有趣的CSS题目(17):不可思议的颜色混合模式 mix-blend-mode

2017/05/10 · CSS ·
CSS

本文作者: 伯乐在线 –
chokcoco
。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

CSS3 新增了一个很有意思的属性 — mix-blend-mode ,其中 mix 和 blend
的中文意译均为混合,那么这个属性的作用直译过来就是混合混合模式,当然,我们我们通常称之为混合模式

混合模式最常见于 photoshop 中,是 PS
中十分强大的功能之一。当然,瞎用乱用混合模式谁都会,利用混合模式将多个图层混合得到一个新的效果,只是要用到恰到好处,或者说在
CSS 中利用混合模式制作出一些效果则需要对混合模式很深的理解及不断的尝试。

我个人对混合模式的理解也十分浅显,本文只是带领大家走进 CSS
混合模式的世界,初浅的了解混合模式及尝试使用它制作一些效果。

Flexible方案

Flexible方案已不是什么神秘的方案了,借助JavaScript来动态修改meta标签中viewport中的initial-scale的值,然后根据dpr修改html中的font-size值,再使用rem来处理。有关于这方面的详细使用可以阅读早期整理的文章《使用Flexible实现手淘H5页面的终端适配》。

但是话说回来,这个方案目前只处理了iOS的dpr2的情况,其他的都没有处理,也就是说不支持Android和drp=3的情况。对于追求完美的同学来说,这是无法接受的。

有问题,总是有解决方案的,有同学做过方面的详细探索。那么跟着其思路也重新撸了一回。先回到Fleible中,其实现原理,大家都知道的。让viewport放大为device-widthdpr倍数,然后缩小1/dpr倍显示。

对于viewport的计算理论上是这样的:

viewportwidth没设置的话,默认是980px,这方面的详细介绍可以阅读《Configuring
the
Viewport》一文;但如果设置了initial-scaleviewport=device-width/scale;同时还设置了widthinitial-scale,则会取min-width,即应用这两个较小的值。详细的介绍可以阅读《Preliminary
meta viewport
research》一文。

接下来看看各种设备下的场景。首先使用JavaScript计算出scale的值:

var scale = 1 / window.devicePixelRation;

1
var scale = 1 / window.devicePixelRation;

head中的meta标签设备:

<meta name=”viewport”
content=”initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no”/>

1
  <meta name="viewport" content="initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no"/>

iPhone5viewportwidth=640px,得到的meta值:

<meta name=”viewport”
content=”initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no”/>

1
  <meta name="viewport" content="initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no"/>

符合我们预期所需的结果。

iPhone6 Plus也是完美的:

<meta name=”viewport”
content=”initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no”/>

1
  <meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no"/>

再来看几个Android的设备。比如米3,它的dpr=3viewportwidth=1080,得到的值也是我们期待的:

<meta name=”viewport”
content=”initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no”/>

1
  <meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no"/>

在米2中,它的dpr=2viewportwidth=720,效果也是OK的。

<meta name=”viewport”
content=”initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no”/>

1
  <meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no"/>

看到这里时,大家可能都会觉得完美,无需纠结啥,事实上在米2和米3中,看到的都是设置默认的浏览器、UC和Chrome浏览器的结果。回过头来再看WebView,那就出问题了。当Webview为360时,线依然也是粗的,这里测试,发现user-scalable=no会使viewport的值等于device-width。那么我们进一步去掉user-scalable=no或者设置user-scalable=yes

<meta name=”viewport”
content=”initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5″/>
<meta name=”viewport”
content=”initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333″/>

1
2
  <meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5"/>
  <meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333"/>

这样设置,在iOS、米3的Webview下都能得到预期效果,但是在米2中的Webview还是有问题,页面会被放大。问题是出在于米2的Webview的viewportwidth=490px,是由默认的980px缩放0.5后的值。而米2的device-width=360,所以就会出现撑开放不下的现象。

米2的Webview怎么办?
想起还有个被webkit在2013年3月抛弃的属性target-densitydpi=device-dpi,此属性是之前Android对viewport标签的扩展,arget-densitydpi的值有:
device-dpi, high-dpi, medium-dpi,
low-dpi四个。对于小米2的Webview才出现的问题估计只能非标准的属性来hack试试,densitydpi=device-dpi会让页面按照设备本身的dpi来渲染。

<meta name=”viewport”
content=”densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5″/>

1
  <meta name="viewport" content="densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5"/>

测试其他都正常,就小米2的Webview会出现有些边框偶尔出现若隐若现,原来是此时页面的viewport=980,densitydpi=device-dpi以设备真实的dpi显示后,scale的倍数变为360/980,这种情况压缩下去也许就这么残了~~

想办法让小米2的缩放比为小米的dprviewport如何能变为2*360=720呢,试试user-scalable=no重新加回去试试,终于,小米2的Webview下出现了纤细的线条。

<meta name=”viewport”
content=”densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no”/>

1
  <meta name="viewport" content="densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no"/>

测试了下对iPhone系列、三星系列、华为等主流机型的影响,正常!

别高兴的太早,在大天朝下,不仅仅有这些设备。还有VIVO之类的手机,他们的dpr=3,他们的viewport=980px,缩小为原来的1/3后,效果就不是我们所要的了。除此之外,还有一些设备,它的dpr很变态,比如VIVO的Android4.1.2,它的dpr=1.5,而其viewport也等于980,缩小为原来的1/1.5 = 2 / 3,宽度就变成了980 * 2 / 3 = 653.333,得到的效果也是无法直视的。当然还有一些我们所不知道的设备呢?这些可以通过Device
Metrics网站来查阅出设备相关的参数:

澳门微尼斯人手机版 1

这也是当初Fleible放弃治疗Android的原因。

但总的而言,其根本原因是一样的,viewport的默认宽度依然是980initial-scale等的设置无法改变viewport的基准计算。看来这些非主流机型上只能通过width来改变了。不出所料,设置如下即可

<meta name=”viewport”
content=”target-densitydpi=device-dpi,width=device-width,user-scalable=no”/>

1
  <meta name="viewport" content="target-densitydpi=device-dpi,width=device-width,user-scalable=no"/>

进一步测试发现绝大部分Android机器用下面的vieport设置也完全可以实现1px的真实效果。但是新webkit下已经移除了对target-densitydpi=device-dpi的支持。所以主流Android还是用标准的设置上述initscale=scale,因此最后的方案是主流的设备设置viewport

<meta name=”viewport”
content=”densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5″/>

1
  <meta name="viewport" content="densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5"/>

设置以上viewport还是无法改变默认980为宽度的viewport的非主流设备(如vivo,云os等),设置如下:

<meta name=”viewport”
content=”target-densitydpi=device-dpi,width=device-width,user-scalable=no”/>

1
  <meta name="viewport" content="target-densitydpi=device-dpi,width=device-width,user-scalable=no"/>

因此,最后的实现代码如下:

metaEl.setAttribute(‘content’,
‘target-densitydpi=device-dpi,user-scalable=no,initial-scale=’ + scale +
‘,maximum-scale=’ + scale + ‘, minimum-scale=’ + scale);
//不通过加入具体设备的白名单,通过此特征检测 docEl.clientWidth == 980
//initial-scale=1不能省,因为上面设置为其他的scale了,需要重置回来
if(docEl.clientWidth == 980) { metaEl.setAttribute(‘content’,
‘target-densitydpi=device-dpi,width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1’);
}

1
2
3
4
5
6
metaEl.setAttribute(‘content’, ‘target-densitydpi=device-dpi,user-scalable=no,initial-scale=’ + scale + ‘,maximum-scale=’ + scale + ‘, minimum-scale=’ + scale);
//不通过加入具体设备的白名单,通过此特征检测 docEl.clientWidth == 980
//initial-scale=1不能省,因为上面设置为其他的scale了,需要重置回来
if(docEl.clientWidth == 980) {
    metaEl.setAttribute(‘content’, ‘target-densitydpi=device-dpi,width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1’);
}

压缩的代码可以点击这里下载。这个也可以说是Flexible的升级版本吧(另外感兴趣的可以看看npm上的postcss-adaptive)。但也不是我所需要的方案,我的最终方案是放弃Flexible。

如果你对上面的方案不是很满意,你可以根据这篇文章《Mobile Web: Logical
Pixel vs Physical
Pixel》提供的解决方案,整理出适合自己的方案。原理和前面介绍的一样。

iPhone系列的viewport

<meta name=”viewport” content=”width=device-width initial-scale=0.5
maximum-scale=0.5 user-scalable=no”/>

1
  <meta name="viewport" content="width=device-width initial-scale=0.5 maximum-scale=0.5 user-scalable=no"/>

Android系列的viewport:

<meta name=”viewport” content=”width=device-width
target-densityDpi=device-dpi initial-scale=0.5 maximum-scale=0.5
user-scalable=no”/>

1
  <meta name="viewport" content="width=device-width target-densityDpi=device-dpi initial-scale=0.5 maximum-scale=0.5 user-scalable=no"/>

同样为了达到上述的需求,通过JavaScript来处理:

if (window.devicePixelRatio === 1) { if (window.innerWidth === 2 *
screen.width || window.innerWidth === 2 * screen.height) { el =
document.getElementById(‘viewport’); el.setAttribute(‘content’,
‘width=device-width target-densityDpi=device-dpi ‘ + ‘initial-scale=1
maximum-scale=1 user-scalable=no’); document.head.appendChild(el); width
= window.innerWidth; height = window.innerHeight; if (width === 2 *
screen.width) { width /= 2; height /= 2; } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (window.devicePixelRatio === 1) {
    if (window.innerWidth === 2 * screen.width ||
        window.innerWidth === 2 * screen.height) {
        el = document.getElementById(‘viewport’);
        el.setAttribute(‘content’, ‘width=device-width target-densityDpi=device-dpi ‘ +
            ‘initial-scale=1 maximum-scale=1 user-scalable=no’);
        document.head.appendChild(el);
        width = window.innerWidth;
        height = window.innerHeight;
        if (width === 2 * screen.width) {
            width /= 2;
            height /= 2;
        }
    }
}

是不是感觉他们非常类似。感兴趣不仿试试。

在 SmashingMag阅读更多:

  • 改善粉碎杂志的表现:案例研究
  • PostCSS介绍
  • 预加载,有什么好处?
  • 前端性能检查表

如果我想快速提高网站的性能, Google的 PageSpeed
Insights
工具是我的首选。 当尝试检测网页并找到需要改进的区域时,这非常有用。
您只需输入要测试的页面的URL,该工具就会提供一系列性能建议。

如果您曾经通过PageSpeed
Insights工具运行自己的网站,您可能会遇到以下建议。

澳门微尼斯人手机版 2

CSS and JavaScript 会阻塞页面的渲染。
(查看大图)

我必须承认,我第一次看到这个时有点困惑。 该建议的内容如下:

“如果以下资源未下载完成,您的页面上的任何内容都不会被渲染。
尝试延迟或异步加载阻塞资源,或直接在HTML中内联嵌入这些资源的关键部分。“

幸运的是,解决这个问题比看起来更简单!
答案在于CSS和JavaScript在您的网页中的加载方式。

mix-blend-mode 概述

上文也说了,mix-blend-mode 描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合。我们将
PS 中图层的概念替换为 HTML 中的元素。

看看可取的值有哪些:

JavaScript

{ mix-blend-mode: normal; // 正常 mix-blend-mode: multiply; // 正片叠底
mix-blend-mode: screen; // 滤色 mix-blend-mode: overlay; // 叠加
mix-blend-mode: darken; // 变暗 mix-blend-mode: lighten; // 变亮
mix-blend-mode: color-dodge; // 颜色减淡 mix-blend-mode: color-burn; //
颜色加深 mix-blend-mode: hard-light; // 强光 mix-blend-mode: soft-light;
// 柔光 mix-blend-mode: difference; // 差值 mix-blend-mode: exclusion;
// 排除 mix-blend-mode: hue; // 色相 mix-blend-mode: saturation; //
饱和度 mix-blend-mode: color; // 颜色 mix-blend-mode: luminosity; //
亮度 mix-blend-mode: initial; mix-blend-mode: inherit; mix-blend-mode:
unset; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
  mix-blend-mode: normal;         // 正常
  mix-blend-mode: multiply;       // 正片叠底
  mix-blend-mode: screen;         // 滤色
  mix-blend-mode: overlay;        // 叠加
  mix-blend-mode: darken;         // 变暗
  mix-blend-mode: lighten;        // 变亮
  mix-blend-mode: color-dodge;    // 颜色减淡
  mix-blend-mode: color-burn;     // 颜色加深
  mix-blend-mode: hard-light;     // 强光
  mix-blend-mode: soft-light;     // 柔光
  mix-blend-mode: difference;     // 差值
  mix-blend-mode: exclusion;      // 排除
  mix-blend-mode: hue;            // 色相
  mix-blend-mode: saturation;     // 饱和度
  mix-blend-mode: color;          // 颜色
  mix-blend-mode: luminosity;     // 亮度
  
  mix-blend-mode: initial;
  mix-blend-mode: inherit;
  mix-blend-mode: unset;
}

除去 initial 默认、inherit 继承 和 unset 还原这 3 个所有 CSS
属性都可以取的值外,还有另外的 16
个具体的取值,对应不同的混合效果。

如果不是专业的 PSer
天天和混合模式打交道,想要记住这么多效果,还是挺困难的。不过有前人帮我们总结了一番,看看如何比较好的理解或者说记忆这些效果,摘自Photoshop中高级进阶系列之一——图层混合模式原理:

澳门微尼斯人手机版 3

澳门微尼斯人手机版,当然,上图是 PS 中的混合模式,数量比 CSS
中的多出几个,但是分类还是通用的。

.5px方案

2014年的WWDC大会中,Ted O’Conor在分享“设计响应的Web体验”
主题时提到关于Retina Hairlines一词,也就是Retina极细的线:

在Retina屏上仅仅显示1物理像素的边框,开发者应该如何处理呢?

实际上其想表达的是iOS8下1px边框的解决方案。1px的边框在devicePixelRatio = 2的Retina屏下会显示成2px,在iPhone6
Plus下甚至会显示成3px

还好,时代总是进步的,在iOS8下,苹果系列都已经支持0.5px了,那么意味着在devicePixelRatio = 2时,我们可以借助媒体查询来处理:

.border { border: 1px solid black; } @media
(-webkit-min-device-pixel-ratio: 2) { .border { border-width: 0.5px } }

1
2
3
4
5
6
7
8
9
.border {
    border: 1px solid black;
}
 
@media (-webkit-min-device-pixel-ratio: 2) {
    .border {
        border-width: 0.5px
    }
}

但在iOS7以下和Android等其他系统里,0.5px将会被显示为0px,那么我们就需要想出办法解决,说实在一点就是找到Hack。

首先我们可以通过JavaScript来判断UA,如果是iOS8+,则输出类名hairlines,为了防止重绘,把这段代码添加在“之前:

if (/iP(hone|od|ad)/.test(navigator.userAgent)) { var v =
(navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/), version =
parseInt(v[1], 10); if(version >= 8){
document.documentElement.classList.add(‘hairlines’) } }

1
2
3
4
5
6
7
if (/iP(hone|od|ad)/.test(navigator.userAgent)) {
    var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/),
        version = parseInt(v[1], 10);
    if(version >= 8){
        document.documentElement.classList.add(‘hairlines’)
    }
}

除了判读UA之外,还可以通过JavaScript来判断是否支持0.5px边框,如果支持的话,同样输出类名hairlines

if (window.devicePixelRatio && devicePixelRatio >= 2) { var testElem
= document.createElement(‘div’); testElem.style.border = ‘.5px solid
transparent’; document.body.appendChild(testElem); if
(testElem.offsetHeight == 1){
document.querySelector(‘html’).classList.add(‘hairlines’); }
document.body.removeChild(testElem); }

1
2
3
4
5
6
7
8
9
if (window.devicePixelRatio && devicePixelRatio >= 2) {
    var testElem = document.createElement(‘div’);
    testElem.style.border = ‘.5px solid transparent’;
    document.body.appendChild(testElem);
    if (testElem.offsetHeight == 1){
        document.querySelector(‘html’).classList.add(‘hairlines’);
    }
    document.body.removeChild(testElem);
}

相比于第一种方法,这种方法的可靠性更高一些,但是需要把JavaScript放在body标签内,相对来说会有一些重绘,个人建议是用第一种方法。

这个方案无法兼容iOS8以下和Android的设备。如果需要完美的兼容,可以考虑和方案一结合在一起处理。只是比较蛋疼。当然除了和Flexible方案结合在一起之外,还可以考虑和下面的方案结合在一起使用。

什么是关键CSS?

对CSS文件的请求可以显著增加网页呈现所需的时间。
原因是默认情况下,浏览器将延迟页面呈现,直到它完成加载、解析和执行所有在“页面”中引用的CSS文件。
这样做是因为它需要计算页面的布局。

不幸的是,这意味着如果我们有一个非常大的CSS文件,并且需要一段时间才能完成下载,我们的用户将在浏览器开始呈现页面之前等待整个文件被下载下来。
幸运的是,有一个巧妙的技术,使我们能够优化我们的CSS的传输并减轻阻塞。这种技术被称为优化关键渲染路径。
关键渲染路径表示浏览器呈现页面的所有必须步骤。
我们想要找到最小的阻塞CSS集合 ,或者关键 CSS,以使页面显示给用户。
关键资源是可能阻塞页面首屏呈现的所有资源。
这背后的想法是,网站应该在前几个TCP数据包响应中为用户获取第一个屏幕的内容(或“首屏”内容)。
想要简要了解如何在网页上工作,请查看下面的图片。

澳门微尼斯人手机版 4

关键 CSS是向用户呈现第一屏的内容所需CSS的最少集合。
(查看大图)

在上面的示例中,网页的关键部分只是用户在首次加载页面时可以看到的内容
这意味着我们只需要加载最小量的CSS来渲染页面顶部的内容。
对于CSS的其余部分,我们不需要担心,因为我们可以异步加载它。

我们如何确定关键CSS?
确定页面的关键CSS是相当复杂的,需要您浏览网页的DOM。
接下来,我们需要确定当前应用于视图中每个元素的样式列表。
手动执行此操作将是一个繁琐的过程,但是一些很棒的工具可以自动执行这个过程。

在本文中,我将向您展示如何使用关键的CSS提高您的网页呈现速度,并介绍一个可以帮助您自动执行此过程的工具。

mix-blend-mode 实例

眼见为实,要会使用 mix-blend-mode ,关键还是要迈出使用这一步。这里我写了一个简单的
Demo,包括了所有的混合模式,可以大概试一下各个模式的效果:

See the Pen mix-blend-mode
混合模式示例 by Chokcoco
(@Chokcoco) on
CodePen.

CodePen Demo(-webkit- Only)

当然,仅仅是这样是感受不到混合模式的魅力的,下面就列举几个利用了混合模式制作的
CSS 动画。

border-image

border-image是一个很神奇的属性,Web开发人员借助border-image的九宫格特性,可以很好的运用到解决1px边框中。使用border-image解决1px咱们需要一个特定的图片,这张图片要符合你的要求,不过它长得像下图:澳门微尼斯人手机版 5

 

实际使用的时候:

border-width: 0 0 1px 0; border-image: url(linenew.png) 0 0 2 0 stretch;

1
2
border-width: 0 0 1px 0;
border-image: url(linenew.png) 0 0 2 0 stretch;

上面的效果也仅实现了底部边框border-bottom1px的效果。之所以使用的图片是2px的高,上部分的1px颜色为透明,下部分的1px使用的视觉规定的border颜色。但如果我们边框底部和顶部都需要border时,需要做一下图片的调整:

澳门微尼斯人手机版 6

border-width: 1px 0; border-image: url(linenew.png) 2 0 stretch;

1
2
border-width: 1px 0;
border-image: url(linenew.png) 2 0 stretch;

到目前为止,我们已经能在iPhone上展现1px边框的效果。但是我们也发现这样的方法在非视网膜屏幕上会出现border不显示的现象。为了解决这个问题,可以借助媒体查询来处理:

.border-image-1px { border-bottom: 1px solid #666; } @media only screen
and (-webkit-min-device-pixel-ratio: 2) { .border-image-1px {
border-bottom: none; border-width: 0 0 1px 0; border-image:
url(../img/linenew.png) 0 0 2 0 stretch; } }

1
2
3
4
5
6
7
8
9
10
.border-image-1px {
    border-bottom: 1px solid #666;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
    .border-image-1px {
        border-bottom: none;
        border-width: 0 0 1px 0;
        border-image: url(../img/linenew.png) 0 0 2 0 stretch;
    }
}

不管是只有一边的边框(比如示例中的底部边框),还是上下都有边框,我们都需要对图片做相应的处理,除些之外,如果边框的颜色做了变化,那么也需要对图片做处理。这样也不是一个很好的解决方案。

关键CSS实践

使用关键CSS,我们需要改变我们处理CSS的方式 – 这意味着将其分成两个文件。
对于第一个文件,我们仅提取渲染上述内容所需的最小CSS集,然后将其内联在网页中。
对于第二个文件或非关键的CSS,我们异步加载它,以免阻塞网页。

一开始似乎有点奇怪,但是通过将关键的CSS集成到HTML中,我们可以消除关键路径中的额外的请求。
这使我们能够在一次请求中提供关键的CSS,以尽快向用户展示页面。

下面的代码给出了一个基本的例子。

JavaScript

<!doctype html> <head> <style> /* 内联CSS */
</style> “<script> loadCSS(‘non-critical.css’);
</script>“ </head> <body> …body goes here
</body> </html>

1
2
3
4
5
6
7
8
9
&lt;!doctype html&gt;
&lt;head&gt;
  &lt;style&gt; /* 内联CSS */ &lt;/style&gt;
  “&lt;script&gt; loadCSS(‘non-critical.css’); &lt;/script&gt;“
&lt;/head&gt;
&lt;body&gt;
  …body goes here
&lt;/body&gt;
&lt;/html&gt;

如上,我们将关键CSS内联在style 标签中。然后,使用 loadCSS();
异步加载非关键的CSS。 这很重要,因为我们在展示首屏后加载繁重的(非关键)
CSS。

起初,这似乎是一场噩梦。 为什么要手动在每个页面内嵌CSS片段?
但是有一个好消息,这个过程可以自动化,在这个例子中,我将运行一个名为Critical
的工具。 Addy Osmani
创造,它是一个允许您自动提取和内联关键路径CSS到HTML中的的Node.js包。
我将把这个工具和 Grunt 一起介绍,
Grunt是一个JavaScript 任务执行器, 自动处理CSS。 如果你之前没听过Grunt,
这个网站有一些非常 详细文档,
以及配置项目的各种解释。我之前博客介绍过这个工具.

发表评论

电子邮件地址不会被公开。 必填项已用*标注