Heroku and Javascript

I have built a games website in Rails. Runs run on local system. But when deployed to Heroku the Javascript requests either run slow or freeze. Often the whole page freezes. I’m only using one Dyno as I’m still in the testing phase.

Heroku doesn’t have any suggestions to fix the problem

Slug size on Heroku is 36.5. MiB of 500 MiB

Cheers Dave

Anything in browser javascript console? Is anything not being served properly? And, dumb question time but we all have these kind of moments, did you remember to precompile, and are all your JS libraries set to have pointers to the compiled locations of assets?

Cheers,

Jess

Got some issues not sure how to fix.

My application.html.erb in Production on local system

Has the following code. Comes up with the error '(index):39 Uncaught ReferenceError: play is not defined at onload ((index):39)"

<%= full_title(yield(:title)) %>

<%= render ‘layouts/rails_default’ %>

<%= render ‘layouts/shim’ %>

<%= render ‘layouts/header’ %>

<% flash.each do |message_type, message| %>

<%= content_tag(:div, message, class: “alert alert-#{message_type}”) %>

<% end %>

<%= yield %>

<%= render ‘layouts/footer’ %>

<%= debug(params) if Rails.env.development? %>

Not sure how to fix that one?

In Heroku I get this error ‘GET https://morning-caverns-39088.herokuapp.com/assets/blackJack.js 404 (Not Found)’ which m,eans it can’t find the assets/blackJack.js file

My BlackJack.html,erb file is as follows

<h2>Playing Black Jack</h2>

<div id = "blackJackcontrols">

	<div class ="blackJackdealer"><button class = 'button' >Dealer</button></div>

	<div class = "blackJackplayer"><button class = 'button' >Player</button></div>

</div>

<div id = "blackJackcards">

	<div id="blackJackdealersCards">

		<span id = "BD0"></span>

		<span id = "BD1"></span>

		<span id = "BD2"></span>

		<span id = "BD3"></span>

		<span id = "BD4"></span>

		<span id = "BD5"></span>

		<span id = "BD6"></span>

		<span id = "BD7"></span>

	</div>

	<div id="blackJackplayersCards">

		<span id = "BP0"></span>

		<span id = "BP1"></span>

		<span id = "BP2"></span>

		<span id = "BP3"></span>

		<span id = "BP4"></span>

		<span id = "BP5"></span>

		<span id = "BP6"></span>

		<span id = "BP7"></span>

	</div>

</div>
<div class ="blackJackplayButton"><button  class = 'button'  onclick="blackJackplayAgain()">Play Again</button></div>

<div  id = "blackJackmoneyValue">Players Money is $5000</div>

<div id = "blackJackplayersReturn">Players Card Total is 0</div>

<div id = "blackJackmessagesValue">Messages</div>

<div class="blackJackbeat">

	<form name ="subscribe" id="subscribe_frm" action="#">

		<input  class = 'button'   type="button" id = "blackJackbeatenterBeat" name="submit" value="Enter Beat"  onclick="blackJackgetBeat()" />

		<input  type="text"  name="beat" id="blackJackbeatName" /> 

	</form>

</div>

<div class = "hitNoHit">

	<input  class = 'button' type="button" id = "hit" name="submit" value="Hit"  onclick="hit()" />

	<input  class = 'button'  type="button" id = "nohit" name="submit" value="No Hit"  onclick="noHit()" />

</div>

My assets.rb file in config/initializers looks like this

Be sure to restart your server when you modify this file.

Version of your assets, change this if you want to expire all your assets.

Rails.application.config.assets.version = ‘1.0’

Add additional assets to the asset load path.

Rails.application.config.assets.paths << Emoji.images_path

Add Yarn node_modules folder to the asset load path.

Rails.application.config.assets.paths << Rails.root.join(‘node_modules’)

Precompile additional assets.

application.js, application.css, and all non-JS/CSS in the app/assets

folder are already added.

Rails.application.config.assets.precompile += %w( admin.js admin.css )

Rails.application.config.assets.precompile += %w( game.scss )

Rails.application.config.assets.precompile += %w( blackJack.js )

Rails.application.config.assets.precompile += %w( poker.js )

Rails.application.config.assets.precompile += %w( yaghtzee.js )

Rails.application.config.assets.precompile += %w( mastermind.js )

My _rails_default.html.erb file in views/layouts looks like this

<%= csrf_meta_tags %>

<%= stylesheet_link_tag ‘application’, media: ‘all’,‘data-turbolinks-track’: ‘reload’ %>

<%= javascript_include_tag ‘application’, ‘data-turbolinks-track’: ‘reload’ %>

If you can find why the function play() can’t be seen and why the javascript files in Heroku can’t be find that would be great.

i put the links like for BlackJack.html,erb in BlackJack.html,erb because some function names were too similar causing issues.

Cheers Dave

The play() problem is resolved once I login and go to the Blackjack page.

The problem with Heroku not finding the javasripts pages is not resolved although this problem

doesn’t exist when running on the local system.

Cheers Dave

Got some issues not sure how to fix.

My application.html.erb in Production on local system

Has the following code. Comes up with the error '(index):39 Uncaught ReferenceError: play is not defined at onload ((index):39)"

<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <meta name="turbolinks-visit-control" content="reload">
    <%= render 'layouts/rails_default' %>

I am guessing that the partial in the line above this one is where the regular <%= javascript_include_tag :application %> would live?

    <%= render 'layouts/shim' %>
  </head>
  <body onload="play()">
    <%= render 'layouts/header' %>
    <div class="container">
      <% flash.each do |message_type, message| %>
        <%= content_tag(:div, message, class: "alert alert-#{message_type}") %>
      <% end %>
      <%= yield %>
      <%= render 'layouts/footer' %>
      <%= debug(params) if Rails.env.development? %>
    </div>
  </body>
</html>

Not sure how to fix that one?

In Heroku I get this error 'GET https://morning-caverns-39088.herokuapp.com/assets/blackJack.js 404 (Not Found)' which m,eans it can't find the assets/blackJack.js file

My BlackJack.html,erb file is as follows

<script type="text/javascript" src="assets/blackJack.js" ></script>

If you have put your scripts in the assets folder, then they have already been concatenated and minified into application.js. Loading a separate script here as a static html reference will fail in any normal Rails production environment. If you want to load it separately, you need to use the javascript_include_tag helper, which will also understand the fingerprint of the file (note that even in development, the URLs to individual resource files end with an MD5 hash of their contents, which is a cache-busting strategy. You don't need to know this directly, you would just use the helper and the correct link would be written out in the rendered HTML.

I recommend you read the Rails Guide about the Asset Pipeline, it covers this and lots more.

One thing I have noticed over the years is that when Rails makes something really difficult, it is often because doing things the easier way will lead you to a better design, or a better performing one. I have fought with the asset pipeline before, but I ended up writing better JS (namespaces, to avoid conflicts between modules) and then loading all of it at once, and letting Turbolinks handle the "go fast" part of the problem for me.

Walter

Thanks Walter for the help

Are you to give me an example of this please.
javascript_include_tag helper

Sure. In the main application.html.erb of your site, you should see this line somewhere in the <head>:

    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

If you don't, then that's because you moved it into a partial (called rails_defaults, maybe -- that's what I recall from your first post).

You can use any script name you like here, application is the default, where by convention, all of your other scripts are "rolled up". That's done by the file /app/javascripts/application.js, which culminates in the line

//= require tree .

which slurps up all the javascript files in the /app/assets/javascripts directory that are not already loaded by previous require directives in application.js, and concatenates them into the one published file.

A generic (rails new ...) generated site will have all of this done for you, so I recommend you try building a new stunt site from scratch and see what gets built for you. Try building a new app, then inside that, using the scaffold generator to make a couple or more models:

rails new test_blog
cd test_blog
rails g scaffold Post title body:text slug
rails g scaffold Author name email
rails g migration add_author_to_posts author:references

rake db:migrate
rails s

navigate to http://localhost:3000/posts

Everything you see will be run through the asset pipeline, although the full concatenation will not be there in development mode.

If you add some JS to the app/assets/javascripts/authors.js and posts.js, and refresh your browser, you should see those scripts appear in your browser's Developer tools when you inspect the DOM. In development, each file will be listed separately, as coming from /javascripts/posts-asdfsdfsdsdfsdafsdfsdafsd.js or similar (32 character hash, which is the MD5 of the file itself, is appended to the filename).

To see how this would work in production, you would first run:

rake db:create RAILS_ENV=production
rake db:migrate RAILS_ENV=production
rake assets:precompile RAILS_EN=production

and then when you started the dev server with the production version:

rails s production -p 3000

you would see all of the JS and CSS concatenated into application.js and application.css respectively. None of the individual files would appear at all. The whole thing will be minified and concatenated.

If you require some files in order in application.js, then only the files you don't require by name would be auto-loaded by the greedy require_tree operator. You might do this if you needed to specify that jQuery load before something else that needs it, for example. But otherwise, the files will be concatenated in alphabetical order and then minified and gzipped into one application-someMD5hashgoeshere.js file. The javascript_include_tag helper knows how to find that file and load it.

Walter

Thanks