You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 7 JS/CSS加载延迟及remote:true失效问题求助

问题

之前仅开发过Rails <=5版本,现在开发Rails 7应用时遇到以下资产加载异常:

  • 资产应用有明显延迟:带有remote:true的link_to,页面重载后过早点击会变成普通链接,发送HTML请求而非JS请求
  • CSS加载存在可见延迟,页面先显示无样式状态0.5-1秒后才加载样式
  • 图片渲染缓慢,怀疑是图片分辨率过高导致
  • 对Rails 7新JS方案不熟悉,疑惑为何延迟会影响remote:true选项

相关配置代码

importmap.rb

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin "jquery", to: "jquery.min.js", preload: true
pin "jquery_ujs", to: "jquery_ujs.js", preload: true
pin "bootstrap", to: "https://ga.jspm.io/npm:bootstrap@5.2.1/dist/js/bootstrap.esm.js"
pin "@popperjs/core", to: "https://ga.jspm.io/npm:@popperjs/core@2.11.6/lib/index.js"
pin "chosen-jquery", to: "chosen-jquery"
pin "flatpickr", to: "flatpickr"

pin_all_from "app/javascript/custom", under: "custom"

application.js

import "@hotwired/turbo-rails"
import "controllers"
import "jquery"
import "jquery_ujs"
import 'bootstrap'
import 'chosen-jquery'
import 'flatpickr'

import "custom/choosen"
import "custom/datepicker"
import "custom/login_banner"
import "custom/mobile_menu"
import "custom/forms"

自定义JS示例(custom/forms.js)

window.form_small_img_display = function() {
  $("#user_avatar").change(function(){
    const [file] = this.files
    if (file) {
      $(this).closest(".form-img-display-js").find("img.small-form-img-js").attr("src", URL.createObjectURL(file))
      // $("img.small-form-avatar").attr("src", URL.createObjectURL(file))
    }
  })
};

window.close_inline_form = function(){
  $("close-inline-form-js > a").on("click", function(e){
    e.preventDefault();

    $("inline-expedition-logs-form").html("");
  })

  $("close-inline-update-form-js > a").on("click", function(e){
    e.preventDefault();

    parent = $($(this).data('id')).parent();
    $($(this).data('id')).remove();
    parent.prepend($(this).data('partial'))

  })
}

$(document).on('turbo:load', window.form_small_img_display);
$(document).on('turbo:load', window.close_inline_form);

manifest.js

//= link_tree ../images
//= link_directory ../stylesheets .css
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js
//= link chosen-jquery.js
//= link flatpickr

解决方案

1. 修复remote:true过早点击失效问题

Rails 7默认启用Turbo,jquery_ujs与Turbo在事件处理上存在冲突,且JS加载顺序错误会导致ujs未初始化就触发链接点击:

  • 调整JS加载顺序:在application.js中将jquery_ujs移到@hotwired/turbo-rails之前导入,避免Turbo先接管事件:
    import "jquery"
    import "jquery_ujs"
    import "@hotwired/turbo-rails" // 移至jquery_ujs之后
    import "controllers"
    // 其余导入保持不变
    
  • 禁用Turbo对特定链接的接管:给remote:true的链接添加data-turbo="false"属性,确保ujs正常拦截请求:
    <%= link_to "远程操作", some_path, remote: true, data: { turbo: false } %>
    
  • 确保初始化时机正确:保持自定义JS绑定在turbo:load事件上,等待ujs完成初始化后再绑定交互逻辑。

2. 解决CSS加载延迟(FOUC问题)

  • 预加载CSS:在application.html.erb的<head>中给CSS链接添加preload属性,优先加载样式:
    <%= stylesheet_link_tag "application", "data-turbo-track": "reload", rel: "preload", as: "style" %>
    
  • 内联关键CSS:将首屏必需的CSS直接内联到<head>中,避免等待外部CSS文件加载完成。
  • 检查manifest配置:确认//= link_directory ../stylesheets .css正确包含所有CSS文件,无遗漏导致额外请求。

3. 优化图片加载速度

  • 压缩图片分辨率:用ImageOptim、Squoosh等工具将图片压缩至网页适配尺寸(如首屏图片宽度不超1920px),质量调至80%左右平衡画质与大小。
  • 使用响应式图片:通过Railsimage_tag生成srcset和sizes属性,让浏览器按需加载合适尺寸的图片:
    <%= image_tag "example.jpg", srcset: { "example_480w.jpg" => "480w", "example_800w.jpg" => "800w" }, sizes: "(max-width: 600px) 480px, 800px" %>
    
  • 启用懒加载:给非首屏图片添加loading="lazy"属性,延迟加载:
    <%= image_tag "lazy-image.jpg", loading: "lazy" %>
    
  • 验证资产管道配置:确保manifest.js中//= link_tree ../images正确配置,图片已被指纹化并缓存。

4. Rails 7 JS方案适配建议

  • 明确Turbo与jquery_ujs分工:Turbo是Rails 7默认JS框架,若继续使用jquery_ujs,要么禁用Turbo对特定元素的处理,要么逐步迁移到Turbo方案(如用data-turbo-method替代remote:true,用Turbo Streams处理异步更新)。
  • 本地化JS库:将jquery、jquery_ujs等常用库下载到vendor/javascript目录,修改importmap.rb指向本地文件,避免CDN加载延迟:
    pin "jquery", to: "jquery.min.js", preload: true # 确保文件在vendor/javascript下
    pin "jquery_ujs", to: "jquery_ujs.js", preload: true
    
  • 保持关键JS预加载:保留importmap.rb中关键库的preload: true配置,让浏览器提前加载资源,减少初始化等待时间。

内容的提问来源于stack exchange,提问作者jakub_pietrzyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 15:01:10