3

我目前使用 requirejs 主要是因为它的资源加载器。我喜欢它管理后备的方式。

我的 javascript 应用程序一点也不复杂,只是一些 jQuery UI 小部件和其他小的调整。

在我开始使用 requirejs 之前,我什至不知道 FOUC 是什么。这是非常明显的,所以目前我正在避免它:

var protect_from_FOUC = function(element) {
    if(typeof element === 'string') {
        element = document.querySelector(element);
    }
    element.classList.add('ui-helper-hidden');
};

<div id="main" class="main_block" role="main">
<!-- a block affected by FOUC -->
</div>
<script>protect_from_FOUC('#main');</script>

在我的脚本中:

require(['jquery', 'jquery-ui' /*, ...*/], function($) {

var recover_from_FOUC = function(element) {
    $(element).show({
        effect: 'blind',
        duration: 200
    }).removeClass('ui-helper-hidden');
};

$(document).ready(function() {

    // Themed buttons:
    $(':button, :submit, :reset, .button').button();
    // ... Some other similar changes
    recover_from_FOUC('#main');

});  // document.ready

});  // require

这是我所拥有的最好的,我发现的所有关于该主题的在线资源都推荐了这些方面的内容。

我的问题是,考虑到我说的是只影响 UI 的脚本,requirejs 值得吗?正如我所说,我想继续使用它的资源后备系统,但整个“FOUC 补丁”似乎适得其反......

每个 jQuery UI 示例都在头部包含脚本,但互联网上的每个人都建议在关闭正文或使用异步加载器之前包含脚本。此建议是否仅适用于“非 UI”脚本?

在这种情况下什么是最好的?

请注意,即使很接近,这不仅仅是另一个“如何避免 FOUC 问题”。

编辑:添加包含在我的页面和我的外部文件require.config

<!-- This is in my head right below the meta tags and exactly in this order -->
<link rel="shortcut icon" href="images/favicon.ico"/>
<!-- Keep before the site css to allow overriding jquery's style -->
<link rel="stylesheet" href="style/lib/jquery-ui/ui-lightness/jquery-ui.css"/>
<link rel="stylesheet" href="style/lib/chosen/chosen.css"/>
<link rel="stylesheet" href="style/lib/icheck/minimal/yellow.css">
<link rel="stylesheet" href="style/reset.css">
<link rel="stylesheet" href="style/style.css"/>

<!-- Here I have the definition of `protect_from_FOUC` in an inline script -->

<script data-main="js/main" src="js/lib/require.js"></script>

在 main.js 中:

require.config({
    paths: {
        // Common:
        'jquery': ['//code.jquery.com/jquery-2.0.3.min', 'lib/jquery'],
        'sugar': ['//cdnjs.cloudflare.com/ajax/libs/sugar/1.3.9/sugar.min', 'lib/sugar'],

        // UI:
        'jquery-ui': ['//code.jquery.com/ui/1.10.3/jquery-ui.min', 'lib/jquery-ui'],
        'autosize': ['//cdnjs.cloudflare.com/ajax/libs/autosize.js/1.17.1/autosize-min', 'lib/jquery.autosize'],
        'chosen': ['//cdnjs.cloudflare.com/ajax/libs/chosen/0.9.15/chosen.jquery.min', 'lib/chosen.jquery'],
        'icheck': ['lib/jquery.icheck'],

        // django i18n:
        'gettext': [translations_url + '?noext']
    },
    shim: {
        'jquery-ui': {
            deps: ['jquery']
        },
        'autosize': {
            deps: ['jquery']
        },
        'chosen': {
            deps: ['jquery']
        },
        'icheck': {
            deps: ['jquery']
        }
    }
});

require(['style', 'interaction']);
4

2 回答 2

3

scripts-right-before- 赞歌的原因</body>是因为它们阻止了解析。

这很糟糕,尤其是考虑到您的用例,您的页面上可能有很多内容等待解析和呈现,而不是您通过 Javascript 包含的内容。

最后包含脚本允许直接包含在 HTML 中的所有内容都可以愉快地解析和呈现,而无需等待任何脚本(以及它们的整个请求 -> 解析 -> 执行周期)。

但是,这种策略存在一个问题。那就是在你的身体末尾堆积脚本标签不允许良好的(任何?)依赖管理。这是创建 requirejs 的主要原因之一(以及其他用途,如代码封装、版本控制/回退、模板插件等)。

您将 requirejs 用于有效目的,否则管理起来会很痛苦,所以我肯定会说 requirejs 在这种情况下是“值得的”。

至于您对“FOUC 修补”的评论似乎适得其反,我不确定您为什么会这样。考虑一下补丁为您提供了什么:流畅加载的 UI 和畅通无阻的HTML。将阻塞脚本放在头脑中当然可能是一个有效的决定,但前提是页面上的大部分内容取决于它们是否尽快加载。这种情况很少见(实际上是演示/开发使用之外的反模式)。

考虑用户体验,特别是考虑到有些陈旧的智能手机的慢速连接/慢 JS 解析/执行速度。与其让这些用户在空白屏幕上停留 3-5 秒以上,异步加载可以让您感知的加载时间更快。当脚本最终可用时,UI 的花里胡哨可以与您的 FOUC 补丁一起显示。

因此,您可以使用异步脚本提供看似快速的页面加载,并在加载时使用 JS 进行增强,同时使用 requirejs 获得依赖管理/智能资源回退。听起来不错。

于 2013-09-10T20:09:05.633 回答
1

作为外部 CSS 阻塞渲染的后续示例。缓慢的外部样式表将阻止以下页面的呈现(在我测试过的 Chrome 和 FF 中)。

<!doctype html>

<html>

<head>
    <style>body { background: white; }</style>
    <link rel="stylesheet" type="text/css" href="http://deelay.me/0/http://rawgithub.com/gitgrimbo/6487200/raw/red.css">
    <link rel="stylesheet" type="text/css" href="http://deelay.me/5000/http://rawgithub.com/gitgrimbo/6487200/raw/blue.css">
</head>

<body>
    <h1>Top header</h1>

    <script>console.log(new Date()); document.write(new Date());</script>

    <h1>Bottom header</h1>
</body>

</html>

但是,如果您将这两个<link>元素移动到页面正文中(作为 的第一个元素<body>),那么从我在 Chrome 和 FF 中可以看到的...

在 Chrome 中,行为与<link>元素位于文档的<head>.

在 FF 中,您有时会在蓝色之前看到红色背景 5 秒,有时您会在蓝色之前看到一闪而过的红色。我不确定这是为什么。

阻塞脚本?

<script>由于 CSS 延迟,Chrome 和 FF 似乎也阻止了块的运行。也不知道为什么会这样。

于 2013-09-08T18:39:10.573 回答