更好,但浏览器仍加载所有JavaScript包,而不只是所需的包。

Commerce捆绑可减少每页的连接数,但对于每个页面请求,它会加载所有捆绑包,即使所请求的页面可能仅依赖于一个或两个捆绑包中的文件也是如此。 在浏览器缓存捆绑包后,性能得以改进。 但是,由于浏览器同步加载这些捆绑包,因此用户首次访问Commerce店面可能需要一段时间才能呈现,并且会损害用户体验。

要从命令行启用内置合并,请执行以下操作:

php -f bin/magento config:set dev/js/merge_files 1
        

真实世界渲染时间

在开发环境中,之前的捆绑和合并加载时间看起来非常好。 但在现实世界中,很多事情会减慢渲染速度:连接速度慢,连接阈值大,网络有限。 此外,移动设备的呈现速度不如台式机。

要测试和准备店面部署以进行现实世界测试,我们建议您使用Chrome的本机限制配置文件“慢3G”进行测试。 通过Slow 3G,我们以前捆绑的输出时间现在反映了许多用户的连接现实:

请记住,JavaScript捆绑的目标是减少浏览器中加载的每个页面所请求的资产的数量和大小。 为此,我们希望构建捆绑包,以便商店中的每个页面只需要下载一个通用捆绑包和一个针对所访问每个页面的页面特定捆绑包。

实现此目标的一种方法是按页面类型定义捆绑包。 您可以将Commerce的页面划分为多种页面类型,包括“类别”、“产品”、“CMS”、“客户”、“购物车”和“结帐”。 分类为其中一种页面类型的每个页面都具有一组不同的RequireJS模块依赖项。 当按页面类型捆绑RequireJS模块时,最终将只有少数捆绑包覆盖存储中任何页面的依赖项。

例如,最终可能会有一个用于所有页面通用的依赖项的捆绑包、一个用于仅CMS页面的捆绑包、一个用于仅目录页面的捆绑包、另一个用于仅搜索页面的捆绑包,以及一个用于签出页面的捆绑包。

您还可以按用途创建包:用于常见功能、产品相关功能、配送功能、结账功能、税费和表单验证。 如何定义捆绑包取决于您以及商店的结构。 您可能会发现某些捆绑式策略比其他策略效果更好。

干净的Commerce安装允许通过按页面类型拆分捆绑包来实现足够的良好性能,但某些自定义可能需要更深入的分析和其他资产分配。

要执行以下步骤,您必须安装并熟悉以下工具:

稍后,我们将将optimize:设置从_ none更改为uglify2以缩小包输出。 但现在,在开发过程中,您可以将其保留为none以确保更快的生成。

2\。 添加RequireJS依赖项、填充项、路径和映射

将以下RequireJS生成配置节点depsshimpathsmap添加到您的生成文件中:

optimize: 'none', inlineText: true, deps: [], shim: {}, paths: {}, map: { "*": {} },

在此文件中,您将找到每个配置节点(depsshimpathsmap)的多个条目。 您需要将这些多个节点值聚合到build.js文件的单个配置节点中。 例如,如果存储区的requirejs-config.js实例包含15个单独的map节点的条目,则需要将所有15个节点的条目合并到build.js文件中的单个map节点中。 depsshimpaths节点同样如此。 如果没有脚本来自动执行此过程,则可能需要一些时间。

您需要将配置节点paths中的路径mage/requirejs/text更改为requirejs/text,如下所示:

//... paths: { //... "text": "requirejs/text" if (system.args.length === 1) { console.log('Usage: $phantomjs deps.js url'); phantom.exit(1); } else { address = system.args[1]; page.open(address, function (status) { if (status !== 'success') { console.log('FAIL to load the address'); } else { setTimeout(function () { console.log(page.evaluate(function () { return Object.keys(window.require.s.contexts._.defined); phantom.exit(); }, 5000);

打开Commerce根目录中的终端,并对存储中表示特定页面类型的每个页面运行脚本:

phantomjs deps.js 指向特定页面的url > text-file-representing-pagetype-dependencies
        

例如,下面是Luma主题示例存储中的四个页面,这些页面表示我们将用于创建四个包(主页、类别、产品、购物车)的四种页面类型:

phantomjs deps.js http://m2.loc/ > bundle/homepage.txt
phantomjs deps.js http://m2.loc/women/tops-women/jackets-women.html > bundle/category.txt
phantomjs deps.js http://m2.loc/beaumont-summit-kit.html > bundle/product.txt
phantomjs deps.js http://m2.loc/checkout/cart/?SID=m2tjdt7ipvep9g0h8pmsgie975 > bundle/cart.txt (prepare a shopping cart)
..............
        

此命令(在PhantomJS脚本中使用)创建RequireJS依赖项的相同列表并在浏览器控制台中显示它们。 此方法的缺点是,您必须创建自己的包/页面类型文本文件。

6\。 设置输出格式并筛选

将RequireJS依赖项合并到页面类型文本文件后,您可以对每个页面类型依赖项文件使用以下命令,将文件中的逗号替换为换行符:

