【问题标题】:Flashing between page loads在页面加载之间闪烁
【发布时间】:2012-09-03 16:44:12
【问题描述】:

在一个网站上,我遇到了页面加载之间出现的白色“闪光”。它看起来很糟糕,因为我使用的是背景图片,当页面加载时,背景图片会在它出现在屏幕上之前闪烁 (take a look for yourself)。此问题在 chrome 和 IE 中出现,但在 Firefox 中没有。

该网站有一种预加载内容的方法。页面上的每个元素都在一个 div 包装器 #website 中,它最初位于 display:none,每个图像都在一个 div 包装器 #website-images 中,它也是隐藏的。然后站点(使用 jquery 插件)检查#website-images 中的所有图像是否已完成加载,一旦它们是一个 cookie,就会被设置为记住该用户已经加载了图像,因此它不会通过预加载一旦他们转到另一个页面或重新加载当前页面,然后调用$("#website").show() 以显示该网页。

那么是什么导致了页面加载之间的这种闪烁?这是我预加载图像的方式吗?我添加了不同的文档类型,并更改了元信息,但没有任何效果。我真的迷路了,有没有人有任何想法或见解?

【问题讨论】:

  • 我真正想做的是让页面在 IMG 完全加载之前什么都不渲染,然后渲染整个页面。如果我将 body 样式设置为 display:none 并将 JavaScript 放在 body 的末尾以将 body 样式设置为 block,在 Firefox 和 Chrome 中仍然会出现白色闪烁。我认为 img 的实际加载是在整个页面呈现后完成的?似乎不可能消除白色闪光;奇怪。

标签: javascript html optimization dom-events


【解决方案1】:

在关闭正文标记之前将您的 javascript 移动到 html 的末尾。有时会有所帮助。

【讨论】:

    【解决方案2】:

    发生这种情况是因为 DOMLoaded 事件在页面实际呈现之前被触发了足够多的毫秒。

    简而言之,这意味着您必须优化网站的速度。这并不意味着让它下载更快,而是意味着以正确的顺序,以非阻塞的方式下载。

    第一步:您的标记

    1) 看来您可以做很多事情来优化您的标记。首先,可以优化样式表和 JavaScript 的顺序。为确保 CSS 文件是异步下载的,您始终必须在外部 JavaScript 文件之前包含外部 CSS。 style.css 在您的部分/全部 JavaScript 调用后下载。

    在外部 CSS 文件和另一个资源之间的头部发现了 1 个脚本块。要允许并行下载,请将内联脚本移动到外部 CSS 文件之前或下一个资源之后。

    2) 您的主要 JavaScript 文件内联在您的标记中。这不仅会在脚本完成下载之前阻止页面下载,而且在之前您的内容可能会导致(或添加到)白色闪烁。

    在头部异步加载脚本是我的首选方法。然后,您必须在 DOM 完成加载后触发您的脚本,或者您可以通过将脚本放在 body 标记的底部来获得相同的结果。

    第二步:利用浏览器的功能

    1) 查看 http 标头,有 28 个项目作为单独的 HTTP 调用提供服务,没有缓存在浏览器上(包括 html 页面、jpg 图像、样式表和 JavaScript 文件)。

    这些项目是明确不可缓存的,这可以通过编辑您的网络服务器的配置轻松解决。

    2) 启用 gzip 压缩。大多数 Web 浏览器(是的,甚至 IE)都支持 gzip 解压缩,并且大多数(如果不是全部)Web 服务器支持使用 gzip 进行压缩。您甚至可以过分考虑 SPDY,它是一种替代的更轻量级 HTTP 协议(​​在 Chrome 和 Firefox 中受支持)。

    第三步:内容服务

    您的域中提供了大约 30 个单独的项目。首先,考虑如何减少此请求数量。每个页面查看 30 个 HTTP 请求是很多的。您可以使用以下方法解决此问题:

    1) 跨多个主机名的并行下载。浏览器当前限制了单个域的并发连接数。从单独的域(例如,img.bigtim.ca)提供您的图片可以让它们与其他内容并行提供。

    2) 将多个项目合二为一。下载的许多项目都是纯样式内容,例如徽标、菜单元素等。这些可以组合成单个图像(仅下载一次),并使用 CSS 进行拆分。这称为 CSS 精灵。 Stack Overflow 这样做:look here.

    3) 如果您无法减少需要下载的项目的数量,您可以通过提供来自无 cookie 域的静态内容来减少服务器(进而减少客户端浏览器)的负载。 Stack Overflow 使用其所有静态内容(例如图像、样式表和脚本)来执行此操作。

    第四步:优化自己的代码

    HTTP 和浏览器技术可以帮助您提高网站速度的能力有限。这最后一步取决于您。

    1) 您选择自己托管 jquery 有什么原因吗? Jquery 的下载页面显示了多个 CDN,您可以在其中指向快速缓存脚本下载。

    2) 您的样式表中目前有 20 多个未使用的 CSS 规则(占整个 CSS 文件的 36%)。重新考虑真正需要什么。

    3) JavaScript 的主要部分(在你的 body 标签的顶部)似乎是一个试图加快速度的黑客,但可能没有任何帮助。

    正在设置 cookie 以指定页面是否已淡入。您不仅使用 JavaScript 执行 CSS 可以愉快地执行的转换,而且一半以上的脚本用于定义读取和写入 cookie 的功能。

    看到这样的事情:$("body").css ("background-image", "url('images/background.png')"); 和 $("#website").show (); 通常会让我抱怨“关注点分离”,但是这个答案现在已经足够长了,所以希望你能看到在相同的代码。

    附录:看代码,根本不需要jquery来 执行你正在做的事情。但是话又说回来,没有必要 执行你正在做的事情,所以你可能会做得更好 完全是 JavaScript。

    【讨论】:

    • Greg,您如何看待“新”前端 JS 框架的关注点分离?
    • @johnny 一言以蔽之:太糟糕了。几十年来,我们一直在学习分离 HTML、JS 和 CSS 的好处,新的框架出现并持续不断地在没有追索权的情况下破坏网络。
    • 那么你会继续使用 jQuery 还是直接使用 JS 或两者兼而有之?
    • @johnny 视情况而定。我喜欢在服务器上保留尽可能多的逻辑,所以这些天 JavaScript 的使用对我来说是最少的,而 jQuery 将是矫枉过正。但是,如果您正在使用繁重的 JavaScript,那么它提供的跨浏览器 API 仍有空间。
    【解决方案3】:

    我知道这是旧线程,但这是我尝试过并且有效的 hack。 这个想法是在 CSS 完全加载时不显示任何内容。

    在 html 文件中:

    <body style="display:none">
    

    在您的 CSS 中,最后一行:

    body{display:block !important}
    

    【讨论】:

    • 对我来说,这没有效果。在渲染 4.5MB IMG 元素之前,仍然会出现大的白色闪光。我使用的是 STYLE 标签,而不是外部 CSS,因为我使用的是 Bootstrap 5。
    【解决方案4】:

    CSS 是渲染阻塞的。 将你的 CSS 分成两部分 -

    • 关键的 CSS
    • 非关键 CSS

    让页面加载关键的 CSS。它应该嵌入到 head 标签中。 通过 ajax 使非关键 CSS 延迟加载。

    这将导致您网页的性能得到严重优化,从而减少白屏时间。

    另外,您可以考虑以异步/延迟方式加载您的 Javascript。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多