apache / incubator-pagespeed-mod

Apache module for rewriting web pages to reduce latency and bandwidth.
http://modpagespeed.com
Apache License 2.0
696 stars 157 forks source link

TypeError: pagespeed.CriticalImages is undefined #1977

Open MrTschi opened 4 years ago

MrTschi commented 4 years ago

Hi

I'm using Pagespeed with Apache and the users are facing the following issues:

TypeError
pagespeed.CriticalImages is undefined
ReferenceError
Can't find variable: pagespeed
ReferenceError
pagespeed is not defined
TypeError
undefined is not an object (evaluating 'pagespeed.CriticalImages.checkImageForCriticality')

Pagespeed config:

    ModPagespeedEnableFilters insert_dns_prefetch

    ModPagespeedInPlaceResourceOptimization on
    ModPagespeedFetchHttps enable
    ModPagespeedEnableFilters make_google_analytics_async,inline_google_font_css
    ModPagespeedEnableFilters extend_cache,hint_preload_subresources

    ModPagespeedUrlValuedAttribute source srcset image
    ModPagespeedEnableFilters responsive_images,resize_rendered_image_dimensions
    ModPagespeedEnableFilters convert_jpeg_to_webp,convert_gif_to_png,convert_png_to_jpeg
    ModPagespeedEnableFilters recompress_webp
    ModPagespeedEnableFilters lazyload_images
    ModPagespeedImageMaxRewritesAtOnce -1

    ModPagespeedEnableFilters combine_javascript

    ModPagespeedEnableFilters prioritize_critical_css,flatten_css_imports

    ModPagespeedEnableFilters rewrite_style_attributes_with_url,rewrite_css,rewrite_images
    AddOutputFilterByType MOD_PAGESPEED_OUTPUT_FILTER application/xhtml+xml

I was not able to reproduce this, I saw the errors in Sentry (JS frontend error tracking).

URL of website: living-zone . de

Any ideas on what causes this issue?

MrTschi commented 4 years ago

I noticed that the generated pagespeed js may could not be loaded:

https://www . living-zone . de/test/web/cache/1580125657_07a028548649f73a1879a08b83ed2f3b.js.pagespeed.jm.nQcrB2CxD9.js

-> 404

This causes pagespeed to not be able to inject the pagespeed JS. But how to fix this?

Lofesa commented 4 years ago

Hi @MrTschi I can´t see any error. Js files from your domain are rewited and loaded. The only issue I can see in your page is related to images in picture elements, but it´s as spected cause pagespeed don´t recognize picture elements, so these images are not rewrited.

tempsnip

MrTschi commented 4 years ago

@Lofesa thanks for your reply. I saw this issue appear in my browser randomly. Browser console states, that the resource (js or css) generated by pagespeed could not be loaded (404). In case of JS, the "pagespeed is not defined" also appears in this case. After reloading the page, the issue is gone without changing anything (neither on client nor on server side).

I also noticed that the browser request to generated pagespeed css failed (404), but requesting it manually works. Could it be a timing issue so that the file is not yet fully generated by pagespeed when the browser is going to request it?

GTMetrix shows up that the CSS+JS is both loaded twice (original one + pagespeed generated one) resulting in a bad pagespeed score. I couldn't reproduce this behavior in my browser but maybe this is related?

Occurs at a wide number of devices and browsers, but ONLY at the main home page (url 98% at "/", 2% at test system home "/test/"): image

~5k log events per day, last 24h: image

Lofesa commented 4 years ago

Hi @MrTschi Some things: 1.- When pagespeed is off (url/?PageSpeed=off) the main page have cache-control= no-cache,private. Pagespeed need that pages and resources are public cacheable. 2.- Your page don´t show main elements w/o javascript enabled and don´t have an alternative to those main elements, so you don´t need to enable the support noscript filter. Put pagespeed SupportNoScriptEnabled false; in your config. 3.- You serve only 1 css file from your domain, so don´t need the combine css filter: pagespeed DisableFilters combine_css; Same with javascript files: pagespeed DisableFilters comine_js; 4.- You have enabled the inline css and js filters , but had no changed the default max size to inline files, so 2 things: a) disable the inline filters pagespeed DisableFilters inline_css; pagespeed DisableFilters nline_javascript; b) make the size of max inline filter grether than the default: pagespeed CssInlineMaxBytes bytes; pagespeed JsInlineMaxBytes bytes; 5.- To inline the google fonts css you need: a) auth the domain pagespeed Domain https://fonts.googleapis.com; b) Make the CssInlineMaxBytes bigger that the amount of these css 6.- The filter dns-prefecht make the dns resolution faster but then need to connect to the domain. Consider to disable this filter and put a link rel="preconnect" in your pages. 7.- You have enabled the inline_images, so you need to set an apropiate: a) pagespeed MinImageSizeLowResolutionBytes MinBytes; minimun size of images to inline b) pagespeed EnableFilters insert_image_dimensions; 8.- You use the make_google_analytics_async filter, I think this not needed as far as these js snipets have changed to work async and you load the analytics.js from google tags. 9.- You use the hint_preload_subresources filter. Don´t use it. Had an inestable behaviuor, some times insert the rigth header, some times not, some times inser the rewrited and the no rewrited resource.... This filter is the responsible of the issue you view in Gmetrix to load the css and js files 2 times, 1 rewrited and 1 not rewrited, and in a inestable way, some times yes , some not. You don´t see it in the html code cause it work on the http headers. In the image bellow I show where the filter works, in this case it show the rigth items.

Captura

10.- I see the url changes from www to the non-www in the url bar. Maybe is a javascript that changes the url? I don´t see any redirect. For prevent any issues with the authorized domain you can set this: pagespeed Domain http*://*.living-zone.de; This makes pagespeed work with http/https and any subdomain (www/non-www).

Try these changes and see if this a better experience. P.D. Sorry for my bad english, sure I have mistakes......

MrTschi commented 4 years ago

@Lofesa wow thank you for this huge and great analysis!! First, I removed the hint_preload_subresources to get the JS-Issues solved (I'll fix the other things later). But they still persist. I found in the HTML the following HTML-Comment after the original (non-pagespeed) js-script inclusion tag:

<!--deadline_exceeded for filter CacheExtender--><!--deadline_exceeded--><!--deadline_exceeded for filter JavascriptFilter-->

In this case, pagespeed should not inject additional pagespeed-js to the html DOM which then causes the "pagespeed is undefined" But why is this timeouting?

Lofesa commented 4 years ago

@MrTschi These hints are stored in the pagespeed cache (one of the problems is that never get renewed and thus disappear) so until they get stored in the cache.... These deadline are the time pagespeed try to optimize 1 resource, by default 10 ms. You can try

pagespeed RewriteDeadlinePerFlushMs Ms;
pagespeed InPlaceRewriteDeadlineMs Ms;

And for pagespeed not defined, maybe is as you say. I think is related to lazyload images,, pagespeed inject js code for that, and if not injected, the snuppet in each image fail. Your page is heavy, 120 request, 6Mb. with a lot of external resources maybe pagespeed need time to process all this stuff. Pagespeed works hiting the page, if the page don´t have a lot of hits take time to populate their cache. Maybe disbling filters you don´t need.... I forgot a point: 11.- You use inline_css and prioritize critical css, this second filter disables the inline, so you don´t need it, but if still want to inline google fonts css, still need to set the CssInlineMaxBytes.

Ah! Take a look in the hreflang stuff, when I use url parameters. like ?PageSpeedFilters=+debug, the parameters get converted in paths, like https://www.living-zone.de/index/index/PageSpeedFilters/+debug and this maybe indexed by google.