This section will help new contributors to get an overview of the accessbility and performance guidelines laid out to ensure maintainability of the codebase.
Please have a look at this guide before opening pull requests to ensure that your changes promote accessibility and performance.
This section covers new changes and practices introduced in the codebase to support performance.
On linking scripts or stylesheets to html pages, make sure that you use the rails helper function javascript_include_tag
and stylesheet_include_tag
.
Before ading scripts/stylesheets, follow these guidelines:-
<%= stylesheet_link_tag "/lib/leaflet/dist/leaflet.css" %>
should be <%= stylesheet_link_tag "leaflet/dist/leaflet.css" %>
/lib
instead of adding cdn links.Lazyloading of images has been introduced [refer https://github.com/publiclab/plots2/pull/8043] using lazyload-rails gem.
To lazyload an image, follow the following steps-
image_tag
rails helper instead of an img
tag [refer https://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html].class:lazy
to this image.<script> $(function(){ $("img").lazyload(); }); </script>
This change only loads critical css (css applicable for the page) on page load and the rest is loaded asynchronously. You can refer https://github.com/publiclab/plots2/pull/7996 for the changes made. This is accomplished with the help of gems loadcss-rails
and critical-path-css-rails
and is only carried out for application.css
file.
The font awesome library is now pulled from the font-awesome-rails
gem [refer this pr https://github.com/publiclab/plots2/pull/7938]. This gem support Font Awesome version 4.7. Since some icons used by Leaflet Environmental Layers make use of FA version 5, hence an additional Font Awesome v5 has also been linked through cdn in file layouts/application.html.erb
.
Hence it is possible to add FA v4.7 or v5 icons as per your convenience. For FA v5 icons, make sure not to use the prefix fa
since it is used for FA v4.7. Instead stick to fas/far/fab
as per your requirement.
If the scripts you are adding are independent of other scripts and not required immediately on page load, adding defer/async tag to them can help improve performance.
JPEG 2000, JPEG XR, and WebP are image formats that have superior compression and quality characteristics compared to their older JPEG and PNG counterparts. Uploading and using images in these formats rather than JPEG or PNG means that they will load faster and consume less cellular data.
.length
aims to fetch all the entries of the db till the length is reached and then calculates the count. This leads us to unnecessarily fetching all the records.
Book.all.length
Book Load (1.3ms) SELECT "books".* FROM "books"
=> 100
books = Book.all
Book Load (1.3ms) SELECT "books".* FROM "books"
books.length
=> 100
While .count
only calculates the count but if the entries are already fetched then it still makes an extra query.
books = Book.all
Book Load (1.3ms) SELECT "books".* FROM "books"
books.count
(0.2ms) SELECT COUNT(*) FROM "books"
=> 100
So depending on whether our records have been fetched already we may decide which method to use over the other. The .size
method is a method that determines which method between count and length to execute. If we have already loaded the entries, it will use .length
. If we haven’t, it will use .count
. Size can therefore be used in most cases to save you having to worry about any of the performance considerations.
The minification of js is achieved by incorporating the Uglifier gem. This allows minification of js files that are a part of the asset pipeline.
When adding new javascript files that are not a part of the asset pipeline, but instead are a part of /lib it is recommended to add code in the production.rb file to minify these scripts. Here is an example of how this can be done:-
Uglifier.new(harmony: true).compile(File.read("public/lib/leaflet-environmental-layers/lib/glify.js"))`
We can then check if the file is getting minified or not by running to trigger compilation instead of fetching these scripts from the cache:
rake assets:precompile
And then subsequently running a Lighthouse plugin check on the given url to verify whether the script in question is included under the Minify Javascript section of suggestions flagged by Lighthouse.
This section covers new changes and practices introduced in the codebase to support accessibility.
When navigating to a button, descriptive text must be presented to screen reader users to indicate the function of the button.
If your button contains only an icon/image and no text, then to make it more accessible add an aria-label describing the action of the button. Also make sure that the action of the button described is not generic text such as "Click here" but something more meaningful such as "Submit note". The sample code is as follows:-
<button aria-label="More settings" type="button" class="btn btn-outline-secondary dropdown-toggle" id="pt-dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="border-color:#ccc;">
If a link contains no text, the function or purpose of the link will not be presented to the user. This can introduce confusion for keyboard and screen reader users.
If your link contains only an icon/image and no text, then to make it more accessible add an aria-label describing the target of the link. The sample code is as follows:-
<a aria-label="Add tags" id="tags-open" class="btn btn-circle btn-circle-sm" style="float:left;"><i class="fa fa-plus" style="color:#808080;"></i></a>
If a text label for a form control is visible, use the <label> element to associate it with its respective form control.
<label>Title <input class="form-control input-lg" type="text" id="title-input"/> </label>
If there is no visible label, either provide an associated label by creating the label tag before and referencing the input element id in the 'for' attribute of the label. The sample code is as follows:-
<label for="title-input"></label> <input class="form-control input-lg" type="text" id="title-input"/>
You may also add a descriptive title attribute to the form control, or reference the label(s) using aria-labelledby.
<input aria-label="Enter Note Title" class="form-control input-lg" type="text" id="title-input" />
Labels are not required for image, submit, reset, button, or hidden form controls.
Links, which are often read out of context, should clearly describe the destination or function of the link. Ambiguous text, text that does not make sense out of context, and extraneous text (such as "click here") can cause confusion and should be avoided.
Where appropriate, reword the link text so that it is more descriptive of its destination when read out of context. Remove any extraneous text (such as "click here").
Tabindex values of 1 or greater specify an explicit tab/navigation order for page elements. Because it modifies the default tab order, cause confusion, and result in decreased keyboard accessibility, it should be avoided.
If the natural tab order is already logical, remove the tabindex. Otherwise, consider restructuring the page so that tabindex is not needed. If tabindex is maintained, ensure that the resulting navigation is logical and complete.
Headings provide document structure and facilitate keyboard navigation by users of assistive technology. These users may be confused or experience difficulty navigating when heading levels are skipped. For example - an <h1>
is followed by an <h3>
, with no intermediate <h2>
Restructure the document headings to ensure that heading levels are not skipped.
Each image must have an alt attribute. Without alternative text, the content of an image will not be available to screen reader users or when the image is unavailable.
Add an alt attribute to the image.If the content of the image is conveyed in the context or surroundings of the image, or if the image does not convey content or have a function, it should be given empty/null alternative text (alt="").The sample code is given as below:-
Underlines almost universally indicates linked text. Consider removing the underline from the non-link text. Other styling (e.g., bold or italics) can be used to differentiate the text.
Unless there is a distinct need for the underlined text, remove the underline from it.