【问题标题】:Grunt usemin not working after optimizations for Pagespeed优化 Pagespeed 后 Grunt usemin 无法正常工作
【发布时间】:2017-05-02 23:09:40
【问题描述】:

我最近做了一些优化,以提高我正在开发的应用程序 (AngularJS) 在 Google 网站管理员工具的 Pagespeed 工具中的得分。

具体来说,Google 要求“消除首屏内容中的渲染阻塞 JavaScript 和 CSS”。所以我删除了声明并将它们移动到页面完成加载时加载的脚本中,所以我从:

<link rel="stylesheet" href="/bundles/vendor.css"/>
<link rel="stylesheet" href="/bundles/common.css"/>
<script src="/bundles/vendor.bundle.js"></script>

到这里:

    <script type="text/javascript">
    function downloadJSAtOnload() {

        var stylesheet1 = document.createElement('link');
        stylesheet1.href = "https://fonts.googleapis.com/css?family=Poppins";
        stylesheet1.rel = 'stylesheet';
        stylesheet1.type = 'text/css';
        document.getElementsByTagName('head')[0].appendChild(stylesheet1);

        var stylesheet2 = document.createElement('link');
        stylesheet2.href = "/bundles/vendor.css";
        stylesheet2.rel = 'stylesheet';
        stylesheet2.type = 'text/css';
        document.getElementsByTagName('head')[0].appendChild(stylesheet2);

        var stylesheet3 = document.createElement('link');
        stylesheet3.href = "/bundles/common.css";
        stylesheet3.rel = 'stylesheet';
        stylesheet3.type = 'text/css';
        document.getElementsByTagName('head')[0].appendChild(stylesheet3);

        var element1 = document.createElement("script");
        element1.src = "/bundles/common.bundle.js";
        document.body.appendChild(element1);

    }
    if (window.addEventListener)
        window.addEventListener("load", downloadJSAtOnload, false);
    else if (window.attachEvent)
        window.attachEvent("onload", downloadJSAtOnload);
    else window.onload = downloadJSAtOnload;
</script>

在 body 元素的底部。

效果很好,也大大提高了我的分数,但是,它导致了分发问题。

我们使用 grunt 来构建资产,我们执行通常的 uglify、minify 等操作。我们调用 filerev grunt 任务在资产文件中生成缓存破坏器版本 id,然后我们调用usemin 将原始资产文件的引用替换为带有版本号的引用以破坏缓存。

问题是 usemin 只作用于具有 src 元素的元素,并且由于我现在加载这些资产的方式,它保留了对原始资产名称的引用。这意味着我必须在构建之后在发布期间手动更改它,这是不可接受的。

所以我正在寻找使其工作的方法或替代方案,但到目前为止还没有运气。

【问题讨论】:

    标签: javascript angularjs grunt-usemin


    【解决方案1】:

    在我看来,你一开始就不应该这样做。

    在 HTML 加载并呈现在页面上之后,您将加载所有 CSS。这意味着您几乎肯定会拥有flash of unstyled content。为防止这种情况发生,您的样式应首先加载到您的 &lt;head&gt;

    请注意,window.onload 等待您的文档窗口准备好进行演示,这意味着所有外部资源都已加载。例如,如果页面上有图像,则在加载所有图像之前不会加载 CSS 和 JS。这很可能比您等待加载 JS 的时间更长。

    由于&lt;script&gt; 标签阻止了 DOM 的构建(因为它需要执行该 JS),一个更好的方法可能是使用 async or defer attributes 这样您仍然可以将 &lt;script&gt; 标签添加到您的末尾&lt;body&gt; 但它不会阻止您的页面被呈现。

    存在过度优化这样的事情。获得更好的 Pagespeed 分数是否值得降低您的用户体验?这由你决定,但我倾向于学习“不”:)

    【讨论】:

    • 我有点同意你的看法,但客户想提高分数。我尝试了 defer,它对 js 文件很有效,但对 css 无效。
    【解决方案2】:

    好吧,我终于能够解决这个问题了。我使用了filerev-apply grunt plugin,它适用于所有字符串,而不仅仅是那些具有 src 属性的脚本元素,就像 usemin 似乎正在做的那样。

    效果很好

    我使用带有别名的 grunt,所以这是 filerev_apply.js 任务文件:

    module.exports = function(grunt, options) {
        return {
            dist: {
                files: [{
                    '<%= dist %>/index.html': '<%= dist %>/index.html',
                }]
            }
        };
    };
    

    在 filerev 之后调用它就完成了。

    【讨论】:

      猜你喜欢
      • 2014-05-06
      • 1970-01-01
      • 2017-08-07
      • 1970-01-01
      • 1970-01-01
      • 2018-08-16
      • 1970-01-01
      • 2016-02-16
      • 1970-01-01
      相关资源
      最近更新 更多