sed -i -e $'s/,/\\\n/g' bundle/category.txt
sed -i -e $'s/,/\\\n/g' bundle/homepage.txt
sed -i -e $'s/,/\\\n/g' bundle/product.txt
              
sed -i -e 's/mixins\!.*$//g' bundle/homepage.txt
sed -i -e 's/mixins\!.*$//g' bundle/category.txt
sed -i -e 's/mixins\!.*$//g' bundle/product.txt
        

此输出显示buildTools仅在bundle/*.txt文件中的一个文件中为依赖项。 jquery/jquery.metadata依赖项位于两(2)个文件中,es6-collections位于三(3)个文件中。

我们的输出仅显示三种页面类型(主页、类别和产品),这告诉我们:

n = split(rec[R], t, "/") if (n > 1) dup[n] = dup[n] ? dup[n] RS sprintf("\t%-20s -->\t%s", rec[R], R) : \ sprintf("\t%-20s -->\t%s", rec[R], R) for (D in dup) { printf "records found in %d files:\n\n", D printf "%s\n\n", dup[D] rec[$0] = rec[$0] ? rec[$0] "/" FILENAME : FILENAME }' bundle/*.txt

您还可以在https://www.unix.com/shell-programming-and-scripting/140390-get-common-lines-multiple-files.html找到该脚本

在Commerce根目录中打开终端并运行文件:

bash deps-map.sh
              
bundle/product.txt   -->   buildTools,
bundle/category.txt  -->   jquery/jquery.parsequery,
bundle/product.txt   -->   jsbuild,
bundle/category.txt/bundle/homepage.txt -->    jquery/jquery.metadata,
bundle/category.txt/bundle/homepage.txt -->    jquery/validate,
bundle/category.txt/bundle/homepage.txt -->    mage/bootstrap,
bundle/category.txt/bundle/homepage.txt/bundle/product.txt --> jquery,
bundle/category.txt/bundle/homepage.txt/bundle/product.txt --> jquery/ui,
bundle/category.txt/bundle/homepage.txt/bundle/product.txt --> knockoutjs/knockout,
                
  • requirejs/require — 唯一同步加载的包
  • mage/bootstrap — 带有UI组件的引导程序捆绑包
  • bundles/default — 所有页面都需要默认捆绑包
  • bundles/cart — 购物车页面所需的捆绑包
  • bundles/shipping — 购物车和结帐页面的通用捆绑包(假设从未直接打开结帐,那么如果以前打开了购物车页面并且已经加载了装运捆绑包,则结帐页面的加载速度会更快)
  • bundles/checkout — 用于结账的所有内容
  • bundles/catalog — 产品和类别页面的所有内容
  • 第2部分:生成包

    以下步骤描述了生成更高效的Commerce捆绑包的基本流程。 您可以按照所需的任何方式自动执行此过程,但您仍需要使用nodejsr.js来实际生成捆绑包。 如果您的主题具有与JavaScript相关的自定义项并且无法重用相同的build.js文件,则可能需要为每个主题创建多个build.js配置。

    1.生成静态存储站点

    在生成捆绑包之前,请运行静态部署命令:

    php -f bin/magento setup:static-content:deploy -f -a frontend
                  
    total 1900
    drwxr-xr-x  2 root root    4096 Mar 28 11:24 ./
    drwxr-xr-x 70 root root    4096 Mar 28 11:24 ../
    -rw-r--r--  1 root root  116417 Mar 28 11:24 cart.js
    -rw-r--r--  1 root root  187090 Mar 28 11:24 catalog.js
    -rw-r--r--  1 root root  307619 Mar 28 11:24 checkout.js
    -rw-r--r--  1 root root 1240608 Mar 28 11:24 default.js
    -rw-r--r--  1 root root   74233 Mar 28 11:24 shipping.js
    bundlesConfigOutFile: `${config.dir}/requirejs-config.js`,
    onModuleBundleComplete: function(data) {
        if (this.bundleConfigAppended) {
            return;
        this.bundleConfigAppended = true;
        // bundlesConfigOutFile requires a simple require.config call in order to modify the configuration
        const bundleConfigPlaceholder = `
    (function (require) {
    require.config({});
    })(require);
        fs.appendFileSync(this.bundlesConfigOutFile, bundleConfigPlaceholder);
                  
    require.config({
        bundles: {
            "bundles/default": ["mage/template", "mage/apply/scripts", "mage/apply/main", "mage/mage", "mage/translate", "mage/loader"],
            "bundles/cart": ["Magento_Ui/js/lib/validation/utils", "Magento_Ui/js/lib/validation/rules", "Magento_Ui/js/lib/validation/validation"]
            

    空主页的页面加载时间现在比使用本机Commerce捆绑快一倍。 但是我们可以做得更好。

    7.优化包

    即使gzipped,JavaScript文件仍然很大。 使用RequireJS来缩小它们,后者使用修饰符来缩小JavaScript以获得良好的结果。

    要在build.js文件中启用优化程序,请添加uglify2作为build.js文件顶部的优化属性的值:

    optimize: 'uglify2', inlineText: true