Rails 6+Webpacker懒惰加载



我正在运行rails assets:precompile,它输出的是:

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets: 
js/application-c4e0541a90e01b47fbfe.js (1.21 MiB)
js/chartkick-b109b176a3de896848c7.js (657 KiB)
js/datatables-fca8769ee16df57bdc4a.js (296 KiB)
js/application-c4e0541a90e01b47fbfe.js.gz (305 KiB)
js/datatables-fca8769ee16df57bdc4a.js.map.gz (482 KiB)
js/chartkick-b109b176a3de896848c7.js.map.gz (493 KiB)
js/application-c4e0541a90e01b47fbfe.js.map.gz (1.09 MiB)
WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
Entrypoints:
application (1.21 MiB)
js/application-c4e0541a90e01b47fbfe.js
chartkick (657 KiB)
js/chartkick-b109b176a3de896848c7.js
datatables (296 KiB)
js/datatables-fca8769ee16df57bdc4a.js

WARNING in webpack performance recommendations: 
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/

我一直在研究懒惰加载,但找不到任何关于rails的信息(我对webpacker、js等都是新手(。例如,这个链接解释了拆分代码和延迟加载,但我不知道如何在我的超简单代码上调用它。

以下是我拥有的数据表代码示例:

//Global setting and initializer
// Add DataTables jQuery plugin
require('imports-loader?define=>false!datatables.net')(window, $)
require('imports-loader?define=>false!datatables.net-select')(window, $)
require('imports-loader?define=>false!datatables.net-bs4')(window, $)
require('imports-loader?define=>false!datatables.net-select-bs4')(window, $)
// Load datatables styles
import 'datatables.net-bs4/css/dataTables.bootstrap4.css'
import 'datatables.net-select-bs4/css/select.bootstrap4.css'
$(document).on('turbolinks:load', () => {
$(document.body).on('click', '#check_all', () => {
var checkBoxes = $('input[type="checkbox"]')
checkBoxes.prop("checked", !checkBoxes.prop("checked"))
})
})

// init on turbolinks load
$(document).on('turbolinks:load', function() {
if (!$.fn.DataTable.isDataTable(".datatable")) {
$(".datatable").DataTable();
}
});
// turbolinks cache fix
$(document).on('turbolinks:before-cache', function() {
var dataTable = $($.fn.dataTable.tables(true)).DataTable();
if (dataTable !== null) {
dataTable.destroy();
return dataTable = null;
}
});

我很想了解一下,它堵塞了我的应用程序,导致应用程序崩溃。谢谢

要添加动态导入,您可能需要对现有代码进行一些更改:

  1. 提取用于有条件初始化插件实例的函数
  2. 对每个数据表模块或导入这些模块的单独文件使用import().then()动态导入语句

提取初始值设定项函数

由于您将异步导入数据表,因此还不能指望它会被加载。这只是一个例子,但处理这一问题的一种方法是在任何您想进行数据表初始化的地方使用一个可重复使用的函数(也许还有另一个用于"缓存前"挂钩的函数(,如果数据表还没有加载,它将表现得很好。

function initializeDatatables() {
if (!$.fn.DataTable) return;
if (!$.fn.DataTable.isDataTable(".datatable")) {
$(".datatable").DataTable();
}
}

使用动态导入

由于您有四个单独的导入,您可以尝试将它们作为一个"块"从一个单独的文件导入:

// app/javascript/datatables.js
require('imports-loader?define=>false!datatables.net')(window, $)
require('imports-loader?define=>false!datatables.net-select')(window, $)
require('imports-loader?define=>false!datatables.net-bs4')(window, $)
require('imports-loader?define=>false!datatables.net-select-bs4')(window, $)
// your original initializer file
import('./datatables').then(initializeDatatables)
$(document).on('turbolinks:load', initializeDatatables);

您也可以尝试使用splitChunksAPI,这样Webpack就可以将JS放入单独的块中,但这是一个单独的主题。

最新更新