Skip to content
This repository was archived by the owner on Mar 3, 2026. It is now read-only.

Commit ae27e63

Browse files
committed
Assets performance
- Improve performance for development, it now resolve files from file system (not from memory) - Reuse instances of V8 engine to speed up processing - Introduce a EngineFactory and Engine contracts (help to manage lifecycle of V8 engine) - Do not run asset compiler during jooby:run restarts - Added a progress bar (cosmetic improvements) - For development, it now process a file only once - Updated tests - Fix jooby-project#1085
1 parent 63c750f commit ae27e63

File tree

55 files changed

+2482
-1253
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2482
-1253
lines changed

modules/jooby-assets-autoprefixer/src/main/java/org/jooby/assets/AutoPrefixer.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,8 @@ public boolean matches(final MediaType type) {
291291
@Override
292292
public String process(final String filename, final String source, final Config conf)
293293
throws Exception {
294-
return V8Context.run(v8 -> {
295-
return v8.invoke("auto-prefixer.js", source, options(), filename);
296-
});
294+
return engine(V8Engine.class)
295+
.execute("auto-prefixer.js", source, options(), filename);
297296
}
298297

299298
}

modules/jooby-assets-autoprefixer/src/test/java/org/jooby/assets/AutoPrefixerTest.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
package org.jooby.assets;
22

3+
import com.typesafe.config.ConfigFactory;
4+
import org.jooby.MediaType;
5+
import org.junit.AfterClass;
36
import static org.junit.Assert.assertEquals;
47
import static org.junit.Assert.assertFalse;
58
import static org.junit.Assert.assertTrue;
6-
7-
import java.util.Arrays;
8-
9-
import org.jooby.MediaType;
109
import org.junit.Test;
1110

12-
import com.typesafe.config.ConfigFactory;
11+
import java.util.Arrays;
1312

1413
public class AutoPrefixerTest {
14+
private static V8EngineFactory engineFactory = new V8EngineFactory();
15+
16+
@AfterClass
17+
public static void release() {
18+
engineFactory.release();
19+
}
1520

1621
@Test
1722
public void css() throws Exception {
@@ -37,7 +42,9 @@ public void defaults() throws Exception {
3742
" display: -ms-flexbox;\n" +
3843
" display: flex\n" +
3944
"}",
40-
new AutoPrefixer().process("/styles.css", ":fullscreen a {\n" +
45+
new AutoPrefixer()
46+
.set(engineFactory)
47+
.process("/styles.css", ":fullscreen a {\n" +
4148
" display: flex\n" +
4249
"}",
4350
ConfigFactory.empty()));
@@ -60,6 +67,7 @@ public void browsers() throws Exception {
6067
" display: flex\n" +
6168
"}",
6269
new AutoPrefixer()
70+
.set(engineFactory)
6371
.set("browsers", Arrays.asList("> 1%", "IE 7"))
6472
.process("/styles.css", ":fullscreen a {\n" +
6573
" display: flex\n" +

modules/jooby-assets-babel/src/main/java/org/jooby/assets/Babel.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,8 @@ public boolean matches(final MediaType type) {
266266
@Override
267267
public String process(final String filename, final String source, final Config conf)
268268
throws Exception {
269-
return V8Context.run(v8 -> {
270-
return v8.invoke("babel.js", source, options(), filename);
271-
});
269+
return engine(V8Engine.class)
270+
.execute("babel.js", source, options(), filename);
272271
}
273272

274273
}

modules/jooby-assets-babel/src/test/java/org/jooby/assets/BabelTest.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
package org.jooby.assets;
22

3+
import com.typesafe.config.ConfigFactory;
4+
import org.junit.AfterClass;
35
import static org.junit.Assert.assertEquals;
6+
import org.junit.Test;
47

58
import java.util.Arrays;
69

7-
import org.junit.Test;
10+
public class BabelTest {
811

9-
import com.typesafe.config.ConfigFactory;
12+
private static V8EngineFactory engineFactory = new V8EngineFactory();
1013

11-
public class BabelTest {
14+
@AfterClass
15+
public static void release() {
16+
engineFactory.release();
17+
}
1218

1319
@Test
1420
public void name() throws Exception {
@@ -19,6 +25,7 @@ public void name() throws Exception {
1925
public void defaults() throws Exception {
2026
assertEquals("code();",
2127
new Babel()
28+
.set(engineFactory)
2229
.process("/x.js",
2330
"code();",
2431
ConfigFactory.empty()));
@@ -37,6 +44,7 @@ public void imports() throws Exception {
3744
"\n" +
3845
"alert(\"2 = \" + math.sum(math.pi, math.pi));",
3946
new Babel()
47+
.set(engineFactory)
4048
.set("presets", Arrays.asList("es2015"))
4149
.process("/x.js",
4250
"import * as math from \"math\";\n" +
@@ -50,6 +58,7 @@ public void err() throws Exception {
5058
"\n" +
5159
"code(;",
5260
new Babel()
61+
.set(engineFactory)
5362
.process("/x.js",
5463
"co de(;",
5564
ConfigFactory.empty()));
@@ -59,6 +68,7 @@ public void err() throws Exception {
5968
public void react() throws Exception {
6069
assertEquals("var myDivElement = React.createElement(\"div\", { className: \"foo\" });",
6170
new Babel()
71+
.set(engineFactory)
6272
.set("presets", Arrays.asList("react"))
6373
.process("/x.js",
6474
"var myDivElement = <div className=\"foo\" />;",
@@ -70,6 +80,7 @@ public void inlineSourceMaps() throws Exception {
7080
assertEquals("var myDivElement = React.createElement(\"div\", { className: \"foo\" });\n" +
7181
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInguanMiXSwibmFtZXMiOlsibXlEaXZFbGVtZW50Il0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxlQUFlLDZCQUFLLFdBQVUsS0FBZixHQUFuQiIsImZpbGUiOiJ4LmpzIiwic291cmNlc0NvbnRlbnQiOlsidmFyIG15RGl2RWxlbWVudCA9IDxkaXYgY2xhc3NOYW1lPVwiZm9vXCIgLz47Il19",
7282
new Babel()
83+
.set(engineFactory)
7384
.set("sourceMaps", "inline")
7485
.set("presets", Arrays.asList("react"))
7586
.process("/x.js",
@@ -126,6 +137,7 @@ public void polyfill() throws Exception {
126137
" }\n" +
127138
"}",
128139
new Babel()
140+
.set(engineFactory)
129141
.set("presets", Arrays.asList("es2015"))
130142
.process("/x.js",
131143
"let fibonacci = {\n" +
@@ -195,6 +207,7 @@ public void polyfillWithExternalHelpers() throws Exception {
195207
" }\n" +
196208
"}",
197209
new Babel()
210+
.set(engineFactory)
198211
.set("presets", Arrays.asList("es2015"))
199212
.set("plugins", Arrays.asList("external-helpers"))
200213
.process("/x.js",
@@ -227,6 +240,7 @@ public void ecma6Arrow() throws Exception {
227240
" return v + 1;\n" +
228241
"});",
229242
new Babel()
243+
.set(engineFactory)
230244
.set("presets", Arrays.asList("es2015"))
231245
.process("/x.js",
232246
"var odds = evens.map(v => v + 1);",
@@ -241,6 +255,7 @@ public void ecma6TemplateStr() throws Exception {
241255
" time = \"today\";\n" +
242256
"\"Hello \" + name + \", how are you \" + time + \"?\";",
243257
new Babel()
258+
.set(engineFactory)
244259
.set("presets", Arrays.asList("es2015"))
245260
.process("/x.js",
246261
"var name = \"Bob\", time = \"today\";\n" +
@@ -264,6 +279,7 @@ public void ecma6LexicalThis() throws Exception {
264279
" }\n" +
265280
"};",
266281
new Babel()
282+
.set(engineFactory)
267283
.set("presets", Arrays.asList("es2015"))
268284
.process("/x.js",
269285
"var bob = {\n" +

modules/jooby-assets-clean-css/src/main/java/org/jooby/assets/CleanCss.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,8 @@ public boolean matches(final MediaType type) {
259259
@Override
260260
public String process(final String filename, final String source, final Config conf)
261261
throws Exception {
262-
return V8Context.run(v8 -> {
263-
return v8.invoke("clean-css.js", source, options(), filename);
264-
});
262+
return engine(V8Engine.class)
263+
.execute("clean-css.js", source, options(), filename);
265264
}
266265

267266
}

modules/jooby-assets-clean-css/src/test/java/org/jooby/assets/CleanCSSTest.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.jooby.assets;
22

3+
import org.junit.AfterClass;
34
import static org.junit.Assert.assertEquals;
45

56
import org.junit.Test;
@@ -8,6 +9,13 @@
89

910
public class CleanCSSTest {
1011

12+
private static V8EngineFactory engineFactory = new V8EngineFactory();
13+
14+
@AfterClass
15+
public static void release() {
16+
engineFactory.release();
17+
}
18+
1119
@Test
1220
public void name() throws Exception {
1321
assertEquals("clean-css", new CleanCss().name());
@@ -16,21 +24,27 @@ public void name() throws Exception {
1624
@Test
1725
public void defaults() throws Exception {
1826
assertEquals("a{font-weight:700}",
19-
new CleanCss().process("/styles.css", "a {\n font-weight:bold;\n}\n",
27+
new CleanCss()
28+
.set(engineFactory)
29+
.process("/styles.css", "a {\n font-weight:bold;\n}\n",
2030
ConfigFactory.empty()));
2131
}
2232

2333
@Test(expected = AssetException.class)
2434
public void error() throws Exception {
2535
assertEquals("a{font-weight:700}",
26-
new CleanCss().process("/styles.css", "a {\n font-weight:bold;\n\n",
36+
new CleanCss()
37+
.set(engineFactory)
38+
.process("/styles.css", "a {\n font-weight:bold;\n\n",
2739
ConfigFactory.empty()));
2840
}
2941

3042
@Test
3143
public void importDirective() throws Exception {
3244
assertEquals(".foo{color:#fff}a{font-weight:700}",
33-
new CleanCss().process("/styles.css", "@import 'foo.css';\na {\n font-weight:bold;\n}\n",
45+
new CleanCss()
46+
.set(engineFactory)
47+
.process("/styles.css", "@import 'foo.css';\na {\n font-weight:bold;\n}\n",
3448
ConfigFactory.empty()));
3549
}
3650

modules/jooby-assets-csslint/src/main/java/org/jooby/assets/Csslint.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,6 @@
232232
*/
233233
public class Csslint extends AssetProcessor {
234234

235-
public Csslint() {
236-
}
237-
238235
@Override
239236
public boolean matches(final MediaType type) {
240237
return MediaType.css.matches(type);
@@ -243,9 +240,8 @@ public boolean matches(final MediaType type) {
243240
@Override
244241
public String process(final String filename, final String source, final Config conf)
245242
throws Exception {
246-
return V8Context.run(v8 -> {
247-
return v8.invoke("csslint.js", source, options(), filename);
248-
});
243+
return engine(V8Engine.class)
244+
.execute("csslint.js", source, options(), filename);
249245
}
250246

251247
}

modules/jooby-assets-csslint/src/test/java/org/jooby/assets/CsslintTest.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.jooby.assets;
22

3+
import org.junit.AfterClass;
34
import static org.junit.Assert.assertEquals;
45

56
import org.junit.Test;
@@ -8,6 +9,13 @@
89

910
public class CsslintTest {
1011

12+
private static V8EngineFactory engineFactory = new V8EngineFactory();
13+
14+
@AfterClass
15+
public static void release() {
16+
engineFactory.release();
17+
}
18+
1119
@Test
1220
public void name() throws Exception {
1321
assertEquals("csslint", new Csslint().name());
@@ -20,7 +28,9 @@ public void defaults() throws Exception {
2028
" padding: 5px;\n" +
2129
" width: 100px;\n" +
2230
"}\n" +
23-
"", new Csslint().process("/styles.css", ".mybox {\n" +
31+
"", new Csslint()
32+
.set(engineFactory)
33+
.process("/styles.css", ".mybox {\n" +
2434
" border: 1px solid black;\n" +
2535
" padding: 5px;\n" +
2636
" width: 100px;\n" +
@@ -34,7 +44,9 @@ public void boxModelErr() throws Exception {
3444
" padding: 5px;\n" +
3545
" width: 100px;\n" +
3646
"}\n" +
37-
"", new Csslint().set("box-model", 2).process("/styles.css", ".mybox {\n" +
47+
"", new Csslint()
48+
.set(engineFactory)
49+
.set("box-model", 2).process("/styles.css", ".mybox {\n" +
3850
" border: 1px solid black;\n" +
3951
" padding: 5px;\n" +
4052
" width: 100px;\n" +

0 commit comments

Comments
 (0)