Saturday, May 11, 2024
119
rated 0 times [  124] [ 5]  / answers: 1 / hits: 17021  / 8 Years ago, sat, may 21, 2016, 12:00:00

I have a WYSIWYG editor that I have built into the site and customised. There are a lot of Javascript files that only need to be loaded on the pages with the WYSIWYG editor; currently they are loaded on every page (and even break other Javascript on certain pages).



Currently the Javascript files are in assets/javascript/wysiwyg/ and aren't included as the require files in application.js but are still included on every page because of the assets pipeline (I think).



I want to know if I can exclude these files from the other pages. Is it possible to move them from the assets pipeline to the public/ directory and import them (in the coffee script files, maybe?) into the appropriate views?


More From » ruby-on-rails

 Answers
45

You can put any Javascript files that you want to load manually in the public/javascripts/lib directory of your application, and they will not be included in the assets pipeline. You can then load them manually on the pages that need them.



For instance, in one project, I use the Chosen jQuery plugin, and I load it like so:



<script type=text/javascript src=/javascripts/lib/chosen.jquery.min.js></script>


Rails will source the public files from public/, so you only need to reference your files from there (remove the public/ bit).



This project is fairly large, with 88 controllers, 662 actions, and a total of 38 custom javascript libraries that get used sporadically around the app, including markdown editors, charting libraries, and even jQuery UI.



To manage the sprawl and to keep each page as tight as possible, I have done 2 things: 1) in my controller, I set an instance variable,@page_libs, to list the libs to load, and 2) the layout uses the values in @page_libs to include the specialty Javascript when required.



A controller action might look like this:



def edit
@products = products.find(params[:id])
@page_libs = [:ui, :textile]
end


And the app/views/layouts/application.html.erb includes this in the correct place:



<%- if @page_libs&.include?(:ui) || @page_libs&.include?(:table) %>
<script type=text/javascript src=//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js></script>
<script type=text/javascript src=/javascripts/lib/chosen.jquery.min.js></script>
<% end -%>
<%- if @page_libs&.include?(:swiper) %>
<script type=text/javascript src=/javascripts/lib/idangerous.swiper.min.js></script>
<% end -%>
<%- if @page_libs&.include?(:table) %>
<script type=text/javascript src=/javascripts/lib/jquery.handsontable.full.js></script>
<% end -%>
<%- if @page_libs&.include?(:textile) %>
<script type=text/javascript src=/javascripts/lib/textile.js charset=utf-8></script>
<% end -%>


Note that the first include is for jQuery UI, which I load from a CDN, rather than from my app's public. This technique works just as well with external libraries, as well as those that you host. In fact, most pages in my app only depend on 2 external libraries (jQuery and Underscore.js), but have the option of loading up to 16 other Javascript libraries from external sources. Limiting external libraries on the page can significantly reduce your page load times, which is a direct performance boost for your application.



Sometimes, a Javascript library will include CSS components, as well. Or, you may even have page-specific CSS to include. The same approach can be taken with external stylesheet. These are the corresponding page-specific stylesheet includes for the above Javascript libraries:



<%- if @page_libs&.include?(:ui) %>
<link rel=stylesheet type=text/css href=//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css>
<link rel=stylesheet type=text/css href=/stylesheets/lib/chosen.min.css>
<% end -%>
<%- if @page_libs&.include?(:swiper) %>
<link rel=stylesheet type=text/css href=/stylesheets/lib/idangerous.swiper.css>
<% end -%>


This way, I have a single point in the project to manage the libraries, regardless of how many (or few) are required for a page. I'll probably eventually create a series of custom before_action handlers in the ApplicationController to define which the libraries a page needs included. Something like this:



before_action: :include_library_ui,     only: [:new, :edit]
before_action: :include_library_swiper, only: [:show]


This would clean up the controller actions a bit more and make it easier to identify dependencies. However, given the size of my codebase and the pressing tasks remaining, I haven't taken this leap yet. Maybe it will inspire you to do so to start out.


[#62082] Thursday, May 19, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
billt

Total Points: 608
Total Questions: 100
Total Answers: 87

Location: Cape Verde
Member since Fri, Nov 27, 2020
4 Years ago
;