当使用许多flexbox、图标和字体时,如何减少页面显示的闪烁?

5

我有一个使用了 flexbox 和一些带有CSS background-image 图标的HTML页面。

在浏览器中打开HTML页面时(即使是本地打开,没有使用网络),会出现一些小闪烁(可能少于100毫秒,但仍然存在):

  • 某些项目会移动几个像素(因为flexbox居中)

  • 某些图标需要几毫秒才能加载

  • 字体需要几十毫秒才能加载,因此我们可以看到使用默认字体显示的内容(可能是 < 50 ms),然后是正确的字体(@font-face...)

如何请求浏览器只在准备好以100%的最终方式绘制(不再移动/闪烁)时才显示诸如工具栏<div class="header-toolbar">等HTML元素?


1
请问您能否包含相关页面的代码?具体而言,是加载字体的部分。但是,提供的代码越多越好 ;) - inwerpsel
@inwerpsel 谢谢!@font-face { font-family: myfont; src: url(local-font.ttf); } - Basj
5个回答

2
  1. 您可以为图像指定宽度和高度。这也是根据Google Insights的建议,以防止“布局移位”。

  2. 至于字体,也许这个会起作用

@font-face {
  font-family: "My Font";
  src: url("/fonts/My-Font.otf");
  font-display: block; /* Fix flickering */
}

或者这样:
<link rel="preload" href="assets/fonts/xxx.woff" as="font" type="font/woff" crossorigin>
  1. 图标是字体的一部分。也许根据 @AlignItems 的回答,它们默认情况下的可见性被设置为隐藏,然后在窗口 load 事件中再次显示它们。

  2. 背景图片不应该有影响。不要忘记设置备用的背景颜色,这可以防止一些闪烁。


1
font-display: block 并不能完全解决闪烁问题,甚至可能会使情况变得更糟。它会导致浏览器在自定义字体未加载时使用不可见的占位符字体来渲染元素(参见文档)。如果必须处理字体延迟问题,则暂时使用默认字体通常会产生更好的效果。 - inwerpsel

2
如何让浏览器仅在准备好以100%确定的方式呈现/显示HTML元素(而无需进一步移动/闪烁)时才请求显示工具栏?
需要注意的一件事是:浏览器不会异步渲染HTML / CSS!
问题不在于HTML / CSS的加载时间,而在于异步内容的加载时间(例如图像/ API调用/等等...)
要解决您遇到的内容闪烁问题,有两个解决方案:
  1. 使用骨架屏加载器。骨架屏加载器是一种填充页面内容的方式,这些内容仍在异步加载中,但不会丢失页面布局,而这正是您所面临的问题。了解更多信息这里
  2. 减少加载时间。如果您可以减少异步数据的加载时间,您可以使其几乎瞬间呈现,几乎不会(即<20ms)注意到移动。当然,从用户体验的角度来看,这仍然不是最好的解决方案,但它是最快的解决方案。减少加载时间的最佳方法之一是压缩图像,或减小字体族大小
这是我找到的另一篇不错的文章(在这里),希望能帮到你更多。祝你好运!

1
也许你正在寻找window.onload:请参考window
.header-toolbar {
  visibility: hidden;
}

window.onload = function() {
const toolbar = document.querySelector('.header-toolbar');
toolbar.style.visibility = 'visible';
};

或者您可以使用特殊的加载器,一些旋转图标,直到窗口加载完成才会显示。


1

这种方法对我有效:

  1. 首先,将<body>添加display: none;opacity: 0;visibility: hidden;也可以)。
  2. 编写两个函数:
function loaded() {
  // Change 'block' to default display value of your body element.
  document.querySelector('body').style.display = 'block';
}

requestAnimationFrame(loaded);

0

正如 @Lorik: 所指出的,更好地专注于减少布局位移。
因此,优化所有外部资产总是一个好主意。

另一种方法可能是在你的 HTML 中 内联关键 CSS
关键意味着所有的 CSS 规则都是必要的,用于给初始页面视图(不需要滚动)即“above-the-fold”内容添加样式。

这可能是一个棘手的任务,因为根据设备的视口大小,在获取最终的关键 CSS 时很难找到平衡点。

但是,你可以通过仅内联主导航/工具栏等样式规则来找到一个不错的折中。

@font-face {
  font-family: MontserratWoff2;
  font-style: normal;
  font-weight: 900;
  src: url('https://fonts.gstatic.com/s/montserrat/v25/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCvC73w5aXo.woff2') format('woff2');
}

.woff2{
  font-family:MontserratWoff2;
  font-weight: 900;
}
<style>
/** 
* critical css for main toolbar
* font subset: ABCDEFGHIJKLMNOPQRSTUVWXYZ.:;?! 
*/
@font-face {
  font-family: 'MontserratSubset';
    src: url('data:font/woff2;charset=utf-8;base64,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') format('woff2');
  font-weight: 900;
  font-style: normal;
  font-display:swap;
}
  
