forked from Shopify/theme-check
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasset_size_javascript.rb
42 lines (38 loc) · 1.49 KB
/
asset_size_javascript.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# frozen_string_literal: true
module ThemeCheck
# Reports errors when trying to use too much JavaScript on page load
# Encourages the use of the Import on Interaction pattern [1].
# [1]: https://addyosmani.com/blog/import-on-interaction/
class AssetSizeJavaScript < HtmlCheck
include RegexHelpers
severity :error
category :html, :performance
doc docs_url(__FILE__)
attr_reader :threshold_in_bytes
def initialize(threshold_in_bytes: 10000)
@threshold_in_bytes = threshold_in_bytes
end
def on_script(node)
file_size = src_to_file_size(node.attributes['src'])
return if file_size.nil?
return if file_size <= threshold_in_bytes
add_offense(
"JavaScript on every page load exceeds compressed size threshold (#{threshold_in_bytes} Bytes), consider using the import on interaction pattern.",
node: node
)
end
def src_to_file_size(src)
# We're kind of intentionally only looking at {{ 'asset' | asset }} or full urls in here.
# More complicated liquid statements are not in scope.
if src =~ /^#{LIQUID_VARIABLE}$/o && src =~ /asset/ && src =~ Liquid::QuotedString
asset_id = Regexp.last_match(0).gsub(START_OR_END_QUOTE, "")
asset = @theme["assets/#{asset_id}"]
return unless asset.is_a?(AssetFile)
asset.gzipped_size
elsif src =~ %r{^(https?:)?//} && no_liquid?(src)
asset = RemoteAssetFile.from_src(src)
asset.gzipped_size
end
end
end
end