From 8da16468ffadda412e699c52250b71a1e79df5a9 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Thu, 16 Apr 2020 13:21:24 +0100 Subject: [PATCH] Delay the initial AJAX call by 2 seconds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At the moment the first AJAX call is triggered as soon as the page loads. We then look at its response time to work out how long to wait until making the next call. This isn’t great because: - stuff is unlikely to have changed straight away, so it’s a waste of a call - while the DOM is being updated it seems to introduce a delay in clicks on links, which is either more pronounced or more noticeable when it’s happening straight away, making the UI feel less snappy I chose a value of 2 seconds as a rough proxy for the minimum time we’d expect to see a notification go from created to delivered. Median time-to-delivered was 2.9 seconds when we analysed it for https://github.com/alphagov/notifications-admin/pull/2974#discussion_r286101286 --- app/assets/javascripts/updateContent.js | 14 +++++++++----- tests/javascripts/updateContent.test.js | 14 +++++++++++++- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/updateContent.js b/app/assets/javascripts/updateContent.js index f519a0f63..b607e77df 100644 --- a/app/assets/javascripts/updateContent.js +++ b/app/assets/javascripts/updateContent.js @@ -3,6 +3,7 @@ var queues = {}; var dd = new global.diffDOM(); + var defaultInterval = 2000; var interval = 0; var calculateBackoff = responseTime => parseInt(Math.max( @@ -54,11 +55,14 @@ global.GOVUK.Modules.UpdateContent = function() { - this.start = component => poll( - getRenderer($(component)), - $(component).data('resource'), - getQueue($(component).data('resource')), - $(component).data('form') + this.start = component => setTimeout( + () => poll( + getRenderer($(component)), + $(component).data('resource'), + getQueue($(component).data('resource')), + $(component).data('form') + ), + defaultInterval ); }; diff --git a/tests/javascripts/updateContent.test.js b/tests/javascripts/updateContent.test.js index bd1c92abb..2d5a36c66 100644 --- a/tests/javascripts/updateContent.test.js +++ b/tests/javascripts/updateContent.test.js @@ -110,6 +110,7 @@ describe('Update content', () => { // start the module window.GOVUK.modules.start(); + jest.advanceTimersByTime(2000); expect($.ajax.mock.calls[0][0]).toEqual(resourceURL); @@ -122,6 +123,7 @@ describe('Update content', () => { // start the module window.GOVUK.modules.start(); + jest.advanceTimersByTime(2000); // check the right DOM node is updated expect(document.querySelectorAll('.big-number-number')[0].textContent.trim()).toEqual("0"); @@ -135,6 +137,7 @@ describe('Update content', () => { // start the module window.GOVUK.modules.start(); + jest.advanceTimersByTime(2000); // check the right DOM node is updated expect(document.querySelectorAll('.big-number-number')[0].textContent.trim()).toEqual("1"); @@ -152,19 +155,26 @@ describe('Update content', () => { test("It should use the GET HTTP method", () => { + jest.advanceTimersByTime(2000); expect($.ajax.mock.calls[0][1].method).toEqual('get'); }); test("It shouldn't send any data as part of the requests", () => { + jest.advanceTimersByTime(2000); expect($.ajax.mock.calls[0][1].data).toEqual({}); }); test("It should request updates with a dynamic interval", () => { - // First call happens straight away + // First call doesn’t happen in the first 2000ms + jest.advanceTimersByTime(1999); + expect($.ajax).toHaveBeenCalledTimes(0); + + // But it happens after 2000ms by default + jest.advanceTimersByTime(1); expect($.ajax).toHaveBeenCalledTimes(1); // It took the server 1000ms to respond to the first call so we @@ -213,12 +223,14 @@ describe('Update content', () => { test("requests should use the same HTTP method as the form", () => { + jest.advanceTimersByTime(2000); expect($.ajax.mock.calls[0][1].method).toEqual('post'); }) test("requests should use the data from the form", () => { + jest.advanceTimersByTime(2000); expect($.ajax.mock.calls[0][1].data).toEqual(helpers.getFormDataFromPairs([ ['serviceName', 'Buckhurst surgery'], ['serviceNumber', serviceNumber]