rel="preload" loads a resource early for the current document before the body is parsed, potentially saving overall loading time.
As a hint with a lower priority, rel="prefetch" caches a resource for the next navigation after the current document has been loaded.
Lorem ipsum dolor sit amet.
vs
preload is a declarative fetch, allowing you to force the browser to make a request for a resource without blocking the document’s onload event.
Prefetch is a hint to the browser that a resource might be needed, but delegates deciding whether and when loading it is a good idea or not to the browser.
preload
<link rel="preload"> tells the browser to download and cache a resource (like a script or a stylesheet) as soon as possible. It’s helpful when you need that resource a few seconds after loading the page, and you want to speed it up.
The browser doesn’t do anything with the resource after downloading it. Scripts aren’t executed, stylesheets aren’t applied. It’s just cached – so that when something else needs it, it’s available immediately.
prefetch
<link rel="prefetch"> asks the browser to download and cache a resource (like, a script or a stylesheet) in the background. The download happens with a low priority, so it doesn’t interfere with more important resources. It’s helpful when you know you’ll need that resource on a subsequent page, and you want to cache it ahead of time.
The browser doesn’t do anything with the resource after downloading it. Scripts aren’t executed, stylesheets aren’t applied. It’s just cached – so that when something else needs it, it’s available immediately.
I noticed some concepts in Qedy ain't right. For instance, I always perceived Modal window as a separate entity, but in fact it's just bit more complicated QView. This also once again confirms, that my choice of just four component types (elem, form, list, view) is indeed sufficient.
Similar problem was with various frontend perks, like content prefetching or smooth scrolling. I added prefetch to an ordinary QList as f_prefetch
feature and I created some extensions (“plugins”) for QView_Page.
http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html
https://github.com/nikic/FastRoute
https://benhoyt.com/writings/go-routing/
You have several options, how to route HTTP requests. My habit is to find the fastest way, but it's not needed here, because the router is called only once on URL change.
Loop through pre-compiled regexes or patterns and pass matches using the request context
Or use directly the HTTP method:
A switch statement with cases that call a regex-based match()
helper which scans path parameters into variables.
Similar to regex match, but using a simple pattern matching function instead of regexes. It's not that powerful, but you will mostly need “anything” wildcard for a path part anyway.
Split the path on /
and then switch on the contents of the path segments
Basically delegates the route matching to the module, according to the first path part. For a/b/c
path the router will call an “a” module, pass him [b,c]
and don't care any more.
You have several options when it comes to icons on a web. The oldest way is to use images (GIF, later PNG), but they may look blurry on today's high DPI displays. You can use SVG, which is great, scales great, but may become CPU heavy and are harder to recolor on hover events. And then you have font icons.
Microns
Icomoon
Font Awesome 3
Font Awesome 4
If I find reengineering favorable, I usually go for it. Therefore major versions with breaking changes appear fairly quickly in the beginning of a new software product, allowing me to stabilize the API as soon as possible.
On the other hand, most changes are in QedyJS, so unfortunately almost none of the current improvements will go open source.
Scopes. Multiple modules at once, scope is passed with the component, which is no problem in most cases. But it's a little annoying, since I decided to have no cirucular references, which means a component can't contain scope object and therefore I have to pass component and scope separately in two parameters. And for the rest you must specify the scope, which is also annoying, but also necessary.
Speaking of scopes, I reimagined JavaScript scopes as well. Now module methods have direct access to the scope via this
and because I decided to “trust” converters, they have now direct access to components and therefore are able to modify them. It makes a lot of things much easier and more streamlined.
I waited with a release many months, to have full functionality right from the start. Nothing was postponed (like datastores in Mk. II), because that's what bit me in the butt in the past the most.
Found even more great articles and talks about JS performance and did tremendous amount of micro optimizations in the code, especially in loops, where it makes sense the most. Some (if not most) of them are probably unnecessary, but I'm a performance freak, so it feels good to have 'em all :-)
Got rid of domLinks, now links are bundled with the component. The same applies for items and data-realted logic (e.g. sorting and filtering) were moved from components to datastores.
Some of original designs are great and in fact some of them even goes back to Mk. I. And don't let me start with the whole concept of QetriX, I must admin it makes me proud the core basics I established over a decade ago still works perfectly.
Browsers and especially Chromium based ones offers a lot of information about the device it's running on in various APIs. They are great if you want to tailor the experience for your users.
Some of such APIs are in Navigator interface, accessible as read-only object from window.navigator property.
navigator.connection
: .effectiveType (how fast), .saveData (data saver preference)
navigator.deviceMemory
: reducing memory consumption
navigator.hardwareConcurrency
: limit CPU intensive logic and effects
Those APIs also could be abused. There's a rumor one Booking site used now deprecated Battery Status API to crank up prices when your Android phone was running low on juice and therefore you probably didn't have much time to think and compare.
In recent years browser manufacturers added an additional security checks for third party content, in a form of headers or META tags.
CORS (Cross-Origin Resource Sharing) is telling the browser it can read data even if it's in different origin. You can get around it using a CORS Proxy.
CSP (Content Security Policy) battles XSS (cross site scripting) and packet sniffing attacks, and exists in three versions. The first requires to specify a white-list of allowed sources in Content-Security-Policy header, which often led to enabling all of them for convenience. The second introduced a nonce, and the third is the best, but not yet widely supported.
I had a little more time, so instead doing just incremental changes I was able to go knee-deep into some of those excremental ones :-)
RSS, RDF, Atom easily, not inventing wheel. It's similar to each other, so I used XDocument for that with ease.
Every feed item holds a “feed” object, containing basic info about the feed, because in one timeline there are multiple feeds.
As a storage I used serialization, until it became unbearable and I'll do it properly using SQLite database.
Register as Dev on Twitter website.
For starters I used a nice tutorial by Danny Tuppeny for simple Twitter posting and it really worked right away. But I abandoned his solution for one based on TinyTwitter, which I still had to modify heavily.
For example, it's quite old and therefore doesn't support 280 char tweets. I had to add tweet_mode=extended to API call and then in JSON response use full_text instead of text.
Speaking of JSON, for Qip I used heavily modified custom JSON library, even there's the popular Json.NET from Newtonsoft. It's based on per-character loop and I don't think there's much faster approach how to parse it.
I customized it to accept comments and commas after the last element or property (in a JSON5 manner). For viewing I used open source JSON Viewer by Eyal Post.
Problem datetime created_at thanks to solution:
```
DateTime createdAt = DateTime.ParseExact(tweet["created_at"],
"ddd MMM dd HH:mm:ss +ffff yyyy", new System.Globalization.CultureInfo("en-US"));
```
asdf
…asdf IconsDownload
RSS or favicon
Bitmap as PNG or ICO to PNG
Quac icon as dynamic bitmap.
Custom Quac icons, that gives users a freedom to use whatever icon they please.
For icons and glyphs I've always preferred webfonts, because they're easier to work with and has much lower impact on CPU. But they're not easy to create, fortunately there are services like Fontello, that allows to pick only what I need.
Inline SVG in CSS
Mismatched markup, unnecessary namespaces, ballast metadata from editors, empty <g> elements etc.
Editing by hand, simple HTML editor
xxx
xx
https://pastebin.com/4Afm45AH
https://en.wikipedia.org/wiki/Fast_inverse_square_root
www.beyond3d.com/content/articles/8/ www.beyond3d.com/content/articles/8/www.beyond3d.com/content/articles/15/ www.beyond3d.com/content/articles/15/www.lomont.org/Math/Papers/2003/InvSqrt.pdf www.lomont.org/Math/Papers/2003/InvSqrt.pdfbetterexplained.com/articles/understanding-quakes-fast-inverse-square-root/betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
Even I still adore Data Particles I “invented” almost 10 years ago, without proper tools (I struggle to create) it's quite hard to manage the data. I encounter it from time to time when I need to fix some order in our intranet app.
So for QB I decided to move from Data Particles to JSON structure I created for Qedy. It suits the purpose rather well and I can improve it to be mutually beneficial.
I created a simple parser, that runs for every ID, which is time consuming, but there's no rush.
I thought more about tags and found out it's even more flexible, than I imagined. All in the sense of the original idea of simplification for QetriX, tags is a generic group of anything.
It works well for users. Now tag is not only a group of users, but it acts as a role as well. You can tag users as “employee”, “customer”, “vip”
I know the industry standard is keep lines of code up to 80 characters. Also I know my FullHD computer screen has a pivot, so I can it to "portrait" mode to see much more lines.
But I don't.
PSR
tabs vs spaces
Idiomatic CSS and JS
…I consider it a great data type
object's keys are unordered, usually ordered by name or by how properties were added.
array always preserves order of elements
Not for humans, so for better human writing emerged more forgiving formats, like JSON5 (ES5), HJSON and more.
There's a nice summary of all competing formats.
ER diagram editor, multipurpose
Canvas or SVG
Golfers have caddie, corporations have Qedy. Both do basically the same job – supports the star in every way possible. And there are really many ways for Qedy!
Qedy is a commercial extension of the Framework, which means most of the shared functionalities won't be open source. Qedy is purposed for rapid development of intranet and extranet information systems.
With Qedy, instead of coding, you simply create your apps in Builder, where you can see a mockup of GUI, define a data model, create label translations and more.
But Qedy isn't just for web apps, you can create websites with it as well! Using simple block approach you add content for the page quickly and easily. In fact, exhibit A is this blog, whose content editor uses exactly that.
With Qedy you can define component conditions, visualize them and test using defined values.
Incorrect:
SELECT name, positive, negative, positive/total x FROM productz ORDER BY x DESC;
By the way, I'm not sure that the Wilson correction gives any better results than a one standard deviation lower bound for the positive score:
SELECT name, positive, negative, positive/total - sqrt(positive*negative/total)/total x FROM productz ORDER BY x DESC;
Score = Lower bound of Wilson score confidence interval for a Bernoulli parameter:
SELECT name, positive, negative, ((positive + 1.9208) / (positive + negative) -
1.96 SQRT((positive negative) / (positive + negative) + 0.9604) /
(positive + negative)) / (1 + 3.8416 / (positive + negative))
AS ci_lower_bound
FROM productz
WHERE positive + negative > 0
ORDER BY ci_lower_bound DESC;
Single 1 0 1
Good new 5 0 1
Excellent 23400 23 0.9988134107340426
Quite good 520 200 0.7055298549839887
Exc-ish 5 1 0.6811881781678829
Some shitty 1000 2000 0.3247267033417656
Quite bad 28 82 0.21301210856756564
Bad-ish 1 2 0.06116780616017409
Single bad 0 1 0
Single 1 0 1.0000
Good new 5 0 1.0000
Excellent 23400 23 0.9990
Exc-ish 5 1 0.8333
Quite good 520 200 0.7222
Some shitty 1000 2000 0.3333
Bad-ish 1 2 0.3333
Quite bad 28 82 0.2545
Single bad 0 1 0.0000
Excellent 23400 23 0.998
Quite good 520 200 0.688
Good new 5 0 0.565
Exc-ish 5 1 0.436
Some shitty 1000 2000 0.316
Single 1 0 0.206
Quite bad 28 82 0.182
Bad-ish 1 2 0.061
Single bad 0 1 4.586
rating = (((positive + 1.9208) / (positive + negative) - 1.96 Math.Sqrt(((positive negative) / (positive + negative)) + 0.9604) / (positive + negative)) / (1 + 3.8416 / (positive + negative)));