body{
  font-size:2vw;
}

a{
  text-decoration:none;
  color:inherit;
}

.flex{
  display:flex;
  justify-content:center;
  gap:1em;
  border:1px solid #ccc;
  padding:3em;
}

.header-toolbar a{
  text-transform:uppercase;
}

.icon{
  height:1em;
  margin-right:0.333em;
  transform:translateY(0.1em)
}
  
.subset{
  font-family:MontserratWoff2, MontserratSubset;
  font-weight: 900;
}
  
</style>

<div class="flex header-toolbar woff2 subset">
  <a href="#"><svg class="icon" viewBox="0 0 448 512"><use href="#icon-calendar" /></svg>Home</a>
  <a href="#"><svg class="icon" viewBox="0 0 512 512"><use href="#icon-circle-right" /></svg>About us</a>
  <a href="#"><svg class="icon" viewBox="0 0 512 512"><use href="#icon-circle-check" /></svg>Legal notice</a>
  <a href="#"><svg class="icon" viewBox="0 0 512 512"><use href="#icon-circle-left" /></svg>Privacy policy</a>
</div>

<p class="woff2">One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.</p>


<!-- hidden svg icon assets -->

<svg width="0" height="0">
  <symbol class="icon icon-calendar" id="icon-calendar" viewBox="0 0 448 512">
    <path d="M152 64H296V24C296 10.75 306.7 0 320 0C333.3 0 344 10.75 344 24V64H384C419.3 64 448 92.65 448 128V448C448 483.3 419.3 512 384 512H64C28.65 512 0 483.3 0 448V128C0 92.65 28.65 64 64 64H104V24C104 10.75 114.7 0 128 0C141.3 0 152 10.75 152 24V64zM48 448C48 456.8 55.16 464 64 464H384C392.8 464 400 456.8 400 448V192H48V448z"></path>
  </symbol>

  <symbol class="icon icon-circle-right" id="icon-circle-right" viewBox="0 0 512 512">
    <path d="M280.2 150.2C273.1 143.8 262.1 142.2 254.3 146.1S239.1 158.5 239.1 167.1l.002 56L152 224C138.8 224 128 234.8 128 248v16C128 277.3 138.8 288 152 288L240 287.1v56c0 9.531 5.656 18.16 14.38 22c8.75 3.812 18.91 2.094 25.91-4.375l96-88.75C381.2 268.3 384 261.9 384 255.2c-.3125-7.781-2.875-13.25-7.844-17.75L280.2 150.2zM256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 464c-114.7 0-208-93.31-208-208S141.3 48 256 48s208 93.31 208 208S370.7 464 256 464z"></path>
  </symbol>

  <symbol class="icon icon-circle-check" id="icon-circle-check" viewBox="0 0 512 512">
    <path d="M335 175L224 286.1L176.1 239c-9.375-9.375-24.56-9.375-33.94 0s-9.375 24.56 0 33.94l64 64C211.7 341.7 217.8 344 224 344s12.28-2.344 16.97-7.031l128-128c9.375-9.375 9.375-24.56 0-33.94S344.4 165.7 335 175zM256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 464c-114.7 0-208-93.31-208-208S141.3 48 256 48s208 93.31 208 208S370.7 464 256 464z"></path>
  </symbol>
  
<symbol class="icon icon-circle-left" id="icon-circle-left" viewBox="0 0 512 512">
    <path d="M360 224L272 224v-56c0-9.531-5.656-18.16-14.38-22C248.9 142.2 238.7 143.9 231.7 150.4l-96 88.75C130.8 243.7 128 250.1 128 256.8c.3125 7.781 2.875 13.25 7.844 17.75l96 87.25c7.031 6.406 17.19 8.031 25.88 4.188s14.28-12.44 14.28-21.94l-.002-56L360 288C373.3 288 384 277.3 384 264v-16C384 234.8 373.3 224 360 224zM256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 464c-114.7 0-208-93.31-208-208S141.3 48 256 48s208 93.31 208 208S370.7 464 256 464z"></path>
  </symbol>
</svg>

在上面的代码片段中,主导航可以立即呈现字体,而下一个段落将稍有延迟。
使用数据URL作为内联字体子集
除了使用更高效的woff2字体格式外,您还可以通过数据URL添加用于“关键字母”(用于主导航)的子集字体。
这可能是一种合适的方法,特别是如果您的主导航仅使用大写字母。
您可以使用像transfonter这样的工具创建子集,将字符/字形范围缩小到例如“ABCDEFGHIJKLMNOPQRSTUVWXYZ.:;?!”

transfonter - subset

缺点
显然,您的HTML文件大小将增加。
因此,如果您在纯HTML中维护代码,则可读性也会受到影响。

另请参阅


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接