Skip to content

Commit c04d064

Browse files
Initial commit
0 parents  commit c04d064

File tree

17 files changed

+2778
-0
lines changed

17 files changed

+2778
-0
lines changed

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
._*
2+
.DS_Store
3+
.DS_Store?
4+
.idea
5+
.Spotlight-V100
6+
.Trashes
7+
docs
8+
Icon?
9+
node_modules
10+
public/scripts/bower_components

.jshintrc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"node": true,
3+
"browser": true,
4+
"bitwise": true,
5+
"devel": false,
6+
"eqeqeq": false,
7+
"forin": true,
8+
"immed": true,
9+
"latedef": "nofunc",
10+
"newcap": true,
11+
"noarg": true,
12+
"noempty": true,
13+
"nonew": true,
14+
"nomen": false,
15+
"sub": true,
16+
"trailing": true,
17+
"undef": true,
18+
"unused": true,
19+
"asi": true
20+
}

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 bestguy
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

Readme.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Lazy load example
2+
3+
* [ES6 (via BabelJS)](http://babeljs.io/)
4+
* [Ractive](http://www.ractivejs.org/)
5+
* [Webpack](http://webpack.github.io)
6+
* [lodash](https://lodash.com/docshttps://github.com/chjj/marked)
7+
* [xhttp](https://github.com/Mitranim/xhttp)
8+
* [Ractive-route](https://github.com/MartinKolarik/ractive-route)
9+
10+
----
11+
12+
## Install & Run:
13+
14+
### For development:
15+
16+
npm install
17+
npm start
18+
19+
Open: http://localhost:3000
20+
21+
### For production bundle:
22+
23+
webpack -p
24+
npm start
25+
26+
Open: http://localhost:3000

app.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
let config = require('config');
4+
let express = require('express');
5+
let logger = require('morgan');
6+
let request = require('request-promise');
7+
let data = require('./data.json');
8+
9+
let app = new express();
10+
11+
// ## Middleware
12+
13+
app.use(logger('dev'));
14+
app.use(express.static(`${__dirname}/public`));
15+
16+
// ## Routes
17+
if (config.env == 'dev') {
18+
let webpackMiddleware = require('webpack-dev-middleware');
19+
let webpack = require('webpack');
20+
let webpackConfig = require('./webpack.config.js');
21+
app.use(webpackMiddleware(webpack(webpackConfig), {}));
22+
}
23+
24+
app.get('/api/data', (req, resp) => {
25+
let start = parseInt(req.query.start || 0);
26+
let size = parseInt(req.query.size || 1000);
27+
let results = {
28+
results: data.slice(start, start+size),
29+
total: data.length
30+
}
31+
32+
setTimeout(() => resp.json(results), 3500); // Fake delay to simulate reality
33+
});
34+
35+
app.listen(config.port, () => console.log(`Server running on port ${config.port}...`));

config/default.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
env: process.env.NODE_ENV || 'dev',
3+
port: process.env.PORT || 3000
4+
};

data.json

Lines changed: 2347 additions & 0 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "lazy-load-example",
3+
"version": "0.1.0",
4+
"private": true,
5+
"main": "app.js",
6+
"scripts": {
7+
"start": "node app.js"
8+
},
9+
"dependencies": {
10+
"config": "^1.8.1",
11+
"express": "^4.10.2",
12+
"morgan": "^1.5.0"
13+
},
14+
"devDependencies": {
15+
"animate.css": "^3.5.1",
16+
"autoprefixer-loader": "^3.2.0",
17+
"babel-core": "^5.8.35",
18+
"babel-loader": "^5.4.0",
19+
"css-loader": "^0.23.1",
20+
"html-loader": "^0.4.3",
21+
"lodash": "^4.6.1",
22+
"ractive": "^0.7.3",
23+
"ractive-loader": "^0.5.6",
24+
"ractive-route": "github:martinkolarik/ractive-route",
25+
"ractive-transitions-fade": "^0.3.1",
26+
"ractive-transitions-slide": "^0.4.0",
27+
"request-promise": "^3.0.0",
28+
"style-loader": "^0.13.0",
29+
"webpack": "^1.12.14",
30+
"webpack-dev-middleware": "^1.5.1",
31+
"xhttp": "0.0.8"
32+
}
33+
}

public/index.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>Lazy-load example</title>
7+
<meta charset="utf-8">
8+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
9+
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
10+
<meta name="apple-mobile-web-app-capable" content="yes">
11+
<meta name="apple-mobile-web-app-status-bar-style" content="black">
12+
<meta name="format-detection" content="telephone=no">
13+
<link rel="stylesheet" href="/styles/bootstrap.min.css">
14+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
15+
</head>
16+
17+
<body>
18+
<div id="main" class="container"></div>
19+
</body>
20+
21+
<script type="text/javascript" src="./bundle.js"></script>
22+
23+
</html>

public/scripts/Home.es6

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import Ractive from 'ractive';
2+
import xhttp from 'xhttp';
3+
import _ from 'lodash';
4+
5+
export default Ractive.extend({ // jshint ignore:line
6+
template: require('./Home.html'),
7+
data() {
8+
return {
9+
loading: true,
10+
search_index: 0
11+
}
12+
},
13+
computed: {
14+
search_results() {
15+
let { data, search } = this.get();
16+
search = search.trim().toLowerCase();
17+
if (search.trim().length > 0) {
18+
return _.filter(data, user => user.first.startsWith(search) || user.last.startsWith(search)) || [];
19+
} else {
20+
return []
21+
}
22+
}
23+
},
24+
oninit() {
25+
let page_size = 500;
26+
27+
this.observe({
28+
search: () => this.set({ search_index: 0 }) // Reset index on new search
29+
});
30+
31+
// Request first page of data, up to page_size results:
32+
xhttp({ method: 'get', url: `/api/data?size=${page_size}`})
33+
.then(data => {
34+
// Get total results from first request:
35+
let total_results = data.total;
36+
37+
// Display first results and total:
38+
this.set({
39+
data: data.results,
40+
total: total_results
41+
});
42+
43+
// If results length < page size, we are done; otherwise queue up requests:
44+
if (total_results > page_size) {
45+
46+
// Build array of page start indexes:
47+
let page_indexes = _.range(page_size, total_results, page_size);
48+
49+
// Create array of promises for requesting each page, then appending results:
50+
let page_requests =
51+
page_indexes.map(start_index => () => {
52+
return xhttp({ method: 'get', url: `/api/data?size=${page_size}&start=${start_index}`})
53+
.then(data => this.push('data', ...data.results)); // Appends data
54+
});
55+
56+
// Sets loading indicator to false when all requests are complete:
57+
page_requests.push(() => this.set({ loading: false }));
58+
59+
// This calls the promises above in sequence:
60+
page_requests.reduce((promise, next_request) => promise.then(next_request), Promise.resolve());
61+
62+
// Parallel
63+
// let page_requests =
64+
// page_indexes.map(start_index => new Promise(() => {xhttp({ method: 'get', url: `/api/data?size=${page_size}&start=${start_index}`})
65+
// .then(data => this.push('data', ...data.results))); // Appends data
66+
// // Start all requests, set loading indicator to false when all are complete:
67+
// Promise.all(page_requests)
68+
// .then(data => this.set({ loading: false }))
69+
// .catch(err => console.error);
70+
}
71+
})
72+
.catch(err => console.error);
73+
}
74+
});

0 commit comments

Comments
 (0)