mirror of
https://github.com/servo/servo.git
synced 2025-09-11 23:48:21 +01:00
tests: Vendor blink perf tests (#38654)
Vendors the [blink perf tests](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/perf_tests/). These perf tests are useful to evaluate the performance of servo. The license that governs the perf tests is included in the folder. Running benchmark cases automatically is left to future work. The update.py script is taken from mozjs and slightly adapted, so we can easily filter (and patch if this should be necessary in the future. Testing: This PR just adds the perf_tests, but does not use or modify them in any way. --------- Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
parent
7621332824
commit
ee781b71b4
648 changed files with 359694 additions and 0 deletions
40
tests/blink_perf_tests/perf_tests/css/AtScope.html
Normal file
40
tests/blink_perf_tests/perf_tests/css/AtScope.html
Normal file
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<style id=style></style>
|
||||
<div id=root class=myscope></div>
|
||||
<script>
|
||||
const SELECTORS = 1000;
|
||||
|
||||
function makeStyle() {
|
||||
let selectors = [...Array(SELECTORS).keys()].map(x => `.a${x}`);
|
||||
// Creates a selector list which is expensive to evaluate:
|
||||
// (.a1, .a2, .a3 ... .a<n-1>, .myscope)
|
||||
return `
|
||||
@scope (${selectors.join(',')}, .myscope) {
|
||||
div {
|
||||
margin: 1px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
function setup() {
|
||||
style.textContent = makeStyle();
|
||||
createDOMTree(root, /* siblings */ 2, /* depth */ 11);
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: '@scope with many ancestors',
|
||||
run: () => {
|
||||
root.offsetTop;
|
||||
root.classList.toggle('myscope');
|
||||
root.offsetTop;
|
||||
root.classList.toggle('myscope');
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
70
tests/blink_perf_tests/perf_tests/css/AtScopeAncestor.html
Normal file
70
tests/blink_perf_tests/perf_tests/css/AtScopeAncestor.html
Normal file
|
@ -0,0 +1,70 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<style id=style></style>
|
||||
<div id=root></div>
|
||||
<script>
|
||||
const SELECTORS = 1000;
|
||||
const DOM_WIDTH = 10;
|
||||
const DOM_DEPTH = 1000;
|
||||
|
||||
function makeStyle() {
|
||||
let selectors = [...Array(SELECTORS).keys()].map(x => `.a${x}`);
|
||||
// Creates a selector list which is expensive to evaluate:
|
||||
// (.a1, .a2, .a3 ... .a<n-1>, ...)
|
||||
return `
|
||||
@scope (:not(:is(${selectors.join(',')})).foo) {
|
||||
div:empty:not(.bar) {
|
||||
margin: 1px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
function makeChain(n) {
|
||||
if (n <= 0) {
|
||||
return null;
|
||||
}
|
||||
let element = document.createElement('div');
|
||||
let child = makeChain(n - 1);
|
||||
if (child != null) {
|
||||
element.appendChild(child);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
let leaf_nodes = [];
|
||||
|
||||
function setup() {
|
||||
style.textContent = makeStyle();
|
||||
|
||||
for (let i = 0; i < DOM_WIDTH; ++i) {
|
||||
root.appendChild(makeChain(DOM_DEPTH));
|
||||
}
|
||||
|
||||
leaf_nodes = document.querySelectorAll('div:empty');
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Non-matching ancestor via :scope',
|
||||
run: () => {
|
||||
root.offsetTop;
|
||||
for (let e of leaf_nodes) {
|
||||
e.classList.toggle('bar');
|
||||
}
|
||||
root.offsetTop;
|
||||
for (let e of leaf_nodes) {
|
||||
e.classList.toggle('bar');
|
||||
}
|
||||
root.offsetTop;
|
||||
for (let e of leaf_nodes) {
|
||||
e.classList.toggle('bar');
|
||||
}
|
||||
root.offsetTop;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
42
tests/blink_perf_tests/perf_tests/css/AtScopeInsertion.html
Normal file
42
tests/blink_perf_tests/perf_tests/css/AtScopeInsertion.html
Normal file
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<div id=container></div>
|
||||
<div id=root class=myscope></div>
|
||||
<script>
|
||||
const SELECTORS = 2000;
|
||||
|
||||
let style = document.createElement('style');
|
||||
|
||||
function makeStyle() {
|
||||
let selectors = [...Array(SELECTORS).keys()].map(x => `.a${x}`);
|
||||
// Creates a selector list which is expensive to evaluate:
|
||||
// (.a1, .a2, .a3 ... .a<n-1>, .myscope)
|
||||
return `
|
||||
@scope (${selectors.join(',')}, .myscope) {
|
||||
div {
|
||||
margin: 1px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
function setup() {
|
||||
style.textContent = makeStyle();
|
||||
createDOMTree(root, /* siblings */ 1, /* depth */ 50);
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Inserting @scope with a deep tree',
|
||||
run: () => {
|
||||
container.append(style);
|
||||
root.offsetTop;
|
||||
style.remove();
|
||||
root.offsetTop;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
[attr=root] [attr=child] {}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
function addChildren(element, numChildren, idPrefix)
|
||||
{
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.id = idPrefix + i;
|
||||
element.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTree(element, depth, fanOut, idPrefix)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return;
|
||||
addChildren(element, fanOut, idPrefix);
|
||||
for (var child = element.firstChild; child.nextSibling; child = child.nextSibling) {
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
}
|
||||
if (child)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
}
|
||||
|
||||
var root = document.querySelector("#root");
|
||||
makeTree(root, 6, 5, "child");
|
||||
|
||||
var child = document.querySelector("#child012341");
|
||||
child.setAttribute("attr", "child");
|
||||
var runFunction = function()
|
||||
{
|
||||
root.offsetHeight; // force recalc style
|
||||
root.setAttribute("attr" , "root");
|
||||
root.offsetHeight;
|
||||
root.removeAttribute("attr");
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the CSS attribute descendant selector ([a=b] [c=d]).",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
53
tests/blink_perf_tests/perf_tests/css/BigContainerQuery.html
Normal file
53
tests/blink_perf_tests/perf_tests/css/BigContainerQuery.html
Normal file
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
#container {
|
||||
width: 200px;
|
||||
}
|
||||
.inline_size {
|
||||
container-type: inline-size;
|
||||
}
|
||||
</style>
|
||||
<div id=container>
|
||||
<div id=target></div>
|
||||
</div>
|
||||
<style id=style></style>
|
||||
<script>
|
||||
|
||||
// Makes a big container query as follows:
|
||||
//
|
||||
// @container ((width = 1000px) or (width = 1001px) or ... (width = (1000+n)px) or (width = 200px)) {
|
||||
// #target {}
|
||||
// #target {}
|
||||
// ... n times in total ...
|
||||
// #target {}
|
||||
// }
|
||||
function makeQuery(n) {
|
||||
let expressions = [];
|
||||
let rules = [];
|
||||
for (let i = 0; i < n; i++) {
|
||||
expressions.push(`(width = ${1000+i}px)`);
|
||||
rules.push('#target { }');
|
||||
}
|
||||
expressions.push(`(width = 200px)`);
|
||||
return `@container (${expressions.join(' or ')}) { ${rules.join('\n') } }`;
|
||||
}
|
||||
|
||||
function setup() {
|
||||
style.textContent = makeQuery(1000);
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Big container query with many inner rules',
|
||||
run: () => {
|
||||
target.offsetTop;
|
||||
container.classList.toggle('inline_size');
|
||||
target.offsetTop;
|
||||
container.classList.toggle('inline_size');
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
32
tests/blink_perf_tests/perf_tests/css/CSSCountersCreate.html
Normal file
32
tests/blink_perf_tests/perf_tests/css/CSSCountersCreate.html
Normal file
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div {
|
||||
counter-increment: my-counter;
|
||||
}
|
||||
div::before {
|
||||
content: counter(my-counter);
|
||||
}
|
||||
</style>
|
||||
<body></body>
|
||||
<script>
|
||||
function createTree(root, num_elements, depth) {
|
||||
if (!depth) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < num_elements; ++i) {
|
||||
const div = document.createElement('div');
|
||||
root.append(div);
|
||||
createTree(div, num_elements, depth - 1);
|
||||
}
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measure the time of the css counters creation',
|
||||
run: function() {
|
||||
document.body.innerHTML = '';
|
||||
createTree(document.body, 5, 6);
|
||||
},
|
||||
iterationCount: 5,
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<style>
|
||||
body.default_ltr .default { direction: ltr; }
|
||||
body.default_ltr .alternative { direction: rtl; }
|
||||
|
||||
body.default_rtl .default { direction: rtl; }
|
||||
body.default_rtl .alternative { direction: ltr; }
|
||||
div { margin-inline-start: 10px; }
|
||||
/* Give the cascade something to do: */
|
||||
div { border: 0px solid red; }
|
||||
div { border: 0px solid green !important; }
|
||||
div { border: 0px solid black; }
|
||||
div { padding: 0px; }
|
||||
</style>
|
||||
<body class="default_ltr"></body>
|
||||
<script>
|
||||
|
||||
function createTree(node, siblings, depth) {
|
||||
if (!depth)
|
||||
return;
|
||||
for (let i = 0; i < siblings; i++) {
|
||||
var div = document.createElement('div');
|
||||
div.className = (depth % 2 == 0) ? 'default' : 'alternative';
|
||||
node.append(div);
|
||||
createTree(div, siblings, depth - 1);
|
||||
}
|
||||
}
|
||||
createTree(document.body, 4, 6);
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measure impact of switching direction with css-logical',
|
||||
run: function() {
|
||||
document.body.classList.toggle('default_ltr');
|
||||
document.body.classList.toggle('default_rtl');
|
||||
forceStyleRecalc(document.body);
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,85 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="test"></div>
|
||||
</body>
|
||||
<script>
|
||||
var div = document.getElementById("test");
|
||||
var properties = {
|
||||
'azimuth' : 'right',
|
||||
'backgroundColor' : 'green',
|
||||
'backgroundImage' : 'url(\'test.png\')',
|
||||
'backgroundPosition' : 'top',
|
||||
'backgroundRepeat' : 'repeat-x',
|
||||
'background' : '#ffffff url(\'img_tree.png\') no-repeat right top',
|
||||
'border' : '20px dotted red',
|
||||
'borderBottomStyle' : 'dotted',
|
||||
'borderCollapse' : 'separate',
|
||||
'borderColor' : 'blue',
|
||||
'borderSpacing' : '3px',
|
||||
'borderStyle' : 'solid',
|
||||
'borderTop' : 'green',
|
||||
'borderWidth' : '20em',
|
||||
'bottom' : '20%',
|
||||
'captionSide' : 'top',
|
||||
'clear' : 'both',
|
||||
'clip' : 'rect(5px, 40px, 45px, 5px)',
|
||||
'color' : 'red',
|
||||
'content' : 'normal',
|
||||
'direction' : 'rtl',
|
||||
'display' : 'block',
|
||||
'cssFloat' : 'right',
|
||||
'fontFamily' : '"Times New Roman",Georgia,Serif',
|
||||
'fontSize' : '13px',
|
||||
'fontVariant' : 'small-caps',
|
||||
'fontWeight' : '700',
|
||||
'font' : 'italic bold 12px/30px Georgia, serif',
|
||||
'height' : '200px',
|
||||
'left' : '20%',
|
||||
'letterSpacing' : '10px',
|
||||
'lineHeight' : '40px',
|
||||
'listStyleImage' : 'url(\'test.png\')',
|
||||
'listStylePosition' : 'outside',
|
||||
'listStyleType' : 'decimal',
|
||||
'listStyle' : 'circle inside',
|
||||
'marginRight' : '50px',
|
||||
'margin' : '10px 20px 30px 5em',
|
||||
'maxHeight' : '700px',
|
||||
'maxWidth' : '300px',
|
||||
'minHeight' : '100px',
|
||||
'minWidth' : '100px',
|
||||
'outlineColor' : 'gray',
|
||||
'outlineStyle' : 'dotted',
|
||||
'outlineWidth' : '5px',
|
||||
'paddingTop' : '30px',
|
||||
'padding' : '30px 20px 10px 50px',
|
||||
'pageBreakAfter' : 'always',
|
||||
'pageBreakInside' : 'auto',
|
||||
'pause' : '2s',
|
||||
'position' : 'static',
|
||||
'right' : '150px',
|
||||
'textAlign' : 'center',
|
||||
'textDecoration' : 'blink',
|
||||
'textTransform' : 'capitalize',
|
||||
'top' : '25%',
|
||||
'verticalAlign' : 'text-bottom',
|
||||
'visibility' : 'visible',
|
||||
'width' : '300px',
|
||||
'webkitTransform' : 'scale3d(0.5, 0.5, 0.5)',
|
||||
'wordSpacing' : '40px',
|
||||
};
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the CSS style array index getter and setter (a = elem.style[b], elem.style[c] = d).",
|
||||
run:function() {
|
||||
for (key in properties) {
|
||||
var value = div.style[key];
|
||||
div.style[key] = "";
|
||||
div.style[key] = properties[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,85 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="test"></div>
|
||||
</body>
|
||||
<script>
|
||||
var div = document.getElementById("test");
|
||||
var properties = {
|
||||
'azimuth' : 'right',
|
||||
'background-color' : 'green',
|
||||
'background-image' : 'url(\'test.png\')',
|
||||
'background-position' : 'top',
|
||||
'background-repeat' : 'repeat-x',
|
||||
'background' : '#ffffff url(\'img_tree.png\') no-repeat right top',
|
||||
'border' : '20px dotted red',
|
||||
'border-bottom-style' : 'dotted',
|
||||
'border-collapse' : 'separate',
|
||||
'border-color' : 'blue',
|
||||
'border-spacing' : '3px',
|
||||
'border-style' : 'solid',
|
||||
'border-top' : 'green',
|
||||
'border-width' : '20em',
|
||||
'bottom' : '20%',
|
||||
'caption-side' : 'top',
|
||||
'clear' : 'both',
|
||||
'clip' : 'rect(5px, 40px, 45px, 5px)',
|
||||
'color' : 'red',
|
||||
'content' : 'normal',
|
||||
'direction' : 'rtl',
|
||||
'display' : 'block',
|
||||
'css-float' : 'right',
|
||||
'font-family' : '"Times New Roman",Georgia,Serif',
|
||||
'font-size' : '13px',
|
||||
'font-variant' : 'small-caps',
|
||||
'font-weight' : '700',
|
||||
'font' : 'italic bold 12px/30px Georgia, serif',
|
||||
'height' : '200px',
|
||||
'left' : '20%',
|
||||
'letter-spacing' : '10px',
|
||||
'line-height' : '40px',
|
||||
'list-style-image' : 'url(\'test.png\')',
|
||||
'list-style-position' : 'outside',
|
||||
'list-style-type' : 'decimal',
|
||||
'list-style' : 'circle inside',
|
||||
'margin-right' : '50px',
|
||||
'margin' : '10px 20px 30px 5em',
|
||||
'max-height' : '700px',
|
||||
'max-width' : '300px',
|
||||
'min-height' : '100px',
|
||||
'min-width' : '100px',
|
||||
'outline-color' : 'gray',
|
||||
'outline-style' : 'dotted',
|
||||
'outline-width' : '5px',
|
||||
'padding-top' : '30px',
|
||||
'padding' : '30px 20px 10px 50px',
|
||||
'page-break-after' : 'always',
|
||||
'page-break-inside' : 'auto',
|
||||
'pause' : '2s',
|
||||
'position' : 'static',
|
||||
'right' : '150px',
|
||||
'text-align' : 'center',
|
||||
'text-decoration' : 'blink',
|
||||
'text-transform' : 'capitalize',
|
||||
'top' : '25%',
|
||||
'vertical-align' : 'text-bottom',
|
||||
'visibility' : 'visible',
|
||||
'width' : '300px',
|
||||
'webkit-transform' : 'scale3d(0.5, 0.5, 0.5)',
|
||||
'word-spacing' : '40px',
|
||||
};
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the CSS style getter and setter methods (elem.style.(getPropertyValue|removeProperty|setProperty)).",
|
||||
run:function() {
|
||||
for (key in properties) {
|
||||
var value = div.style.getPropertyValue(key);
|
||||
div.style.removeProperty(key);
|
||||
div.style.setProperty(key, properties[key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,83 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="test"></div>
|
||||
</body>
|
||||
<script>
|
||||
var div = document.getElementById("test");
|
||||
var properties = {
|
||||
'azimuth' : 'right',
|
||||
'backgroundColor' : 'green',
|
||||
'backgroundImage' : 'url(\'test.png\')',
|
||||
'backgroundPosition' : 'top',
|
||||
'backgroundRepeat' : 'repeat-x',
|
||||
'background' : '#ffffff url(\'img_tree.png\') no-repeat right top',
|
||||
'border' : '20px dotted red',
|
||||
'borderBottomStyle' : 'dotted',
|
||||
'borderCollapse' : 'separate',
|
||||
'borderColor' : 'blue',
|
||||
'borderSpacing' : '3px',
|
||||
'borderStyle' : 'solid',
|
||||
'borderTop' : 'green',
|
||||
'borderWidth' : '20em',
|
||||
'bottom' : '20%',
|
||||
'captionSide' : 'top',
|
||||
'clear' : 'both',
|
||||
'clip' : 'rect(5px, 40px, 45px, 5px)',
|
||||
'color' : 'red',
|
||||
'content' : 'normal',
|
||||
'direction' : 'rtl',
|
||||
'display' : 'block',
|
||||
'cssFloat' : 'right',
|
||||
'fontFamily' : '"Times New Roman",Georgia,Serif',
|
||||
'fontSize' : '13px',
|
||||
'fontVariant' : 'small-caps',
|
||||
'fontWeight' : '700',
|
||||
'font' : 'italic bold 12px/30px Georgia, serif',
|
||||
'height' : '200px',
|
||||
'left' : '20%',
|
||||
'letterSpacing' : '10px',
|
||||
'lineHeight' : '40px',
|
||||
'listStyleImage' : 'url(\'test.png\')',
|
||||
'listStylePosition' : 'outside',
|
||||
'listStyleType' : 'decimal',
|
||||
'listStyle' : 'circle inside',
|
||||
'marginRight' : '50px',
|
||||
'margin' : '10px 20px 30px 5em',
|
||||
'maxHeight' : '700px',
|
||||
'maxWidth' : '300px',
|
||||
'minHeight' : '100px',
|
||||
'minWidth' : '100px',
|
||||
'outlineColor' : 'gray',
|
||||
'outlineStyle' : 'dotted',
|
||||
'outlineWidth' : '5px',
|
||||
'paddingTop' : '30px',
|
||||
'padding' : '30px 20px 10px 50px',
|
||||
'pageBreakAfter' : 'always',
|
||||
'pageBreakInside' : 'auto',
|
||||
'pause' : '2s',
|
||||
'position' : 'static',
|
||||
'right' : '150px',
|
||||
'textAlign' : 'center',
|
||||
'textDecoration' : 'blink',
|
||||
'textTransform' : 'capitalize',
|
||||
'top' : '25%',
|
||||
'verticalAlign' : 'text-bottom',
|
||||
'visibility' : 'visible',
|
||||
'width' : '300px',
|
||||
'webkitTransform' : 'scale3d(0.5, 0.5, 0.5)',
|
||||
'wordSpacing' : '40px',
|
||||
};
|
||||
// The first run will just add the properties but it's fine as the first run of the benchmark is always ignored.
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the CSS style array index setter (elem.style[a] = b).",
|
||||
run:function() {
|
||||
for (key in properties)
|
||||
div.style[key] = properties[key];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</html>
|
35
tests/blink_perf_tests/perf_tests/css/CSSQuotesCreate.html
Normal file
35
tests/blink_perf_tests/perf_tests/css/CSSQuotesCreate.html
Normal file
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div {
|
||||
quotes: "A" "Z";
|
||||
}
|
||||
div::before {
|
||||
content: open-quote;
|
||||
}
|
||||
div::after {
|
||||
content: close-quote;
|
||||
}
|
||||
</style>
|
||||
<body></body>
|
||||
<script>
|
||||
function createTree(root, num_elements, depth) {
|
||||
if (!depth) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < num_elements; ++i) {
|
||||
const div = document.createElement('div');
|
||||
root.append(div);
|
||||
createTree(div, num_elements, depth - 1);
|
||||
}
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measure the time of the css quotes creation',
|
||||
run: function() {
|
||||
document.body.innerHTML = '';
|
||||
createTree(document.body, 5, 6);
|
||||
},
|
||||
iterationCount: 5,
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,98 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>CSS Custom Properties and Variables: Changes that require resolving variable references</title>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<style>
|
||||
.container > div {
|
||||
display: inline-block;
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid green;
|
||||
}
|
||||
.container {
|
||||
height: 0px;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<header id=info>CSS Variables: <button id=button></button></header>
|
||||
<script>
|
||||
const NUM_ELEMENTS = 20000;
|
||||
const PROP_COUNT = 1000;
|
||||
let curBorder = -1;
|
||||
let root = document.createElement('div');
|
||||
root.classList.add(`container`);
|
||||
|
||||
// Add ?ref to URL to run a similar test without CSS Variables.
|
||||
const ref = document.location.href.endsWith('?ref');
|
||||
button.textContent = ref ? 'OFF' : 'ON';
|
||||
button.addEventListener('click', function(){
|
||||
let href = document.location.href;
|
||||
if (ref) {
|
||||
document.location.href = href.substr(0, href.length - 4);
|
||||
} else {
|
||||
document.location.href = href + '?ref';
|
||||
}
|
||||
});
|
||||
|
||||
function hexcolor(i) {
|
||||
let hex = i.toString(16);
|
||||
while (hex.length < 6)
|
||||
hex = '0' + hex;
|
||||
return '#' + hex;
|
||||
}
|
||||
|
||||
function createDOMTree() {
|
||||
for (let n = 0; n < NUM_ELEMENTS; n++) {
|
||||
let div = document.createElement('div');
|
||||
let i = n % PROP_COUNT;
|
||||
div.classList.add(`bg-color${i}`);
|
||||
root.appendChild(div);
|
||||
}
|
||||
document.body.appendChild(root);
|
||||
}
|
||||
|
||||
function createDivRules() {
|
||||
let lines = [];
|
||||
for (let i = 0; i < PROP_COUNT; i++) {
|
||||
lines.push(`.border${i} > div { border-color: ${hexcolor(i)}; }`);
|
||||
if (ref)
|
||||
lines.push(`.bg-color${i} { background-color: ${hexcolor(i)}; }`);
|
||||
else
|
||||
lines.push(`.bg-color${i} { background-color: var(--prop-${i}); }`);
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
// Create a rule which defines 'propCount' custom properties at :root.
|
||||
function createRootRule() {
|
||||
if (ref)
|
||||
return;
|
||||
let lines = [':root {'];
|
||||
for (let i = 0; i < PROP_COUNT; i++) {
|
||||
lines.push(`--prop-${i}: ${hexcolor(i)};`);
|
||||
}
|
||||
lines.push('}');
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
applyCSSRule(createDivRules());
|
||||
applyCSSRule(createRootRule());
|
||||
createDOMTree();
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of the CSS variable reference recalc.",
|
||||
setup: () => {
|
||||
root.classList.remove(`border${curBorder}`);
|
||||
// Using PROP_COUNT to ensure different border values, avoiding the style cache
|
||||
curBorder = (curBorder + 1) % PROP_COUNT;
|
||||
},
|
||||
run: function() {
|
||||
root.classList.add(`border${curBorder}`);
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i = 0; i < allElements.length; ++i) {
|
||||
if (i % 2 == 0) {
|
||||
allElements[i].className = "a";
|
||||
} else {
|
||||
allElements[i].className = "b";
|
||||
}
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of a child class selector.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule(".a > .b { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of applying a style on the div child of a div.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("div div { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>CSS Custom Properties and Variables: Changes in property's declaration</title>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<style>
|
||||
.crosshair { --prop: crosshair; }
|
||||
.default { --prop: default; }
|
||||
body > div > div { background-color: grey; }
|
||||
</style>
|
||||
<body>
|
||||
<script>
|
||||
function createDOMTree() {
|
||||
let div = document.createElement('div');
|
||||
div.innerHTML = '<div><div><div><div><div style="cursor: var(--prop)">' + '' + '</div></div></div></div></div>';
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
document.body.appendChild(div.cloneNode(true));
|
||||
}
|
||||
}
|
||||
createDOMTree();
|
||||
var theme;
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance in the propagation of a custom property declaration.",
|
||||
setup: () => {
|
||||
document.body.classList.remove(theme);
|
||||
theme = theme == 'crosshair' ? 'default' : 'crosshair';
|
||||
},
|
||||
run: function() {
|
||||
document.body.classList.add(theme);
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of applying a style on all divs.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("div { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of applying a style on the div grandchild of a div.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("div div div { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i = 0; i < allElements.length; ++i) {
|
||||
allElements[i].className = "a b";
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of multiple class selectors.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule(".a .b { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i = 0; i < allElements.length; ++i) {
|
||||
if (i % 2 == 0)
|
||||
allElements[i].dataset.a = "foo";
|
||||
else
|
||||
allElements[i].dataset.b = "bar";
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of an qualified data attribute selector with a value.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("div[data-a=\"foo\"] div[data-b=\"bar\"] { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createDOMTree(document.body, 3, 3);
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of a solo pseudo selector applied on a grandchild of a div.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("div div div:after { content: 'after'; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<style id="sheet">
|
||||
.c { cursor: crosshair; }
|
||||
</style>
|
||||
<body>
|
||||
<script>
|
||||
createDOMTree(document.body, 6, 6);
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i = 0; i < allElements.length; ++i) {
|
||||
allElements[i].className = 'c';
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of inserting/deleting a new rule into an existing stylesheet.",
|
||||
run: function() {
|
||||
let sheet = document.getElementById('sheet').sheet;
|
||||
sheet.insertRule(".doesnotexist { color: red; }", 1);
|
||||
forceStyleRecalc(document.body);
|
||||
sheet.deleteRule(1);
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of a pair of nth-child selectors.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("div:nth-child(1) div:nth-child(1) div { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i=0; i < allElements.length; i+=2) {
|
||||
allElements[i].className = "wrap";
|
||||
}
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of partial attribute matching.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("[class^='wrap'] { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i = 0; i < allElements.length; ++i) {
|
||||
allElements[i].dataset.test = "foo";
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of a qualified data attribute selector.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("div[data-test] { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i = 0; i < allElements.length; ++i) {
|
||||
allElements[i].dataset.test = "foo";
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of an qualified data attribute selector with a value.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("div[data-test=\"foo\"] { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<style type="text/css">
|
||||
/*
|
||||
We are attempting to manipulate 'expensive' properties here.
|
||||
*/
|
||||
#item {
|
||||
background-color: red;
|
||||
border-radius: 5px;
|
||||
padding: 3px;
|
||||
box-shadow: 0 5px 5px #000;
|
||||
transform: rotate(10deg);
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createShallowDOMTree();
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
var length = allElements.length
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of changing the style of an element in a shallow and broad tree",
|
||||
run: function() {
|
||||
for (var i=0; i < length; i++) {
|
||||
allElements[i].id = "item";
|
||||
forceStyleRecalc(allElements[i]);
|
||||
allElements[i].id = "";
|
||||
forceStyleRecalc(allElements[i]);
|
||||
}
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i = 0; i < allElements.length; ++i) {
|
||||
allElements[i].className = "test";
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of a single class selector with inherited property.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule(".test { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of a nth-child selector.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("div:nth-child(1) div { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createDOMTree(document.body, 3, 3);
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of a solo pseudo selector.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("div:after { content: 'after'; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of the universal selector.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("* { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i = 0; i < allElements.length; ++i) {
|
||||
allElements[i].dataset.test = "foo";
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of an unqualified data attribute selector.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("[data-test] { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
createRegularDOMTree();
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i = 0; i < allElements.length; ++i) {
|
||||
allElements[i].dataset.test = "foo";
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of an unqualified data attribute selector with a value.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("[data-test=\"foo\"] { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
createDOMTree(document.body, 5, 5);
|
||||
var allElements = document.body.getElementsByTagName("div");
|
||||
for (var i = 0; i < allElements.length; ++i) {
|
||||
allElements[i].setAttribute('a', 'x');
|
||||
}
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of inserting an attribute rule that matches nothing.",
|
||||
run: function() {
|
||||
var rule = applyCSSRule("[a=y] { cursor: crosshair; }");
|
||||
forceStyleRecalc(document.body);
|
||||
rule.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
.root .child {}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
function addChildren(element, numChildren, idPrefix)
|
||||
{
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.id = idPrefix + i;
|
||||
element.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTree(element, depth, fanOut, idPrefix)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return;
|
||||
addChildren(element, fanOut, idPrefix);
|
||||
for (var child = element.firstChild; child.nextSibling; child = child.nextSibling) {
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
}
|
||||
if (child)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
}
|
||||
|
||||
var root = document.querySelector("#root");
|
||||
makeTree(root, 6, 5, "child");
|
||||
|
||||
var child = document.querySelector("#child012341");
|
||||
child.className = "child";
|
||||
var runFunction = function()
|
||||
{
|
||||
root.offsetHeight; // force recalc style
|
||||
root.className = "root";
|
||||
root.offsetHeight;
|
||||
root.className = "";
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the CSS class descendant selector (.a .b).",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
31
tests/blink_perf_tests/perf_tests/css/ClassInvalidation.html
Normal file
31
tests/blink_perf_tests/perf_tests/css/ClassInvalidation.html
Normal file
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
.a .b { background-color: green }
|
||||
</style>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
function appendDivChildren(root, childCount, levels) {
|
||||
if (levels <= 0)
|
||||
return;
|
||||
for (var i = 0; i < childCount; i++) {
|
||||
var div = document.createElement("div");
|
||||
appendDivChildren(div, childCount, levels - 1)
|
||||
root.appendChild(div);
|
||||
}
|
||||
}
|
||||
|
||||
var root = document.getElementById("root");
|
||||
appendDivChildren(root, 5, 5);
|
||||
root.firstChild.className = "b";
|
||||
document.body.offsetTop; // force style recalc.
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measure the style recalc performance when changing a class affecting the style of a single descendant.",
|
||||
run: function() {
|
||||
root.className = "a";
|
||||
root.offsetTop; // force recalc.
|
||||
root.className = "";
|
||||
root.offsetTop; // force recalc.
|
||||
}});
|
||||
</script>
|
|
@ -0,0 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header id=info>CSS Variables: <button id=button></button></header>
|
||||
</body>
|
||||
<script>
|
||||
const propCount = 1000;
|
||||
|
||||
// Add ?ref to URL to run a similar test without CSS Variables.
|
||||
const ref = document.location.href.endsWith('?ref');
|
||||
|
||||
button.textContent = ref ? 'OFF' : 'ON';
|
||||
button.addEventListener('click', function(){
|
||||
let href = document.location.href;
|
||||
if (ref) {
|
||||
document.location.href = href.substr(0, href.length - 4);
|
||||
} else {
|
||||
document.location.href = href + '?ref';
|
||||
}
|
||||
});
|
||||
|
||||
function hexcolor(i) {
|
||||
let hex = i.toString(16);
|
||||
while (hex.length < 6)
|
||||
hex = '0' + hex;
|
||||
return '#' + hex;
|
||||
}
|
||||
|
||||
// Create a rule which defines 'propCount' custom properties at :root.
|
||||
function createRootRule() {
|
||||
let lines = [':root {'];
|
||||
for (let i = 0; i < propCount; i++) {
|
||||
lines.push(`--prop-${i}: ${hexcolor(i)};`);
|
||||
}
|
||||
lines.push('}');
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
// Create 'propCount' rules, each refering to a custom property created
|
||||
// by createRootRule.
|
||||
//
|
||||
// If 'ref' is true, then the colors that would have been resolved via
|
||||
// the var()-references are inlined instead.
|
||||
function createDivRules() {
|
||||
let lines = [];
|
||||
for (let i = 0; i < propCount; i++) {
|
||||
if (ref) {
|
||||
lines.push(`div { background-color: ${hexcolor(i)}; }`);
|
||||
} else {
|
||||
lines.push(`div { background-color: var(--prop-${i}); }`);
|
||||
}
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
applyCSSRule(createRootRule());
|
||||
applyCSSRule(createDivRules());
|
||||
createRegularDOMTree();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measures the performance of applying many var()-references.',
|
||||
run: function() {
|
||||
document.body.style = 'display: none';
|
||||
forceStyleRecalc(document.body);
|
||||
document.body.style = 'display: block';
|
||||
forceStyleRecalc(document.body);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<body>
|
||||
<nav id="container" class="red" style="visibility:hidden"></nav>
|
||||
<style>
|
||||
.red { --color: red; }
|
||||
.green { --color: green; }
|
||||
#container div { border-color: var(--color); }
|
||||
</style>
|
||||
<script>
|
||||
createDOMTree(container, 5, 6);
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measure impact of referencing a variable that changes on ancestor',
|
||||
setup: () => forceStyleRecalc(container),
|
||||
run: () => {
|
||||
container.classList.toggle('red');
|
||||
container.classList.toggle('green');
|
||||
forceStyleRecalc(container);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Comparing identical custom property sets</title>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<main id=main></main>
|
||||
<script>
|
||||
const PROP_COUNT = 1000;
|
||||
const TOKEN_COUNT = 3000; // Per custom property.
|
||||
const NODE_COUNT = 20000;
|
||||
|
||||
// Generate declarations with values that have many tokens (i.e. values
|
||||
// that would be expensive to call StyleVariables::operator== on).
|
||||
//
|
||||
// --x0:X X X ... 0
|
||||
// --x1:X X X ... 1
|
||||
// ...
|
||||
let base_value = 'X '.repeat(TOKEN_COUNT / 2);
|
||||
let declaration_array = [];
|
||||
for (let i = 0; i < PROP_COUNT; i++) {
|
||||
let value = base_value + i.toString(); // Make value unique.
|
||||
declaration_array.push(`--x${i}:${value};`);
|
||||
}
|
||||
|
||||
// Generate two rules which produce identical StyleVariables objects.
|
||||
// It's important that they are identical, so that StyleVariables::operator==
|
||||
// has to take the slowest possible path.
|
||||
let declarations = declaration_array.join('\n');
|
||||
applyCSSRule(`#main { ${declarations} }`);
|
||||
applyCSSRule(`#main.change { ${declarations} }`);
|
||||
|
||||
createDOMTree(main, NODE_COUNT, 1 /* siblings */);
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Comparing identical custom property sets',
|
||||
run: function() {
|
||||
forceStyleRecalc(main);
|
||||
main.classList.toggle('change');
|
||||
forceStyleRecalc(main);
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
function createDOMChainWithCustomProps(node, depth) {
|
||||
if (!depth) {
|
||||
return;
|
||||
}
|
||||
let div = document.createElement("div");
|
||||
let style = 'cursor: crosshair;'; // Avoid matched properties cache.
|
||||
|
||||
let props = [];
|
||||
let value = 2**32;
|
||||
for (let i = 0; i < 100; ++i) {
|
||||
props.push(`--property-with-long-name-and-value-${depth}-${i}: ${value.toString(2)};`);
|
||||
// Use a unique value every time to avoid optimization that might
|
||||
// utilize identical values.
|
||||
value--;
|
||||
}
|
||||
|
||||
div.style = style + props.join('\n');
|
||||
node.appendChild(div);
|
||||
createDOMChainWithCustomProps(div, depth - 1);
|
||||
}
|
||||
createDOMChainWithCustomProps(document.body, 1000);
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measure impact inheriting large numbers of unchanged custom properties.',
|
||||
run: function() {
|
||||
document.body.style = 'display: none';
|
||||
forceStyleRecalc(document.body);
|
||||
document.body.style = '';
|
||||
forceStyleRecalc(document.body);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
for (let i = 0; i < 5000; i++) {
|
||||
let div = document.createElement('div');
|
||||
div.style = 'cursor: crosshair'; // Avoid matched properties cache.
|
||||
document.body.appendChild(div);
|
||||
}
|
||||
|
||||
let props = [];
|
||||
let value = 2**32;
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
props.push(`--property-with-long-name-and-value-${i}: ${value.toString(2)};`);
|
||||
// Use a unique value every time to avoid optimization that might
|
||||
// utilize identical values.
|
||||
value--;
|
||||
}
|
||||
|
||||
applyCSSRule(`body { ${props.join('\n')} }`);
|
||||
applyCSSRule('body { --x: 0; --y: var(--x); }');
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measure impact of unused custom properties at body.',
|
||||
run: function() {
|
||||
document.body.style = 'display: none';
|
||||
forceStyleRecalc(document.body);
|
||||
document.body.style = '';
|
||||
forceStyleRecalc(document.body);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<link help="https://drafts.csswg.org/css-variables/#pending-substitution-value">
|
||||
<div id="container" style="height: 100px; overflow: hidden"></div>
|
||||
<script>
|
||||
createDOMTree(container, 2, 3);
|
||||
applyCSSRule(':root { --border: 4mm ridge rgba(170, 50, 220, .6); }');
|
||||
applyCSSRule(':root { --margin: 1px 2px 3px 4px; }');
|
||||
applyCSSRule(':root { --padding: 1px 2px 3px 4px; }');
|
||||
applyCSSRule(':root { --background: content-box radial-gradient(crimson, skyblue); }');
|
||||
|
||||
const sequence_size = 2000;
|
||||
|
||||
function create_var_sequence() {
|
||||
let chain = [];
|
||||
for (let i = 0; i < sequence_size; ++i) {
|
||||
chain.push(`var(--v${i}, )`);
|
||||
}
|
||||
return chain.join(' ');
|
||||
}
|
||||
|
||||
applyCSSRule(`div { border: ${create_var_sequence()} var(--border); }`);
|
||||
applyCSSRule(`div { margin: ${create_var_sequence()} var(--margin); }`);
|
||||
applyCSSRule(`div { padding: ${create_var_sequence()} var(--padding); }`);
|
||||
applyCSSRule(`div { background: ${create_var_sequence()} var(--bakground); }`);
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measure impact of resolving pending-substitution-values',
|
||||
run: function() {
|
||||
container.style.setProperty('display', 'none');
|
||||
forceStyleRecalc(container);
|
||||
container.style.setProperty('display', 'block');
|
||||
forceStyleRecalc(container);
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
for (let i = 0; i < 5000; i++) {
|
||||
let div = document.createElement('div');
|
||||
div.style = 'cursor: crosshair'; // Avoid matched properties cache.
|
||||
document.body.appendChild(div);
|
||||
}
|
||||
|
||||
let props = [];
|
||||
let value = 2**32;
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
props.push(`--property-with-long-name-and-value-${i}: ${value.toString(2)};`);
|
||||
// Use a unique value every time to avoid optimization that might
|
||||
// utilize identical values.
|
||||
value--;
|
||||
}
|
||||
|
||||
applyCSSRule(`:root { ${props.join('\n')} }`);
|
||||
applyCSSRule(':root { --x: 0; --y: var(--x); }');
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measure impact of unused custom properties at :root.',
|
||||
run: function() {
|
||||
document.body.style = 'display: none';
|
||||
forceStyleRecalc(document.body);
|
||||
document.body.style = '';
|
||||
forceStyleRecalc(document.body);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,45 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id=target></div>
|
||||
</body>
|
||||
<script>
|
||||
const property_chain_count = 4;
|
||||
const property_chain_length = 500;
|
||||
|
||||
// Create a rule which defines `property_chain_count` chains of custom
|
||||
// properties, each `property_chain_length` long, with linear var()
|
||||
// dependencies.
|
||||
function createRule() {
|
||||
let lines = ['#target {'];
|
||||
for (let chain = 0; chain < property_chain_count; chain++) {
|
||||
for (let property = 0; property < property_chain_length;
|
||||
property++) {
|
||||
let value = '#fefefe';
|
||||
if (property > 0) {
|
||||
value = `var(--prop-${chain}-${property-1})`;
|
||||
}
|
||||
lines.push(`--prop-${chain}-${property}: ${value};`);
|
||||
}
|
||||
}
|
||||
lines.push('}');
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
applyCSSRule(createRule());
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measures performance of var()-as-alias resolution',
|
||||
run: function() {
|
||||
target.style = 'display: none';
|
||||
forceStyleRecalc(target);
|
||||
target.style = '';
|
||||
forceStyleRecalc(target);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</html>
|
1
tests/blink_perf_tests/perf_tests/css/DIR_METADATA
Normal file
1
tests/blink_perf_tests/perf_tests/css/DIR_METADATA
Normal file
|
@ -0,0 +1 @@
|
|||
mixins: "//third_party/blink/renderer/core/css/COMMON_METADATA"
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<body>
|
||||
<nav id="container" class="red" style="visibility:hidden"></nav>
|
||||
<style>
|
||||
.red { border: 1px solid red; }
|
||||
.green { border: 2px solid green; }
|
||||
#container div { all: unset; }
|
||||
#container div { border-color: inherit; }
|
||||
</style>
|
||||
<script>
|
||||
createDOMTree(container, 4, 5);
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measure impact of explicit inheritance',
|
||||
setup: () => forceStyleRecalc(container),
|
||||
run: () => {
|
||||
container.classList.toggle('red');
|
||||
container.classList.toggle('green');
|
||||
forceStyleRecalc(container);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
39
tests/blink_perf_tests/perf_tests/css/FocusUpdate.html
Normal file
39
tests/blink_perf_tests/perf_tests/css/FocusUpdate.html
Normal file
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Measure :focus update for a simple cursor change</title>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style type="text/css">
|
||||
body { margin: 0 }
|
||||
a { cursor: pointer; }
|
||||
a:focus { cursor: crosshair; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
for (var i=0; i<100; i++) {
|
||||
document.write('<div>');
|
||||
for (var j=0; j<100; j++)
|
||||
document.write('<a></a>');
|
||||
document.write('</div>');
|
||||
}
|
||||
</script>
|
||||
<div id="test"><a href="."></a><a href="."></div></div>
|
||||
<script type="text/javascript">
|
||||
document.body.offsetTop; // Force layout.
|
||||
|
||||
var testDiv = document.getElementById("test");
|
||||
var a1 = testDiv.firstChild;
|
||||
var a2 = a1.nextSibling;
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measure :focus update for a simple cursor change",
|
||||
run:function() {
|
||||
a1.focus();
|
||||
document.body.offsetTop; // Update layout for focused state.
|
||||
a2.focus();
|
||||
document.body.offsetTop; // Update layout for focused state.
|
||||
}});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(.b) .c { color: green }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container class=a></div>
|
||||
<script>
|
||||
|
||||
function addChildren(element, numChildren, idPrefix)
|
||||
{
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.id = idPrefix + i;
|
||||
element.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTree(element, depth, fanOut, idPrefix)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return;
|
||||
addChildren(element, fanOut, idPrefix);
|
||||
for (var child = element.firstChild; child.nextSibling; child = child.nextSibling)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
if (child)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
}
|
||||
|
||||
makeTree(container, 11, 2, "child");
|
||||
for (var parent = child11111111111.parentElement;
|
||||
parent.id != "container";
|
||||
parent = parent.parentElement) {
|
||||
parent.classList.add("a");
|
||||
}
|
||||
child11111111110.classList.toggle("c");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(.b) .c' invalidation with multiple :has() anchor elements",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(.b) { color: green }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container class=a></div>
|
||||
<script>
|
||||
|
||||
function addChildren(element, numChildren, idPrefix)
|
||||
{
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.id = idPrefix + i;
|
||||
element.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTree(element, depth, fanOut, idPrefix)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return;
|
||||
addChildren(element, fanOut, idPrefix);
|
||||
for (var child = element.firstChild; child.nextSibling; child = child.nextSibling)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
if (child)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
}
|
||||
|
||||
makeTree(container, 11, 2, "child");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(.b)' invalidation with a single subject element",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(.b) { color: green }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container class=a></div>
|
||||
<script>
|
||||
|
||||
function makeTree(depth) {
|
||||
var parent = container;
|
||||
for (var i = 0; i < depth; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.classList.add("a");
|
||||
child.id = "child" + i;
|
||||
parent.appendChild(child);
|
||||
parent = child;
|
||||
}
|
||||
}
|
||||
|
||||
makeTree(100);
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
child99.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child99.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(.b)' invalidation with multiple subject elements in extream case.",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(.b) { color: green }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container class=a></div>
|
||||
<script>
|
||||
|
||||
function addChildren(element, numChildren, idPrefix)
|
||||
{
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.id = idPrefix + i;
|
||||
element.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTree(element, depth, fanOut, idPrefix)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return;
|
||||
addChildren(element, fanOut, idPrefix);
|
||||
for (var child = element.firstChild; child.nextSibling; child = child.nextSibling)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
if (child)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
}
|
||||
|
||||
makeTree(container, 11, 2, "child");
|
||||
for (var parent = child11111111111.parentElement;
|
||||
parent.id != "container";
|
||||
parent = parent.parentElement) {
|
||||
parent.classList.add("a");
|
||||
}
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(.b)' invalidation with multiple subject elements.",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,64 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(.b) { color: green }
|
||||
.a:has(.c) { color: blue }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container class=a></div>
|
||||
<script>
|
||||
|
||||
function addChildren(element, numChildren, idPrefix)
|
||||
{
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = document.createElement("div");
|
||||
let childId = idPrefix + i;
|
||||
if (childId == 'child0' || childId == 'child11111111111')
|
||||
child.id = childId;
|
||||
element.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTree(element, depth, fanOut, idPrefix)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return;
|
||||
addChildren(element, fanOut, idPrefix);
|
||||
let childIndex = 0;
|
||||
for (var child = element.firstChild; child.nextSibling;
|
||||
child = child.nextSibling) {
|
||||
makeTree(child, depth - 1, fanOut, idPrefix + childIndex);
|
||||
childIndex++;
|
||||
}
|
||||
if (child)
|
||||
makeTree(child, depth - 1, fanOut, idPrefix + childIndex);
|
||||
}
|
||||
|
||||
makeTree(container, 11, 2, "child");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(.b)' invalidation with a single subject and 1 non-matching :has() rule",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,68 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(.b) { color: green }
|
||||
.a:has(.c) { color: blue }
|
||||
.a:has(.d) { color: yellow }
|
||||
.a:has(.e) { color: red }
|
||||
.a:has(.f) { color: yellowgreen }
|
||||
.a:has(.g) { color: purple }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container class=a></div>
|
||||
<script>
|
||||
|
||||
function addChildren(element, numChildren, idPrefix)
|
||||
{
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = document.createElement("div");
|
||||
let childId = idPrefix + i;
|
||||
if (childId == 'child0' || childId == 'child11111111111')
|
||||
child.id = childId;
|
||||
element.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTree(element, depth, fanOut, idPrefix)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return;
|
||||
addChildren(element, fanOut, idPrefix);
|
||||
let childIndex = 0;
|
||||
for (var child = element.firstChild; child.nextSibling;
|
||||
child = child.nextSibling) {
|
||||
makeTree(child, depth - 1, fanOut, idPrefix + childIndex);
|
||||
childIndex++;
|
||||
}
|
||||
if (child)
|
||||
makeTree(child, depth - 1, fanOut, idPrefix + childIndex);
|
||||
}
|
||||
|
||||
makeTree(container, 11, 2, "child");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(.b)' invalidation with a single subject and 5 non-matching :has() rules",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(.b) { color: green }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container class=a></div>
|
||||
<script>
|
||||
|
||||
function addChildren(element, numChildren, idPrefix)
|
||||
{
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = document.createElement("div");
|
||||
let childId = idPrefix + i;
|
||||
if (childId == 'child0' || childId == 'child11111111111')
|
||||
child.id = childId;
|
||||
element.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTree(element, depth, fanOut, idPrefix)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return;
|
||||
addChildren(element, fanOut, idPrefix);
|
||||
let childIndex = 0;
|
||||
for (var child = element.firstChild; child.nextSibling;
|
||||
child = child.nextSibling) {
|
||||
makeTree(child, depth - 1, fanOut, idPrefix + childIndex);
|
||||
childIndex++;
|
||||
}
|
||||
if (child)
|
||||
makeTree(child, depth - 1, fanOut, idPrefix + childIndex);
|
||||
}
|
||||
|
||||
makeTree(container, 11, 2, "child");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child11111111111.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(.b)' invalidation with a single subject element and a matching :has() rule",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(.b) { color: red }
|
||||
.c:has(.d) { color: green }
|
||||
.e:has(.f) .g { color: blue }
|
||||
.e:has(.h) .i { color: navy }
|
||||
.e:has(.f.h) .j { color: lightgreen }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container class="a e"></div>
|
||||
<script>
|
||||
|
||||
function addChildren(element, numChildren, idPrefix)
|
||||
{
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.id = idPrefix + i;
|
||||
element.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTree(element, depth, fanOut, idPrefix)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return;
|
||||
addChildren(element, fanOut, idPrefix);
|
||||
for (var child = element.firstChild; child.nextSibling; child = child.nextSibling)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
if (child)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
}
|
||||
|
||||
makeTree(container, 3, 5, "child");
|
||||
|
||||
child21.classList.add('g');
|
||||
child22.classList.add('i')
|
||||
child23.classList.add('j');
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
// this should not invalidate any element.
|
||||
child22.classList.toggle('d');
|
||||
container.offsetHeight; // force recalc style
|
||||
child22.classList.toggle('d');
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
// this should invalidate only #child21
|
||||
child22.classList.toggle('f');
|
||||
container.offsetHeight; // force recalc style
|
||||
child22.classList.toggle('f');
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the :has() pseudo class invalidation filtering.",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(~ .b .c) { color: green }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container><div class=a></div></div>
|
||||
<script>
|
||||
|
||||
function addChildren(element, numChildren, idPrefix)
|
||||
{
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.id = idPrefix + i;
|
||||
element.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTree(element, depth, fanOut, idPrefix)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return;
|
||||
addChildren(element, fanOut, idPrefix);
|
||||
for (var child = element.firstChild; child.nextSibling; child = child.nextSibling) {
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
}
|
||||
if (child)
|
||||
makeTree(child, depth - 1, fanOut, child.id);
|
||||
}
|
||||
|
||||
for (var i = 0; i < 32; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.id = "child" + i;
|
||||
child.classList.add("b");
|
||||
container.appendChild(child);
|
||||
makeTree(child, 6, 2, child.id + "_")
|
||||
}
|
||||
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
child0_0.classList.toggle("c");
|
||||
container.offsetHeight; // force recalc style
|
||||
child0_0.classList.toggle("c");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
child31_111111.classList.toggle("c");
|
||||
container.offsetHeight; // force recalc style
|
||||
child31_111111.classList.toggle("c");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(~ .b .c)' invalidation with a single subject element.",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(~ .b .c) { color: green }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container></div></div>
|
||||
<script>
|
||||
|
||||
function makeTree(element, depth, children) {
|
||||
if (depth <= 0) {
|
||||
var child = document.createElement("div");
|
||||
child.id = 'sibling_descendant';
|
||||
element.appendChild(child);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < children - 1; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.classList.add("a");
|
||||
child.id = 'subject_' + depth + '_' + i;
|
||||
element.appendChild(child);
|
||||
}
|
||||
var child = document.createElement("div");
|
||||
child.classList.add("b");
|
||||
element.appendChild(child);
|
||||
makeTree(child, depth - 1, children);
|
||||
}
|
||||
|
||||
makeTree(container, 10, 10);
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
sibling_descendant.classList.toggle("c");
|
||||
container.offsetHeight; // force recalc style
|
||||
sibling_descendant.classList.toggle("c");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(~ .b .c)' invalidation with all subject elements.",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,45 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(~ .b) { color: green }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container><div class=a></div></div>
|
||||
<script>
|
||||
|
||||
function makeTree(siblings) {
|
||||
for (var i = 0; i < siblings; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.id = "child" + i;
|
||||
container.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
makeTree(2048);
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
child2047.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child2047.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(~ .b)' invalidation with a single subject element.",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
div { color: grey }
|
||||
.a:has(~ .b) { color: green }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container><div class=a></div></div>
|
||||
<script>
|
||||
|
||||
function makeTree(siblings) {
|
||||
for (var i = 0; i < siblings; i++) {
|
||||
var child = document.createElement("div");
|
||||
child.classList.add("a");
|
||||
child.id = "child" + i;
|
||||
container.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
makeTree(100);
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child0.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
|
||||
child99.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
child99.classList.toggle("b");
|
||||
container.offsetHeight; // force recalc style
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of the '.a:has(~ .b)' invalidation with all subject elements.",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<body>
|
||||
<main></main>
|
||||
<style>
|
||||
/* non-::selection rules required when HighlightInheritance is disabled */
|
||||
:root { --bg: blue; }
|
||||
.green:root { --bg: green; }
|
||||
*::selection /* same as ::selection */ {
|
||||
/* explicitly inherit all for worst case scenario */
|
||||
all: inherit;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
createDOMTree(document.querySelector("main"), 4, 6);
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Measure impact of highlight inheritance on content with universal ::selection rules (no selection, no paint)',
|
||||
run: () => {
|
||||
document.documentElement.classList.toggle("green");
|
||||
forceStyleRecalc(document.documentElement);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<body>
|
||||
<main></main>
|
||||
<style>
|
||||
main { word-wrap: break-word; }
|
||||
main div { display: inline; }
|
||||
:root { --bg: blue; }
|
||||
.green:root { --bg: green; }
|
||||
*::selection /* same as ::selection */ {
|
||||
/* explicitly inherit all for worst case scenario */
|
||||
all: inherit;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
createDOMTree(document.querySelector("main"), 4, 6);
|
||||
for (const leaf of document.querySelectorAll("div:empty"))
|
||||
leaf.append(".");
|
||||
const r = new Range;
|
||||
r.selectNodeContents(document.querySelector("main"));
|
||||
getSelection().removeAllRanges();
|
||||
getSelection().addRange(r);
|
||||
PerfTestRunner.measureFrameTime({
|
||||
description: 'Measure impact of highlight inheritance on content with universal ::selection rules (select all, with paint)',
|
||||
tracingCategories: "blink",
|
||||
traceEventsToMeasure: [
|
||||
"Document::updateStyle",
|
||||
"Document::recalcStyle",
|
||||
"LocalFrameView::RunPaintLifecyclePhase",
|
||||
],
|
||||
run: () => {
|
||||
document.documentElement.classList.toggle("green");
|
||||
forceStyleRecalc(document.documentElement);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
</body>
|
58
tests/blink_perf_tests/perf_tests/css/ImplicitAtScope.html
Normal file
58
tests/blink_perf_tests/perf_tests/css/ImplicitAtScope.html
Normal file
|
@ -0,0 +1,58 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<div id=root></div>
|
||||
<style>
|
||||
/* Explicit inheritance is used to trigger recalc of all elements. */
|
||||
* { z-index: inherit; }
|
||||
:root { z-index: 42; }
|
||||
</style>
|
||||
<script>
|
||||
|
||||
function setup() {
|
||||
createDOMTree(root, /* siblings */ 8, /* depth */ 4);
|
||||
|
||||
let leaf = document.querySelector('body div:empty');
|
||||
let style = document.createElement('style');
|
||||
|
||||
// Create many non-matching rules with an expensive selector
|
||||
// implicitly scoped to a leaf node in the tree.
|
||||
//
|
||||
// @scope {
|
||||
// :not(.a0, .a1, ... .aN):not(div) { --x: 0; }
|
||||
// :not(.a0, .a1, ... .aN):not(div) { --x: 1; }
|
||||
// .
|
||||
// .
|
||||
// .
|
||||
// :not(.a0, .a1, ... .aN):not(div) { --x: M; }
|
||||
// }
|
||||
style.textContent = (() => {
|
||||
const PSEUDO_NOT_COUNT = 50;
|
||||
let selector = `:not(${[...Array(PSEUDO_NOT_COUNT).keys()].map(x => `.a${x}`).join(', ')}):not(div)`;
|
||||
const RULES = 100;
|
||||
let rules = [...Array(RULES).keys()].map(x => `${selector} { --x:${x}; }`).join('\n');
|
||||
return `
|
||||
@scope {
|
||||
${rules}
|
||||
}
|
||||
`;
|
||||
})();
|
||||
leaf.append(style);
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
// Each iteration, we'll recalc all elements. Hopefully, the RuleSet within
|
||||
// the style element beneath the leaf node can be completely ignored for all
|
||||
// elements except `leaf`.
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'An implicit whole-RuleSet @scope deep in the tree',
|
||||
run: () => {
|
||||
root.offsetTop;
|
||||
root.style.zIndex = '43';
|
||||
root.offsetTop;
|
||||
root.style.zIndex = '42';
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<div id=root></div>
|
||||
<script>
|
||||
|
||||
function setup() {
|
||||
createDOMTree(root, /* siblings */ 8, /* depth */ 4);
|
||||
|
||||
let leaf = document.querySelector('#root div:empty');
|
||||
let leaf_style = document.createElement('style');
|
||||
|
||||
// Create many non-matching rules with an expensive selector
|
||||
// implicitly scoped to a leaf node in the tree.
|
||||
//
|
||||
// @scope {
|
||||
// :not(.a0, .a1, ... .aN):not(div) { --x: 0; }
|
||||
// :not(.a0, .a1, ... .aN):not(div) { --x: 1; }
|
||||
// .
|
||||
// .
|
||||
// .
|
||||
// :not(.a0, .a1, ... .aN):not(div) { --x: M; }
|
||||
// }
|
||||
leaf_style.textContent = (() => {
|
||||
const PSEUDO_NOT_COUNT = 50;
|
||||
let selector = `:not(${[...Array(PSEUDO_NOT_COUNT).keys()].map(x => `.a${x}`).join(', ')}):not(div)`;
|
||||
const RULES = 100;
|
||||
let rules = [...Array(RULES).keys()].map(x => `${selector} { --x:${x}; }`).join('\n');
|
||||
return `
|
||||
@scope {
|
||||
${rules}
|
||||
}
|
||||
`;
|
||||
})();
|
||||
|
||||
return [leaf, leaf_style];
|
||||
}
|
||||
|
||||
const [leaf, leaf_style] = setup();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Insertion of stylesheet with implicit @scope',
|
||||
run: () => {
|
||||
leaf.append(leaf_style);
|
||||
root.offsetTop;
|
||||
leaf_style.remove();
|
||||
root.offsetTop;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<main id=main></main>
|
||||
<style>
|
||||
/* Explicit inheritance is used to trigger recalc of all elements. */
|
||||
* { z-index: inherit; }
|
||||
:root { z-index: 42; }
|
||||
</style>
|
||||
<script>
|
||||
|
||||
g_counter = 0;
|
||||
|
||||
// Create a tree where *each* leaf node has a stylesheet
|
||||
// with an implict @scope rule (with a matching style rule inside).
|
||||
function createTree(siblings, depth) {
|
||||
let root = document.createElement('div');
|
||||
if (depth >= 2) {
|
||||
root.append(...[...Array(siblings).keys()].map(() => createTree(siblings, depth - 1)));
|
||||
} else {
|
||||
// Leaf nodes.
|
||||
root.classList.add('leaf');
|
||||
let style = document.createElement('style');
|
||||
style.textContent = `
|
||||
/* Prevent cache: ${g_counter++} */
|
||||
@scope {
|
||||
.leaf:scope { background-color: green; }
|
||||
}
|
||||
`;
|
||||
root.append(style);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
function setup() {
|
||||
let root = createTree(/* siblings */ 5, /* depth */ 5);
|
||||
main.append(root);
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Many implicit whole-RuleSet @scopes with matching rules',
|
||||
run: () => {
|
||||
main.offsetTop;
|
||||
main.style.zIndex = '43';
|
||||
main.offsetTop;
|
||||
main.style.zIndex = '42';
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<style id=style>
|
||||
.toggle { z-index: 42; }
|
||||
</style>
|
||||
<main id=root></main>
|
||||
<main id=unrelated></main>
|
||||
<script>
|
||||
|
||||
function createTree(siblings, depth) {
|
||||
let element = document.createElement('div');
|
||||
if (--depth > 0) {
|
||||
element.append(...[...Array(siblings).keys()].map(() => createTree(siblings, depth)));
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
let leafNodes = null;
|
||||
|
||||
function setup() {
|
||||
const NUM_IDENTICAL_STYLES = 1024;
|
||||
const NUM_CHAINS = 64;
|
||||
const CHAIN_DEPTH = 64;
|
||||
const STYLE = `
|
||||
@scope {
|
||||
:scope { z-index: 42; }
|
||||
}
|
||||
`;
|
||||
|
||||
// Insert many identical <style> elements into #unrelated.
|
||||
// We're not going to recalc styles for any elements in #unrelated,
|
||||
// so these styles only exist to share their StyleSheetContents
|
||||
// (and therefore share the same StyleScope) as the style added
|
||||
// beneath #root.
|
||||
for (let i = 0; i < NUM_IDENTICAL_STYLES; i++) {
|
||||
let style = document.createElement('style');
|
||||
style.textContent = STYLE;
|
||||
let div = document.createElement('div');
|
||||
div.append(style);
|
||||
unrelated.append(div);
|
||||
}
|
||||
|
||||
// Add a identical style to #root.
|
||||
let style = document.createElement('style');
|
||||
style.textContent = STYLE;
|
||||
root.append(style);
|
||||
|
||||
// Add NUM_CHAINS to root, where each child is the root of a linear
|
||||
// chain of descendants. These are separate linear chains instead
|
||||
// of a more realistic tree to avoid the on-stack cache (StyleScopeFrame).
|
||||
let chains = [...Array(NUM_CHAINS).keys()]
|
||||
.map(() => createTree(1 /* siblings */, CHAIN_DEPTH /* depth */));
|
||||
root.append(...chains);
|
||||
|
||||
// We'll recalc of all leaf nodes within #root during measureTime.
|
||||
// For each leaf, we'll traverse up the chain, trying to figure out
|
||||
// if the @scope added below #root is active or not. Hopefully,
|
||||
// the performance of figuring that out is not affected by the large
|
||||
// amount of identical styles in #unrelated.
|
||||
leafNodes = root.querySelectorAll('div:empty');
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Implicit @scope with identical unrelated styles',
|
||||
run: () => {
|
||||
root.offsetTop;
|
||||
leafNodes.forEach(e => e.classList.toggle('toggle'));
|
||||
root.offsetTop;
|
||||
leafNodes.forEach(e => e.classList.toggle('toggle'));
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
150
tests/blink_perf_tests/perf_tests/css/LoadBootstrapBlog.html
Normal file
150
tests/blink_perf_tests/perf_tests/css/LoadBootstrapBlog.html
Normal file
|
@ -0,0 +1,150 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Adapted from https://getbootstrap.com/examples/blog/ -->
|
||||
<div class="blog-masthead">
|
||||
<div class="container">
|
||||
<nav class="blog-nav">
|
||||
<a class="blog-nav-item active" href="#">Home</a>
|
||||
<a class="blog-nav-item" href="#">New features</a>
|
||||
<a class="blog-nav-item" href="#">Press</a>
|
||||
<a class="blog-nav-item" href="#">New hires</a>
|
||||
<a class="blog-nav-item" href="#">About</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="blog-header">
|
||||
<h1 class="blog-title">The Bootstrap Blog</h1>
|
||||
<p class="lead blog-description">The official example template of creating a blog with Bootstrap.</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 blog-main">
|
||||
<div class="blog-post">
|
||||
<h2 class="blog-post-title">Sample blog post</h2>
|
||||
<p class="blog-post-meta">January 1, 2014 by <a href="#">Mark</a></p>
|
||||
<p>This blog post shows a few different types of content that's supported and styled with Bootstrap. Basic typography, images, and code are all supported.</p>
|
||||
<hr>
|
||||
<p>Cum sociis natoque penatibus et magnis <a href="#">dis parturient montes</a>, nascetur ridiculus mus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>
|
||||
<blockquote>
|
||||
<p>Curabitur blandit tempus porttitor. <strong>Nullam quis risus eget urna mollis</strong> ornare vel eu leo. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
|
||||
</blockquote>
|
||||
<p>Etiam porta <em>sem malesuada magna</em> mollis euismod. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur.</p>
|
||||
<h2>Heading</h2>
|
||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
||||
<h3>Sub-heading</h3>
|
||||
<p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
<pre><code>Example code block</code></pre>
|
||||
<p>Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa.</p>
|
||||
<h3>Sub-heading</h3>
|
||||
<p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
|
||||
<ul>
|
||||
<li>Praesent commodo cursus magna, vel scelerisque nisl consectetur et.</li>
|
||||
<li>Donec id elit non mi porta gravida at eget metus.</li>
|
||||
<li>Nulla vitae elit libero, a pharetra augue.</li>
|
||||
</ul>
|
||||
<p>Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue.</p>
|
||||
<ol>
|
||||
<li>Vestibulum id ligula porta felis euismod semper.</li>
|
||||
<li>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</li>
|
||||
<li>Maecenas sed diam eget risus varius blandit sit amet non magna.</li>
|
||||
</ol>
|
||||
<p>Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis.</p>
|
||||
</div><!-- /.blog-post -->
|
||||
<div class="blog-post">
|
||||
<h2 class="blog-post-title">Another blog post</h2>
|
||||
<p class="blog-post-meta">December 23, 2013 by <a href="#">Jacob</a></p>
|
||||
<p>Cum sociis natoque penatibus et magnis <a href="#">dis parturient montes</a>, nascetur ridiculus mus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>
|
||||
<blockquote>
|
||||
<p>Curabitur blandit tempus porttitor. <strong>Nullam quis risus eget urna mollis</strong> ornare vel eu leo. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
|
||||
</blockquote>
|
||||
<p>Etiam porta <em>sem malesuada magna</em> mollis euismod. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur.</p>
|
||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
||||
</div><!-- /.blog-post -->
|
||||
<div class="blog-post">
|
||||
<h2 class="blog-post-title">New feature</h2>
|
||||
<p class="blog-post-meta">December 14, 2013 by <a href="#">Chris</a></p>
|
||||
<p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
|
||||
<ul>
|
||||
<li>Praesent commodo cursus magna, vel scelerisque nisl consectetur et.</li>
|
||||
<li>Donec id elit non mi porta gravida at eget metus.</li>
|
||||
<li>Nulla vitae elit libero, a pharetra augue.</li>
|
||||
</ul>
|
||||
<p>Etiam porta <em>sem malesuada magna</em> mollis euismod. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur.</p>
|
||||
<p>Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue.</p>
|
||||
</div><!-- /.blog-post -->
|
||||
<nav>
|
||||
<ul class="pager">
|
||||
<li><a href="#">Previous</a></li>
|
||||
<li><a href="#">Next</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div><!-- /.blog-main -->
|
||||
<div class="col-sm-3 col-sm-offset-1 blog-sidebar">
|
||||
<div class="sidebar-module sidebar-module-inset">
|
||||
<h4>About</h4>
|
||||
<p>Etiam porta <em>sem malesuada magna</em> mollis euismod. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur.</p>
|
||||
</div>
|
||||
<div class="sidebar-module">
|
||||
<h4>Archives</h4>
|
||||
<ol class="list-unstyled">
|
||||
<li><a href="#">March 2014</a></li>
|
||||
<li><a href="#">February 2014</a></li>
|
||||
<li><a href="#">January 2014</a></li>
|
||||
<li><a href="#">December 2013</a></li>
|
||||
<li><a href="#">November 2013</a></li>
|
||||
<li><a href="#">October 2013</a></li>
|
||||
<li><a href="#">September 2013</a></li>
|
||||
<li><a href="#">August 2013</a></li>
|
||||
<li><a href="#">July 2013</a></li>
|
||||
<li><a href="#">June 2013</a></li>
|
||||
<li><a href="#">May 2013</a></li>
|
||||
<li><a href="#">April 2013</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="sidebar-module">
|
||||
<h4>Elsewhere</h4>
|
||||
<ol class="list-unstyled">
|
||||
<li><a href="#">GitHub</a></li>
|
||||
<li><a href="#">Twitter</a></li>
|
||||
<li><a href="#">Facebook</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div><!-- /.blog-sidebar -->
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.container -->
|
||||
<footer class="blog-footer">
|
||||
<p>Blog template built for <a href="http://getbootstrap.com">Bootstrap</a> by <a href="https://twitter.com/mdo">@mdo</a>.</p>
|
||||
<p>
|
||||
<a href="#">Back to top</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- Performance test runner code below -->
|
||||
<script>
|
||||
var styleText = PerfTestRunner.loadFile("resources/bootstrap.min.css");
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of loading an example Bootstrap blog page.",
|
||||
run: function() {
|
||||
var style = applyCSSRule(styleText);
|
||||
forceStyleRecalc(document.body);
|
||||
style.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'CSSParserImpl::parseStyleSheet.parse',
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,179 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Adapted from here: http://materializecss.com/templates/starter-template/preview.html -->
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>Parallax Template - Materialize</title>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
<link href="resources/materialize.min.css" type="text/css" rel="stylesheet" media="screen,projection"/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<nav class="white" role="navigation">
|
||||
<div class="nav-wrapper container">
|
||||
<a id="logo-container" href="#" class="brand-logo">Logo</a>
|
||||
<ul class="right hide-on-med-and-down">
|
||||
<li><a href="#">Navbar Link</a></li>
|
||||
</ul>
|
||||
|
||||
<ul id="nav-mobile" class="side-nav">
|
||||
<li><a href="#">Navbar Link</a></li>
|
||||
</ul>
|
||||
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="index-banner" class="parallax-container">
|
||||
<div class="section no-pad-bot">
|
||||
<div class="container">
|
||||
<br><br>
|
||||
<h1 class="header center teal-text text-lighten-2">Parallax Template</h1>
|
||||
<div class="row center">
|
||||
<h5 class="header col s12 light">A modern responsive front-end framework based on Material Design</h5>
|
||||
</div>
|
||||
<div class="row center">
|
||||
<a href="http://materializecss.com/getting-started.html" id="download-button" class="btn-large waves-effect waves-light teal lighten-1">Get Started</a>
|
||||
</div>
|
||||
<br><br>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="parallax"><img src="background1.jpg" alt="Unsplashed background img 1"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div class="section">
|
||||
|
||||
<!-- Icon Section -->
|
||||
<div class="row">
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<h2 class="center brown-text"><i class="material-icons">flash_on</i></h2>
|
||||
<h5 class="center">Speeds up development</h5>
|
||||
|
||||
<p class="light">We did most of the heavy lifting for you to provide a default stylings that incorporate our custom components. Additionally, we refined animations and transitions to provide a smoother experience for developers.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<h2 class="center brown-text"><i class="material-icons">group</i></h2>
|
||||
<h5 class="center">User Experience Focused</h5>
|
||||
|
||||
<p class="light">By utilizing elements and principles of Material Design, we were able to create a framework that incorporates components and animations that provide more feedback to users. Additionally, a single underlying responsive system across all platforms allow for a more unified user experience.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<h2 class="center brown-text"><i class="material-icons">settings</i></h2>
|
||||
<h5 class="center">Easy to work with</h5>
|
||||
|
||||
<p class="light">We have provided detailed documentation as well as specific code examples to help new users get started. We are also always open to feedback and can answer any questions a user may have about Materialize.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="parallax-container valign-wrapper">
|
||||
<div class="section no-pad-bot">
|
||||
<div class="container">
|
||||
<div class="row center">
|
||||
<h5 class="header col s12 light">A modern responsive front-end framework based on Material Design</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="parallax"><img src="background2.jpg" alt="Unsplashed background img 2"></div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="section">
|
||||
|
||||
<div class="row">
|
||||
<div class="col s12 center">
|
||||
<h3><i class="mdi-content-send brown-text"></i></h3>
|
||||
<h4>Contact Us</h4>
|
||||
<p class="left-align light">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam scelerisque id nunc nec volutpat. Etiam pellentesque tristique arcu, non consequat magna fermentum ac. Cras ut ultricies eros. Maecenas eros justo, ullamcorper a sapien id, viverra ultrices eros. Morbi sem neque, posuere et pretium eget, bibendum sollicitudin lacus. Aliquam eleifend sollicitudin diam, eu mattis nisl maximus sed. Nulla imperdiet semper molestie. Morbi massa odio, condimentum sed ipsum ac, gravida ultrices erat. Nullam eget dignissim mauris, non tristique erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="parallax-container valign-wrapper">
|
||||
<div class="section no-pad-bot">
|
||||
<div class="container">
|
||||
<div class="row center">
|
||||
<h5 class="header col s12 light">A modern responsive front-end framework based on Material Design</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="parallax"><img src="background3.jpg" alt="Unsplashed background img 3"></div>
|
||||
</div>
|
||||
|
||||
<footer class="page-footer teal">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col l6 s12">
|
||||
<h5 class="white-text">Company Bio</h5>
|
||||
<p class="grey-text text-lighten-4">We are a team of college students working on this project like it's our full time job. Any amount would help support and continue development on this project and is greatly appreciated.</p>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col l3 s12">
|
||||
<h5 class="white-text">Settings</h5>
|
||||
<ul>
|
||||
<li><a class="white-text" href="#!">Link 1</a></li>
|
||||
<li><a class="white-text" href="#!">Link 2</a></li>
|
||||
<li><a class="white-text" href="#!">Link 3</a></li>
|
||||
<li><a class="white-text" href="#!">Link 4</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col l3 s12">
|
||||
<h5 class="white-text">Connect</h5>
|
||||
<ul>
|
||||
<li><a class="white-text" href="#!">Link 1</a></li>
|
||||
<li><a class="white-text" href="#!">Link 2</a></li>
|
||||
<li><a class="white-text" href="#!">Link 3</a></li>
|
||||
<li><a class="white-text" href="#!">Link 4</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-copyright">
|
||||
<div class="container">
|
||||
Made by <a class="brown-text text-lighten-3" href="http://materializecss.com">Materialize</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Performance test runner code below -->
|
||||
<script>
|
||||
var styleText = PerfTestRunner.loadFile("resources/materialize.min.css");
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of Materialize framework on a canonical page",
|
||||
run: function() {
|
||||
var style = applyCSSRule(styleText);
|
||||
forceStyleRecalc(document.body);
|
||||
style.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'CSSParserImpl::parseStyleSheet.parse',
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,184 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- saved from url=(0044)https://semantic-ui.com/examples/sticky.html -->
|
||||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<!-- Standard Meta -->
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
|
||||
|
||||
<!-- Site Properties -->
|
||||
<title>Sticky Example - Semantic</title>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/utils.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="ui main text container">
|
||||
<h1 class="ui header">Sticky Example</h1>
|
||||
<p>This example shows how to use lazy loaded images, a sticky menu, and a simple text container</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="ui borderless main menu">
|
||||
<div class="ui text container">
|
||||
<div href="#" class="header item">
|
||||
<img class="logo" src="./LoadSemanticPageExample_files/logo.png">
|
||||
Project Name
|
||||
</div>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Blog</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Articles</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="ui right floated dropdown item" tabindex="0">
|
||||
Dropdown <i class="dropdown icon"></i>
|
||||
<div class="menu" tabindex="-1">
|
||||
<div class="item">Link Item</div>
|
||||
<div class="item">Link Item</div>
|
||||
<div class="divider"></div>
|
||||
<div class="header">Header Item</div>
|
||||
<div class="item">
|
||||
<i class="dropdown icon"></i>
|
||||
Sub Menu
|
||||
<div class="menu">
|
||||
<div class="item">Link Item</div>
|
||||
<div class="item">Link Item</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">Link Item</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div><div class="ui borderless main menu placeholder" style="display: none;">
|
||||
<div class="ui text container">
|
||||
<div href="#" class="header item">
|
||||
<img class="logo" src="./LoadSemanticPageExample_files/logo.png">
|
||||
Project Name
|
||||
</div>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Blog</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Articles</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="ui right floated dropdown item" tabindex="0">
|
||||
Dropdown <i class="dropdown icon"></i>
|
||||
<div class="menu" tabindex="-1">
|
||||
<div class="item">Link Item</div>
|
||||
<div class="item">Link Item</div>
|
||||
<div class="divider"></div>
|
||||
<div class="header">Header Item</div>
|
||||
<div class="item">
|
||||
<i class="dropdown icon"></i>
|
||||
Sub Menu
|
||||
<div class="menu">
|
||||
<div class="item">Link Item</div>
|
||||
<div class="item">Link Item</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">Link Item</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui text container">
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<div class="overlay">
|
||||
<div class="ui labeled icon vertical menu">
|
||||
<a class="item"><i class="twitter icon"></i> Tweet</a>
|
||||
<a class="item"><i class="facebook icon"></i> Share</a>
|
||||
<a class="item"><i class="mail icon"></i> E-mail</a>
|
||||
</div>
|
||||
</div><div class="overlay placeholder" style="display: none;">
|
||||
<div class="ui labeled icon vertical menu">
|
||||
<a class="item"><i class="twitter icon"></i> Tweet</a>
|
||||
<a class="item"><i class="facebook icon"></i> Share</a>
|
||||
<a class="item"><i class="mail icon"></i> E-mail</a>
|
||||
</div>
|
||||
</div>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<img class="ui medium left floated image" data-src="assets/images/wireframe/square-image.png">
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
|
||||
<img class="ui medium right floated image" data-src="assets/images/wireframe/square-image.png">
|
||||
Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<img class="ui medium left floated image" data-src="assets/images/wireframe/square-image.png">
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
|
||||
<img class="ui medium right floated image" data-src="assets/images/wireframe/square-image.png">
|
||||
Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
|
||||
</div>
|
||||
|
||||
<div class="ui inverted vertical footer segment">
|
||||
<div class="ui center aligned container">
|
||||
<div class="ui stackable inverted divided grid">
|
||||
<div class="three wide column">
|
||||
<h4 class="ui inverted header">Group 1</h4>
|
||||
<div class="ui inverted link list">
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link One</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link Two</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link Three</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link Four</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="three wide column">
|
||||
<h4 class="ui inverted header">Group 2</h4>
|
||||
<div class="ui inverted link list">
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link One</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link Two</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link Three</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link Four</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="three wide column">
|
||||
<h4 class="ui inverted header">Group 3</h4>
|
||||
<div class="ui inverted link list">
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link One</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link Two</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link Three</a>
|
||||
<a href="https://semantic-ui.com/examples/sticky.html#" class="item">Link Four</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="seven wide column">
|
||||
<h4 class="ui inverted header">Footer Header</h4>
|
||||
<p>Extra space for a call to action inside the footer that could help re-engage users.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui inverted section divider"></div>
|
||||
<img src="./LoadSemanticPageExample_files/logo.png" class="ui centered mini image">
|
||||
<div class="ui horizontal inverted small divided link list">
|
||||
<a class="item" href="https://semantic-ui.com/examples/sticky.html#">Site Map</a>
|
||||
<a class="item" href="https://semantic-ui.com/examples/sticky.html#">Contact Us</a>
|
||||
<a class="item" href="https://semantic-ui.com/examples/sticky.html#">Terms and Conditions</a>
|
||||
<a class="item" href="https://semantic-ui.com/examples/sticky.html#">Privacy Policy</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<!-- Performance test runner code below -->
|
||||
<script>
|
||||
var styleText = PerfTestRunner.loadFile("resources/semantic.min.css");
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures the performance of Semantic-UI framework on a canonical page",
|
||||
run: function() {
|
||||
var style = applyCSSRule(styleText);
|
||||
forceStyleRecalc(document.body);
|
||||
style.remove();
|
||||
forceStyleRecalc(document.body);
|
||||
},
|
||||
tracingCategories: 'blink',
|
||||
traceEventsToMeasure: [
|
||||
'CSSParserImpl::parseStyleSheet.parse',
|
||||
'Document::updateStyle',
|
||||
'Document::recalcStyle',
|
||||
'Document::rebuildLayoutTree'
|
||||
]
|
||||
});
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style id="sheet">
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
let style_text = '';
|
||||
for (let i = 0; i < 10000; ++i) {
|
||||
style_text += '.class' + i + ' { color: red; }';
|
||||
}
|
||||
sheet.innerHTML = style_text;
|
||||
|
||||
var runFunction = function()
|
||||
{
|
||||
document.styleSheets[0].cssRules[9999].selectorText = '#random' + Math.floor(Math.random() * 10000000);
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of modifying selectorText on a rule late in the stylesheet",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<style>
|
||||
#root {
|
||||
container-type: size;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
#root.name {
|
||||
container-name: root;
|
||||
}
|
||||
</style>
|
||||
<div id=root class=name></div>
|
||||
|
||||
<!-- Populated with result of `makeContainerQueries(N)` -->
|
||||
<style id=query></style>
|
||||
|
||||
<script>
|
||||
// Returns `ruleCount` @container rules which all query 'root':
|
||||
//
|
||||
// @container root (width > 1px) { #dependent { } }
|
||||
// @container root (width > 1px) { #dependent { } }
|
||||
// @container root (width > 1px) { #dependent { } }
|
||||
// ...
|
||||
// @container root (width > 1px) { #dependent { } }
|
||||
// }
|
||||
function makeContainerQueries(ruleCount) {
|
||||
let rules = [];
|
||||
for (let i = 0; i < ruleCount; i++)
|
||||
rules.push(`@container root (width > 1px) { #dependent { } }`);
|
||||
return rules.join('\n');
|
||||
}
|
||||
|
||||
function setup() {
|
||||
query.textContent = makeContainerQueries(10000);
|
||||
|
||||
createDOMTree(root, 1 /* siblings */, 1000 /* depth */);
|
||||
let inner = root.querySelector('div:empty');
|
||||
inner.textContent = 'Test';
|
||||
inner.setAttribute('id', 'dependent');
|
||||
inner.parentElement.style.container = 'other / size';
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Looking up the same named container many times',
|
||||
run: () => {
|
||||
root.classList.toggle('name');
|
||||
root.offsetHeight;
|
||||
},
|
||||
done: () => {
|
||||
root.remove();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<style id=style>
|
||||
</style>
|
||||
<script>
|
||||
const DECLARATIONS = 200;
|
||||
const VALUE_LENGTH = 2000;
|
||||
|
||||
function makeStyle() {
|
||||
let declarations = [];
|
||||
|
||||
let value = [...Array(VALUE_LENGTH).keys()].map(() => 'X').join(' ');
|
||||
|
||||
for (let i = 0; i < DECLARATIONS; i++) {
|
||||
declarations.push(`background: invalid-thing-${i}(${value});`);
|
||||
}
|
||||
|
||||
return `
|
||||
div {
|
||||
${declarations.join('\n')}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
let globalCounter = 0;
|
||||
const stylesheetText = makeStyle();
|
||||
let stylesheet = new CSSStyleSheet();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Performance of parsing many invalid declarations',
|
||||
run: () => {
|
||||
// This is a parsing test: we don't care about style recalc.
|
||||
// We append a rule based on globalCounter to prevent caching
|
||||
// on the stylesheet string.
|
||||
stylesheet.replaceSync(stylesheetText + `\n .b${globalCounter++} {}`);
|
||||
style.textContent = stylesheetText;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<script>
|
||||
const RULES = 200;
|
||||
const DECLARATIONS_PER_RULE = 10;
|
||||
|
||||
// This test is the same as NestingIdentNonProperty.html, except that the
|
||||
// first ident is a known CSS property, instead of 'not-a-property'.
|
||||
function makeStyle() {
|
||||
let rules = [];
|
||||
|
||||
for (let i = 0; i < RULES; i++) {
|
||||
rules.push(`
|
||||
width:is(.a${i}) {
|
||||
${[...Array(DECLARATIONS_PER_RULE).keys()]
|
||||
.map(x => `--x${x}:a b c d e f g;`).join('\n')}
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
return `
|
||||
div {
|
||||
${rules.join('\n')}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
let globalCounter = 0;
|
||||
const stylesheetText = makeStyle();
|
||||
let stylesheet = new CSSStyleSheet();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Many nested rules that look like width declarations',
|
||||
run: () => {
|
||||
// This is a parsing test: we don't care about style recalc.
|
||||
// We append a rule based on globalCounter to prevent caching
|
||||
// on the stylesheet string.
|
||||
stylesheet.replaceSync(stylesheetText + `\n .b${globalCounter++} {}`);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<script>
|
||||
const DECLARATIONS = 400;
|
||||
const TRAILING_TOKENS_PER_DECLARATION = 1000;
|
||||
|
||||
// Makes many (invalid) width-declarations where {} appears at the start of
|
||||
// the the value, with lots of trailing tokens after.
|
||||
function makeStyle() {
|
||||
let rules = [];
|
||||
|
||||
for (let i = 0; i < DECLARATIONS; i++) {
|
||||
// Note: The '$$$' is there to ensure that we back out of selector
|
||||
// parsing early. Without that, we'd parse a valid selector out of
|
||||
// 'foo0 foo1 foo2 ... fooN' (consisting of 1000 compounds),
|
||||
// and that is not the situation we're worried about the most.
|
||||
// We primarily care about high performance in the far more likely
|
||||
// scenario that we discover an invalid selector early on.
|
||||
rules.push(`width: {} $$$
|
||||
${[...Array(TRAILING_TOKENS_PER_DECLARATION).keys()]
|
||||
.map(x => `foo${x}`).join(' ')}
|
||||
;`);
|
||||
}
|
||||
|
||||
return `
|
||||
div {
|
||||
${rules.join('\n')}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
let globalCounter = 0;
|
||||
const stylesheetText = makeStyle();
|
||||
let stylesheet = new CSSStyleSheet();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Many invalid width declarations with braces at the start',
|
||||
run: () => {
|
||||
// This is a parsing test: we don't care about style recalc.
|
||||
// We append a rule based on globalCounter to prevent caching
|
||||
// on the stylesheet string.
|
||||
stylesheet.replaceSync(stylesheetText + `\n .b${globalCounter++} {}`);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<script>
|
||||
const RULES = 200;
|
||||
const DECLARATIONS_PER_RULE = 10;
|
||||
|
||||
// Returns a style like this:
|
||||
//
|
||||
// div {
|
||||
// not-a-property:is(.a0) {
|
||||
// --x0: a b c d e f g;
|
||||
// --x1: a b c d e f g;
|
||||
// ...
|
||||
// --x9: a b c d e f g;
|
||||
// }
|
||||
//
|
||||
// not-a-property:is(.a1) {
|
||||
// --x0: a b c d e f g;
|
||||
// --x1: a b c d e f g;
|
||||
// ...
|
||||
// --x9: a b c d e f g;
|
||||
// }
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// not-a-property:is(.a99) {
|
||||
// --x0: a b c d e f g;
|
||||
// --x1: a b c d e f g;
|
||||
// ...
|
||||
// --x9: a b c d e f g;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Each nested rule looks like a declaration, because it's an ident followed by
|
||||
// a colon. This case can be optimized by an implementation that recognizes
|
||||
// early (enough) that not-a-property is not a known property.
|
||||
function makeStyle() {
|
||||
let rules = [];
|
||||
|
||||
for (let i = 0; i < RULES; i++) {
|
||||
rules.push(`
|
||||
not-a-property:is(.a${i}) {
|
||||
${[...Array(DECLARATIONS_PER_RULE).keys()]
|
||||
.map(x => `--x${x}:a b c d e f g;`).join('\n')}
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
return `
|
||||
div {
|
||||
${rules.join('\n')}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
let globalCounter = 0;
|
||||
const stylesheetText = makeStyle();
|
||||
let stylesheet = new CSSStyleSheet();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Many nested rules that look like declarations',
|
||||
run: () => {
|
||||
// This is a parsing test: we don't care about style recalc.
|
||||
// We append a rule based on globalCounter to prevent caching
|
||||
// on the stylesheet string.
|
||||
stylesheet.replaceSync(stylesheetText + `\n .b${globalCounter++} {}`);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
2
tests/blink_perf_tests/perf_tests/css/OWNERS
Normal file
2
tests/blink_perf_tests/perf_tests/css/OWNERS
Normal file
|
@ -0,0 +1,2 @@
|
|||
file://third_party/blink/renderer/core/css/OWNERS
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div id="test-target">
|
||||
<div>
|
||||
<div></div>
|
||||
<div>
|
||||
<p></p>
|
||||
<p></p>
|
||||
<p></p>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p></p>
|
||||
</div>
|
||||
</div>
|
||||
<p></p>
|
||||
<p></p>
|
||||
<p></p>
|
||||
<p></p>
|
||||
</div>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script>
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "This benchmark tests CSS Selector performance with querySelector().",
|
||||
run: function() {
|
||||
for (var i = 0; i < 100; i++) {
|
||||
document.querySelector("p:first-child");
|
||||
document.querySelector("p:last-child");
|
||||
document.querySelector("p:first-of-type");
|
||||
document.querySelector("p:last-of-type");
|
||||
document.querySelector("p:nth-child(4n+3)");
|
||||
document.querySelector("p:nth-last-child(4n+3)");
|
||||
document.querySelector("p:nth-of-type(4n+3)");
|
||||
document.querySelector("p:nth-last-of-type(4n+3)");
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="./resources/utils.js"></script>
|
||||
<style>
|
||||
.ancestor ::-webkit-scrollbar-corner { background-color: red; }
|
||||
.ancestor ::-webkit-scrollbar-thumb { background-color: red; }
|
||||
.ancestor ::-webkit-scrollbar-track { background-color: red; }
|
||||
</style>
|
||||
<div id="root"></div>
|
||||
|
||||
<script>
|
||||
function setup() {
|
||||
createDOMTree(root, 1 /* siblings */, 500 /* depth */);
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Calculate styles for a tree of elements affected by scrollbar part pseudo',
|
||||
run: () => {
|
||||
root.classList.add("ancestor");
|
||||
root.offsetHeight;
|
||||
},
|
||||
teardown: () => {
|
||||
root.classList.remove("ancestor");
|
||||
root.offsetHeight;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
.root .child {}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
function insertStyleSheet(css)
|
||||
{
|
||||
var styleElement = document.createElement("style");
|
||||
styleElement.textContent = css;
|
||||
document.head.appendChild(styleElement);
|
||||
return styleElement;
|
||||
}
|
||||
|
||||
function cssStrWithClassSelectors(count) {
|
||||
var selector = '.a' + count + ' .b' + count + ' { cursor: crosshair } ';
|
||||
// Intentionally repeat the same classes many times, to test duplicate optimizations.
|
||||
return selector + selector + selector + selector + selector + selector + selector;
|
||||
}
|
||||
|
||||
function cssStrWithAttributeSelectors(count) {
|
||||
var selector = '[attrA' + count + '="1"]' + ' [attrB' + count + '="1"]' + ' { cursor: crosshair } ';
|
||||
// Intentionally repeat the same classes many times, to test duplicate optimizations.
|
||||
return selector + selector + selector + selector + selector + selector + selector;
|
||||
}
|
||||
|
||||
function runFunction()
|
||||
{
|
||||
var numRules = 1000;
|
||||
var arr = new Array(numRules);
|
||||
for (var i = 0 ; i < numRules; i++) {
|
||||
arr[i] = cssStrWithClassSelectors(i);
|
||||
}
|
||||
for (var i = 0 ; i < numRules; i++) {
|
||||
arr[numRules + i] = cssStrWithAttributeSelectors(i);
|
||||
}
|
||||
var styleElement = insertStyleSheet(arr.join(' '));
|
||||
|
||||
// Force style recalc.
|
||||
document.body.offsetTop;
|
||||
|
||||
styleElement.parentNode.removeChild(styleElement);
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of inserting a stylesheet of 2000 different CSS rules, each of which is duplicated 7 times to test duplicate rule optimizations.",
|
||||
run: runFunction
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
6
tests/blink_perf_tests/perf_tests/css/resources/bootstrap.min.css
vendored
Normal file
6
tests/blink_perf_tests/perf_tests/css/resources/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
16
tests/blink_perf_tests/perf_tests/css/resources/materialize.min.css
vendored
Normal file
16
tests/blink_perf_tests/perf_tests/css/resources/materialize.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
364
tests/blink_perf_tests/perf_tests/css/resources/semantic.min.css
vendored
Normal file
364
tests/blink_perf_tests/perf_tests/css/resources/semantic.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
33
tests/blink_perf_tests/perf_tests/css/resources/utils.js
Normal file
33
tests/blink_perf_tests/perf_tests/css/resources/utils.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
function createDOMTree(node, siblings, depth) {
|
||||
if (!depth)
|
||||
return;
|
||||
for (var i=0; i<siblings; i++) {
|
||||
var div = document.createElement("div");
|
||||
node.appendChild(div);
|
||||
createDOMTree(div, siblings, depth-1);
|
||||
}
|
||||
}
|
||||
|
||||
function createDeepDOMTree() {
|
||||
createDOMTree(document.body, 2, 10);
|
||||
}
|
||||
|
||||
function createShallowDOMTree() {
|
||||
createDOMTree(document.body, 10, 2);
|
||||
}
|
||||
|
||||
function createRegularDOMTree() {
|
||||
createDOMTree(document.body, 4, 4);
|
||||
}
|
||||
|
||||
function forceStyleRecalc(node) {
|
||||
node.offsetTop; // forces style recalc
|
||||
}
|
||||
|
||||
function applyCSSRule(rule) {
|
||||
var css = document.createElement("style");
|
||||
css.type = "text/css";
|
||||
css.innerHTML = rule;
|
||||
document.body.appendChild(css);
|
||||
return css;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue