避免使用同时具有css和js依赖关系的插件进行渲染阻塞

Avoid Render Blocking by plugins which have both css and js dependencies

本文关键字:插件 关系 依赖 js css      更新时间:2023-09-26

我使用的是一个jQuery插件,它有plugin.cssplugin.js作为依赖项,代码在script.js中。我不能让plugin.js和script.js合并,因为我只在我网站的一个网页上使用插件。

为了确保在执行plugin.js和script.js之前加载plugin.css,通常我别无选择,只能在<head>中加载plugin.css,这会导致渲染阻塞(直到头中的所有资源都加载完毕,浏览器不呈现html)。

正常方式:<head>中有CSS,在</body> 之前有JS

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="/css/plugin.css">
</head>
<body>
    // content goes here
    <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'></script>
    <script src="/js/plugin.js"></script>
    <script src="/js/script.js"></script>
</body>
</html>

建议的方法:通过ajax调用加载CSS和JS,并在加载完所有CSS和JS后注入,使用jQuery$。which promise

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    // content goes here
    <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'></script>
    <script class="load-plugin">
        $(document).ready(function(){
            var loadPlugin = {
                css : $.ajax({ url: $(".jquery-plugin-css").data("src")                                                      }),
                js : $.ajax({ url: $(".jquery-plugin-js").data("src")}),
            };
            var scriptJs = $.ajax({ url: $(".script-js").data("src") });
            $.when(loadPlugin.css, loadPlugin.js, scriptJs).then(function(){
                loadPlugin.css.done(function(data){ 
                    $(".jquery-plugin-css").html(data); 
                });
                loadPlugin.js.done(function(data){ 
                    $(".jquery-plugin-js").html(data); 
                });
                scriptJs.done(function(data){ 
                    $(".script-js").html(data); 
                });
            });
        });
    </script>
    <style class="jquery-plugin-css" data-src="/css/plugin.css"></style>
    <script class="jquery-plugin-js" data-src="/js/plugin.js"></script>
    <script class="script-js" data-src="/js/script.js"></script>
</body>
</html>

这将我的第一次渲染时间从3.4秒提高到2.4秒,总页面加载时间从8.5秒提高到8秒。

但这有一些局限性:

  1. 公共托管的url不能使用,因为插件文件中的url就像css文件中的背景图像一样。如果相对于它们的目录提及,那么在代码粘贴到html中后,路径会发生变化
  2. 由于注入的代码不是源文件或外部脚本的一部分,因此无法在开发人员工具中对其进行调试

这种懒散加载插件的方式有优点也有缺点。有人能提出这样做值得吗,还是有更好的做事方式值得吗。

我会尝试的是:

  1. 组合JS文件,使依赖代码位于plugin.JS之后
  2. 在页面底部插入一个脚本,首先动态加载CSS,然后再加载组合的JS。如果您需要示例代码,您可以查看https://github.com/filamentgroup/loadJS/和https://github.com/filamentgroup/loadCSS/.

使用这种方法,CSS和JS都不会阻止渲染。CSS被附加到DOM中,因此相对URL应该没有问题。