ctrager/budoco

Move scripts from <head> to the end of <body>

Opened this issue · 22 comments

Page loading enhancement.

I had a javascript issue - I don't remember what it was - and moving the scripts away from body to head helped solve the problem, maybe. I don't remember well. Maybe it was just something I tried that didn't actually help. And it wasn't so much maybe where they were but that the the layout renders the scripts async, so maybe there was a race condition. So, this optimization might be nice, but I doubt whether it actually would make a difference perceptible to a human.

Playing with the app on budoco.net, it's very fast. My experience tells me that the most important speed optimization is to reduce the number of trips between web server and postgres, even if they are on the same machine. Right now, it's very chatty between them. So, for example, just bringing up the create issue form, empty:

SQL 1:/check_user_permissions/ select * from sessions
inner join users on se_user = us_id
where se_id = '46db6f69-dad5-49de-b9d3-c4e15d4724f4'; /*check_user_permissions */
SQL 2:select og_id, og_name from organizations where og_is_active = true union select 0, '[None]' order by og_name
SQL 3:select us_id, us_username from users where us_is_active = true order by us_username
SQL 4:select c1_id, c1_name from custom_1 where c1_is_active = true order by c1_name
SQL 5:select c2_id, c2_name from custom_2 where c2_is_active = true order by c2_name
SQL 6:select c4_id, c4_name from custom_4 where c4_is_active = true order by c4_name
SQL 7:select og_id, og_name from organizations where og_is_default is true order by og_name limit 1
SQL 8:select c1_id from custom_1 where c1_is_default is true order by c1_name limit 1
SQL 9:select c2_id from custom_2 where c2_is_default is true order by c2_name limit 1
SQL 10:select c4_id from custom_4 where c4_is_default is true order by c4_name limit 1
layout_si

The contents of the dropdowns only change if an admin changes them, so they could all be cached at Startup and then we'd make the cache dirty whenever admin updates them, which is almost never.

SQL 1:select i_organization from issues where i_id = 4030
SQL 2:select posts.*, us_username
from posts
inner join users on us_id = p_created_by_user
where p_issue = 4030 order by p_id asc
SQL 3:select pa_id, pa_file_name, pa_file_length, pa_file_content_type
from post_attachments
where pa_post = 48 order by pa_id asc
SQL 4:select pa_id, pa_file_name, pa_file_length, pa_file_content_type
from post_attachments
where pa_post = 49 order by pa_id asc
SQL 5:select pa_id, pa_file_name, pa_file_length, pa_file_content_type
from post_attachments
where pa_post = 50 order by pa_id asc

Here's getting the posts of an issue that has three posts. N+1 problem here. Instead of fetching attachments three times should do it once.

For js. Using the method after loading the page.
Otherwise, it is possible that the script has not yet loaded.

$(function() {
   // method call
});

SQL 1:select i_organization from issues where i_id = 4030
SQL 2:select posts.*, us_username
from posts
inner join users on us_id = p_created_by_user
where p_issue = 4030 order by p_id asc
SQL 3:select pa_id, pa_file_name, pa_file_length, pa_file_content_type
from post_attachments
where pa_post = 48 order by pa_id asc
SQL 4:select pa_id, pa_file_name, pa_file_length, pa_file_content_type
from post_attachments
where pa_post = 49 order by pa_id asc
SQL 5:select pa_id, pa_file_name, pa_file_length, pa_file_content_type
from post_attachments
where pa_post = 50 order by pa_id asc

select
    posts.*,
    users.us_username,
    post_attachments.pa_id,
    post_attachments.pa_file_name,
    post_attachments.pa_file_length,
    post_attachments.pa_file_content_type
from
    posts
    
    inner join users
    on users.us_id = posts.p_created_by_user
    
    left join post_attachments
    on post_attachments.pa_post = posts.p_id
where
    p_issue = 4030
order by
    p_id asc

Something like that?

A DataSet can also contain multiple tables.

If you were working with BugTracker.NET source code, then you must know that I know all this stuff.

Most likely I don't quite understand the question.

I don't remember asking a question. I don't have a question.

SQL 1:/check_user_permissions/ select * from sessions
inner join users on se_user = us_id
where se_id = '46db6f69-dad5-49de-b9d3-c4e15d4724f4'; /*check_user_permissions */
SQL 2:select og_id, og_name from organizations where og_is_active = true union select 0, '[None]' order by og_name
SQL 3:select us_id, us_username from users where us_is_active = true order by us_username
SQL 4:select c1_id, c1_name from custom_1 where c1_is_active = true order by c1_name
SQL 5:select c2_id, c2_name from custom_2 where c2_is_active = true order by c2_name
SQL 6:select c4_id, c4_name from custom_4 where c4_is_active = true order by c4_name
SQL 7:select og_id, og_name from organizations where og_is_default is true order by og_name limit 1
SQL 8:select c1_id from custom_1 where c1_is_default is true order by c1_name limit 1
SQL 9:select c2_id from custom_2 where c2_is_default is true order by c2_name limit 1
SQL 10:select c4_id from custom_4 where c4_is_default is true order by c4_name limit 1
layout_si

The contents of the dropdowns only change if an admin changes them, so they could all be cached at Startup and then we'd make the cache dirty whenever admin updates them, which is almost never.

https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.caching.memory.imemorycache?view=dotnet-plat-ext-5.0

I don't remember asking a question. I don't have a question.

The question is in its broad sense. No question mark after a sentence. The question may be even if it was not asked. ;)

Sorry. I am not a native speaker, so I cannot accurately convey the idea.

done

Something exciting happened. I now see the error I had that made me move the scripts into .

Try the "Go To Issue" button.

moved the js that was in head to bottom of body and it works. I guess I don't understand $(document).ready...

moved the js that was in head to bottom of body and it works. I guess I don't understand $(document).ready...

$( document ).ready() will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute.
Code included inside $( window ).on( "load", function() { ... }) will run once the entire page (images or iframes), not just the DOM, is ready.
https://learn.jquery.com/using-jquery-core/document-ready/

image

Using before jquery is loaded.

Actually, my comment was stupid. I do know what document ready does. I shouldn't have said that. Here's what I should have talked about: https://stackoverflow.com/questions/1795438/load-and-execution-sequence-of-a-web-page

So, in the past, I had always put libraries and my own <script> tags in head, and never had a problem. You convinced me it's better to put them at the bottom of body, but I guess that means I also need to put <script> in body following <script src=>.

The error I had was that jquery itself hadn't been loaded when my head was calling $(). I think I got it now.

Was my change the correct fix?

Yes. Libs then general scripts then specific scripts.

And then "Scripts" section.