xml-plus
xml-plus copied to clipboard
Chrome Extension to display XML files
XML Plus
Chrome Extension to display XML files built with Vue
Features
-
Supports both
CSSandXPathselectors. -
Supports text search and
Regular Expressionsearch. -
Both
querySelectorAllandjQueryflavors of CSS selectors are available. -
RegExis the only CASE-INSENSITIVE one. -
Highly optimized for large XML files ( > 1MB ).
-
Stand-alone version - extremely fast because of avoiding Chrome's slow loading process.
-
Global
xvariable (window.x) is available in DevTools which includes:doc- raw XML document objectroot- root XML element objectcur- current selected node$- jQuery bound on root elementhistory- search results$q- helper for jQuery searchcs- helper for CSS searchre- helper for RegEx searchtx- helper for Text searchxp- helper for XPath search
Above helpers are
(expression, baseElement = root) => []and searching onbaseElementwhich isx.rootby default.
Links
- Online Demo - Remote links are very UNLIKELY working due to same-origin policy. Local files should be fine.
- Github Repo
- Report Bug
- Chrome Extension
TO-DOs
- [ ] Add some themes
- [ ] Able to customize CSS
- [ ] More optimization
Development
Libraries and techs used
VueVuexlodash/debouncejQuerydocument.querySelectorAlldocument.evaluateforXPathbestzipfor packaging
Dev Mode
yarn devornpm run dev- Open
http://localhost:8080/to start debugging. - Folder
tests/will be served at the same time with CORS, sohttp://localhost:8080/xml/default.xmlis available.
Test as Chrome Extension
yarn watchornpm run watch- Drag and drop
distfolder into Chrome's Extensions page
Build Static Website
yarn website or npm run website
Target folder is
public
Advanced
Proxy
You can also pass PROXY env variable to enable proxy. For example,
PROXY="https://my.proxy/get?url=" yarn website
When fetching https://foo.bar/baz.xml, it will get https://my.proxy/get?url=https%3A%2F%2Ffoo.bar%2Fbaz.xml instead. You can implement your own proxy with CORS.
There is an example for webtask:
const zlib = require('zlib');
const fetch = require('node-fetch'); // 3rd-party
module.exports = async (context, req, res) => {
const { url } = context.query;
if (!url) {
res.writeHead(400, { 'Content-Type': 'text/plain'});
res.end('Required query string `url`');
return;
}
try {
const response = await fetch(url);
const { headers } = response;
Array.from(headers.keys()).forEach((key) => {
if (key === 'content-type') {
res.setHeader('Content-Type', headers.get(key));
}
});
res.writeHead(response.status, {
'Access-Control-Allow-Origin': '*', // IMPORTANT: enables CORS. You can restrict it to your own domain names.
'Content-Encoding': 'deflate',
'Cache-Control': 'max-age=3600',
});
zlib.deflate(await response.buffer(), (err, buff) => {
if (err) throw err;
res.end(buff);
});
} catch (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end(err.message);
}
};
Chrome Extension
yarn watchornpm run watchto build dev indistfolderyarn buildornpm run buildto build prod versionyarn deployornpm run deploywill build and getdeploy/xml-plus.zipready for Chrome store
Others
Benchmarks
Candidates
- Chrome - the browser itself
** * *** ****- Another Extension available on Chrome Store and open-sourced on Github. Will useXto represent it.- XML Plus
Method
- Serve XML files on localhost
- Open Chrome Developer Tools
- Turn-on/off Extension to test
- Kill the tab in Chrome Task Manager to avoid memory operation
- Empty Cache and Hard Reload XML file via local network
- Repeat step 4 to 5 and skip the first read.
Since Extension
Xneeds more time to render the page, I put some extra code to calculate real time. The code is something like:
```js
document.addEventListener('readystatechange', function() {
console.time('ready');
// ... main code
});
// Inside another function
function xxx() {
sendMessage(..., function () {
// ...
sendMessage(..., function () {
// ... it will generate DOM here
setTimeout(() => {
console.timeEnd('ready');
}, 0);
});
});
}
```
Results
-
Round 1: 2MiB XML file (Total 41248 nodes; Max Depth: 5)
- Chrome: 14.55s, 14.34s, 15.19s
- X: 3.54s + 1141ms, 3.46s + 738ms, 2.94s + 898ms
- XML Plus: 4.12s, 3.89s. 4.18s
-
Round 2: 5.2MiB XML file (Total 113126 nodes; Max Depth: 4)
- Chrome: 34.10s, 34.82s, 33.9s (7.7s~8.0s
DOMContentLoaded) - X: 8.50s + 3968ms, 8.74s + 3976ms, 8.44s + 3965ms (7.7s~8.0s
DOMContentLoaded) - XML Plus: 7.32s, 7.30s, 7.50s (4.8s~5.0s
DOMContentLoaded)
- Chrome: 34.10s, 34.82s, 33.9s (7.7s~8.0s
-
Round 3: 14.4MiB XML file (Total 307067 nodes; Max Depth: 4)
- Chrome: 3.2min (~42s
DOMContentLoaded) - X: 43.72s + 17449ms (~42s
DOMContentLoaded) - XML Plus: 22.32s, 24.01s, 22.04s (13.6s~15.8s
DOMContentLoaded)
- Chrome: 3.2min (~42s
- Some Conclusions:
DOMContentLoadedis not avoidable.text/xmlandapplication/xmltake much longer time thantext/plainwhich I used. If you know a better way to make Chrome avoid rendering while processing responses, please let me know!- Chrome will take 1.1min+ If you don't End Process in Task Manager. It will take much longer if the tab used too much memory.
- In Round 2 you can see the styles of X will be applied after
ready, while in Round 3 it took 7s+ to apply styles.
Environment
Windows 10 1803 x64
Intel i7-6700K
32G RAM
Chrome v71.0.3578.98 x64