reduce nuxt project loading time - vue.js

So i have a nuxt app with vue2 and i'm using json-server for a local database and axios to fetch data.
When I run "npm run dev" the compilation (server and client) takes around 10 seconds but the application takes forever to render.I checked the network tab and I think it probably has something to do with the get request
GET /tests 200 32.933 ms - 604001
GET /tests 304 22.315 ms - -
GET /results 304 3.781 ms - -
Any idea how i can improve the performance on how i fetch the data from the server ?
here s how im using axios right now
data() {
return {
search: '',
tests :[]
}
async created() {
try {
const res = await axios.get(`http://localhost:3004/tests`)
this.tests=res.data;
}catch (error){
console.log(error);
}
}

Related

Duplicated requests to same url with fetch using vue and webpack

I have weird results displayed in the web console:
fetch() is sending duplicated requests to the same url.
I thought it could be something related to fetch(), but also noticed that on reload of the app (quasar, based on webpack) also the requests to the http://localhost:8080/sockjs-node/info are duplicated.
By contrast, I noticed that requests handled by jQuery are NOT duplicated and works fine.
I cannot say if it is an error due to webpack configuration, fetch or they way I am using it i Vue components.
E.g. This article points out possible causes https://insights.daffodilsw.com/blog/how-to-avoid-duplicate-api-requests but in my case it is not due to user interaction : requests are triggered at time of relaunching the app (webpack), and particularly the stack trace shows that the requests are fired at time of creating the components, just multiple times.
Example of how I am using fetch():
// component -
methods : {
search(input) {
return new Promise(resolve => { // a new promise is request multiple times, in spite in created() it is called just once
var _base = 'myEndpoint/api'
const url = `${_base}fuzzyautocomplete?q=${encodeURI(input)}`
if (input.length < 3) {
return resolve([])
}
fetch(url) // so promises are actually different, and duplicated requests are fired by fetch
.then(response => response.json())
.then(data => {
console.log(data)
// resolve(data.query.search)
resolve(data)
})
})
},
....
// and it should be called just once at time of creation
created() {
this.search('init first query !!');
}
Could you advise?

Let Puppeteer wait for globalSetup to finish

I use Jest-Puppeteer to end2end test a webapplication. All tests run parallel with async functions. Now I find that the first test already runs before the globalSetup has finished and the data preperation is done (initializing client-settings etc.)
I've tried to timeout after the request, but that isn't working because now all requests have a timeout.
import puppeteer from "puppeteer";
import { getUrlByPath, post } from "../helper";
module.exports = async function globalSetup(globalConfig) {
await setupPuppeteer(globalConfig);
puppeteer.launch({args: ["--no-sandbox", "--disable-setuid-sandbox"]}).then(async browser => {
const page = await browser.newPage();
await post(
page,
getUrlByPath("somePath"),
"prepare_data_for_testing",
);
await browser.close();
});
};
Above code runs a globalConfig, after that it starts preparing the data for the testing environment.
Is there a way to make the test suites run AFTER this script returns the post with http 200: ok ?
I had to place await before puppeteer.launch and add require("expect-puppeteer"); at the top.

Can't get fetch(url) working in React-Native

I am trying to retrieve the json response from api url using fetch (method : GET) in react-native.
constructor(props){
super(props);
this.state = {jsonData: {}};
}
componentWillMount() {
console.log("inside componentWillMount");
fetch('http://localhost:3000/listData')
.then((response) => {console.log('response: '); return response.json();})
.then((responseJson) => {console.log('responseData: '+JSON.stringify(responseJson)); return this.setState({jsonData: responseJson});})
.catch((err) => {console.log(err)});
}
The api returns data in this format:
{
object: 'list',
data: [...]
}
The api url works via curl. I also tried to run the fetch part of the code standalone using node by installing node-fetch and it printed the responseData properly.
But, in react-native, it doesn't print any of the console log statements inside the then function of fetch nor does it set the state of jsonData.
Could you please tell me what could be the problem? I have been googling around for quite a long time trying to find what could be the issue.
EDIT
I tried the async fetch as follows:
componentWillMount() {
console.log("inside componentWillMount");
this.fetchData().done();
}
async fetchData(){
const response = await fetch('http://localhost:3000/listData')
const json = await response.json();
const data = json.url;
console.log('data'+url);
}
Still, the same issue persists.
I am not able to understand why it works with the facebook url and not my local api url
SOLUTION
Thanks to Michael Cheng for pointing me in the right direction.
I found this link :
https://github.com/react-community/create-react-native-app/issues/154 .
Code Fix:
I just replaced the localhost with my ipv4 address as http://myserveripv4address:3000/listData and it worked.
Version:
react-native#0.50.4
Device : Android
some ideas:
if is iOS, you need the remote url to be https or disable this security feature;
You may need to mark your fetch() as async function;
Try to make an async fetch w/o promise.

Workbox - runtime cache only created on second page refresh

I'm new to service workers, and I'm using Workbox to precache my app shell and cache my api data.
The precaching of assets is working correctly, with the cache being created and populated.
The runtime caching isn't creating a cache and populating it until I reload the page a second time.
I thought this might be a timing issue, so I set a page reload of the data in the javascript, however this still didn't cache the call.
I'm not doing anything specific to create the cache, app code is:
...
app.getData = function() {
var requestHeaders = new Headers({
Accept: "application/json"
});
fetch(app.dataUrl, { headers: requestHeaders })
.then(function(response) {
return response.json();
})
.then(function(json) {
app.updateCards(json);
})
.catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
});
}
...
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/my_sw.js')
.then(function() {
console.log('Service Worker Registered');
});
}
app.getData(); # fetch api data
then in the service worker:
...
const workboxSW = new self.WorkboxSW({clientsClaim: true});
// register data url to cache
workboxSW.router.registerRoute(
'/my_api/data',
workboxSW.strategies.staleWhileRevalidate()
);
// pre-cache assets
workboxSW.precache(fileManifest);
I am using the Chrome Dev tools to check the sw status and the cache created. The network calls to the data URL are as follows:
1st load of page:
2nd load of page:
I'd be grateful for any advice on what I'm doing wrong, or how to debug it.
Thanks in advance
Dan
To be safe, you might want to add skipWaitingto the Workbox constructor to ensure the service worker doesn't wait for the page to reload to start caching.
You would also want to wait on serviceWorker.ready in your page before making the API call. This way you know the service worker is active.
These changes together, in your service worker you would have:
...
const workboxSW = new self.WorkboxSW({skipWaiting: true, clientsClaim: true});
// register data url to cache
workboxSW.router.registerRoute(
'/my_api/data',
workboxSW.strategies.staleWhileRevalidate()
);
// pre-cache assets
workboxSW.precache(fileManifest);
Then in your web page
...
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/my_sw.js')
.then(function() {
return navigator.serviceWorker.ready;
})
.then(function() {
app.getData(); # fetch api data
});
}

Prevent supertest from running until express server has started

I have an node / express js app that was generated using the yoman full stack generator. I have swapped out mongo / mongoose for cloudant db (which is just a paid for version of couchdb). I have a written a wrapper for the Cloudant node.js library which handles cookie auth with my instance via an init() method wrapped in a promise. I have refactored my application to not start the express server until the connection to the db has been established as per snippet below taken from my app.js
myDb.init(config).then(function (db) {
logger.write(1001, '','Connection to Cloudant Established');
// Start server
server.listen(config.port, config.ip, function () {
logger.write(1001, "",'Express server listening on '+config.port+', in '+app.get('env')+' mode');
});
});
On my express routes I have introduced a new middleware which attaches the db object to the request for use across the middleware chain as per below. This gets the db connection object before setting the two collections to use.
exports.beforeAll = function (req, res, next) {
req.my = {};
// Adding my-db
req.my.db = {};
req.my.db.connection = myDb.getDbConnection();
req.my.db.orders = req.my.db.connection.use(dbOrders);
req.my.db.dbRefData = req.my.db.connection.use(dbRefData);
next();
};
This mechanism works when i manually drive my apis through POSTman as the express server won't start until after the promise from the db connection has been resolved. However when running my automated tests the first few tests are now always failing because the application has not finished initialising with the db before jasmine starts to run my tests against the APIs. I can see in my logs the requests on the coming through and myDb.getDbConnection(); in the middleware returning undefined. I am using supertest and node-jasmine to run my tests. For example
'use strict';
var app = require('../../app');
var request = require('supertest');
describe('GET /api/content', function () {
it('should respond with JSON object', function (done) {
request(app)
.get('/api/content')
.expect(200)
.expect('Content-Type', /json/)
.end(function (err, res) {
if (err) return done(err);
expect(res.body).toEqual(jasmine.any(Object));
done();
});
});
});
So, my question is how can I prevent supertest from making the requests until the server.listen() step has been completed as a result of the myDb.init() call being resolved? OR perhaps there is some kind of jasmine beforeAll that I can use to stop it running the describes until the promise has been resolved?
You could make you app return an EventEmitter which emits a "ready" event when it has completed its initialisation.
Then your test code, in a before clause, can wait until the "ready" event arrives from the app before proceeding with the tests.