Javascript 在页面加载之间闪烁

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12358087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:48:25  来源:igfitidea点击:

Flashing between page loads

javascripthtmloptimizationdom-events

提问by Jonson Bylvaklov

On a website, I'm experiencing a "flash" of white that occurs between page loads. It looks bad because I'm using a background image and when the page loads, the background images flash before it comes onto the screen (take a look for yourself). This issues occurs in chrome and IE but not in firefox.

在网站上,我遇到了页面加载之间出现的白色“闪光”。它看起来很糟糕,因为我使用的是背景图像,并且当页面加载时,背景图像在出现在屏幕上之前会闪烁(自己看看)。此问题发生在 chrome 和 IE 中,但不在 Firefox 中。

The site has a way of preloading stuff. Every element on the page is in a div wrapper #websitewhich is initially at display:none, and every image is in a div wrapper #website-imageswhich is also hidden. Then the site (using a jquery plugin) checks to see if all the images in #website-imagesare done loading, once they are a cookie is set to remember that this user has loaded the images already so it won't go through the preloading process once they go to another page or reload the current one, then a call to $("#website").show()is made to display the webpage.

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

So what could be causing this flickering between the page loads? Is it my way of preloading images? I've added different doctypes, and changed meta information but NOTHING has worked. I'm really lost here, does anyone have any ideas or insights?

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

回答by Greg

This is happening because the DOMLoaded event is fired enough milliseconds before the page actually renders.

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

In a nutshell, this means you have to optimise your website's speed. This doesn't mean to make it download faster, but it means to download in the correct order, in a non-blockingway.

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

Step one: Your markup

第一步:你的标记

1) It seems there is a lot you can do to optimise your markup. Firstly, the order of stylesheets and JavaScripts can be optimised. To ensure CSS files are downloaded asynchronously, you always have to include external CSS before external JavaScript files. style.cssis downloaded after some/all of your JavaScript calls.

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

There is 1 script block found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline script before the external CSS file, or after the next resource.

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

2) Your main JavaScript file is inline within your markup. Not only does this block the page download until the script has finished downloading, but having it beforeyour content is probably causing (or adding to) the white flash.

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

Loading your script asynchronously in the head is my preferred method. You will then have to trigger your script when the DOM has finished loading, or you can achieve the same result by placing the script at the bottom of the body tag.

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

Step two: Harness the browser's capabilities

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

1) Looking at the http headers, there are 28 items being served as separate HTTP calls, that are not being cached on the browser (including the html pages, jpg images, stylesheets and JavaScript files).

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

These items are explicitly non-cacheable, and this can be easily fixed by editing your webserver's configuration.

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

2) Enable gzip compression. Most web browsers (yes, even IE) supports gzip decompression, and most (if not all) web servers support compressing using gzip. You could even go overkill and look into SPDY, which is an alternative lighter HTTP protocol (supported in Chrome and Firefox).

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

Step three: Content serving

第三步:内容服务

There are around 30 individual items being served from your domain. Firstly, consider how you could reduce this number of requests. 30 HTTP requests per page view is a lot. You can combat this using the following methods:

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

1) Paralleled downloads across multiple hostnames. Browsers currently limit the number of concurrent connections to a single domain. Serving your images from a separate domain (for example, img.bigtim.ca) can allow them to be served in parallel to other content.

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

2) Combine multiple items into one. Many items that are downloaded are purely style content, such as the logo, menu elements, etc. These can be combined into a single image (downloaded only once), and split using CSS. This is called CSS spriting. Stack Overflow does this: look here.

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

3) If you cannot reduce the amount of items needing downloading, you could reduce the load on your server (and in turn, the client's browser) by serving static content from a cookieless domain. Stack Overflow does this with all their static content such as images, stylesheets and scripts.

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

Step four: Optimise your own code

第四步:优化自己的代码

There's only so much that HTTP and browser technology can do to help your website's speed. This last step is down to you.

HTTP 和浏览器技术可以帮助您提高网站速度的功能就这么多。这最后一步取决于你。

1) Is there any reason you choose to host jquery yourself? Jquery's download page shows multiple CDNs where you can point to for speedy, cached script downloading.

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

2) There are currently over 20 unused CSS rules within your stylesheets (that's 36% of your entire CSS file). Have a re-think of what is really needed.

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

3) The main chunk of JavaScript (at the top of your body tag) seems to be a hack to attempt to speed things up, but is probably not helping anything.

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

A cookie is being set to specify whether or not the page has faded in yet. Not only are you using JavaScript to perform a transition which can happily be performed by CSS, but more than half of the script is used to define the functionality for reading and writing the cookie.

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

Seeing things like this: $("body").css ("background-image", "url('images/background.png')");and $("#website").show ();usually gets me ranting about "separation of concerns", but this answer is long enough now so hopefully you can see that it is bad practice to mix style and functionality in the same code.

看到这样的事情:$("body").css ("background-image", "url('images/background.png')");并且$("#website").show ();通常让我咆哮“关注点分离”,但这个答案现在已经足够长了,所以希望你能看到在同一代码中混合样式和功能是不好的做法。

Addendum: Looking at the code, there is no need for jquery at all to perform what you are doing. But then again, there is no need to perform what you are doing, so you could probably do better without any JavaScript at all.

附录:查看代码,根本不需要 jquery 来执行您正在执行的操作。但话又说回来,没有必要执行你正在做的事情,所以你可能可以在没有任何 JavaScript 的情况下做得更好。

回答by iamvaruns

Move your javascript to the end of the html just before closing the body tags. Sometimes it helps.

在关闭 body 标签之前,将您的 javascript 移动到 html 的末尾。有时它有帮助。

回答by Cris

I know this is old thread but here is a hack I tried and works. The idea is not to display anything while CSS is loaded completely.

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

in html file:

在 html 文件中:

<body style="display:none">

in your CSS, the last line:

在你的 CSS 中,最后一行:

body{display:block !important}

回答by Tal

CSS is render-blocking. Divide you CSS into 2 parts -

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

  • Critical CSS
  • Non-Critical CSS
  • 关键 CSS
  • 非关键 CSS

Make Critical CSS load with the page. It should come embedded within the head tag. Make Non-critical CSS lazy load via ajax.

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

This will result in serious performance optimization in your webpage leading to less white-screen time.

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

Also, you can consider loading your Javascript in async/defer way.

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