Need High Performance 3rd party Widget +100 tip and 3 winners
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

We have a news widget we want to allow partners to embed on their site. We want to be high performance and mega lean on the 3rd party site. Ideally they copy from inline script like you would for a youtube video. It will then run in a non blocking way to inject its layout on to the page, make the API call to get the data to go in the widget.

The basic design can be seen here -
https://www.dropbox.com/s/xl3x6gfkjwic80x/News-Widget-%28Grid%29.png?dl=0

The ai file for the design can be seen here. this will help you see the specific font, the hover style etc...
https://www.dropbox.com/s/dl7bg5w8n6c9iye/News%20Widget%20%28Grid%29.ai?dl=0

In the embed script it would be great if we can specify a few things about widget.

-Ideally we can specify the number of items per row and the number of rows to render at default.

-Widget is responsive so if it is 3 wide on load and the browser gets smaller it can drop to 2, and then finally to 1 wide.

-Really important that on mobile it doesnt load exceeding the viewport and then resize, this would be wonky on the page to the end user.

-Clicking on Read more will load another row. We can load this on demand and not on the initial requests

As for the API call.

We are open to anything you think will be amazing, small and render fast. if you use any fancy compression techiques please outline the specifics so we can be sure to understand how we will mimic this in the actual app. If we need to do things like base 64 the images then we are fine with it. We will take your recommendation and benchmark it across the other submissions, we can assume the image server will be running http2 so i dont know if there is a lot of overhead loading them externally vs inline with the json.

Ideally we can do this without jquery, we are open to a smaller framework if needed to handle the GET requests and rendering. We just want to be as small as reasonably possible. as for the html and css, if we need to use a micro framework (not bootstrap) we would be fine with it if the size of the lib is worth it long term. Needs to work well on IE10+ , Newest Edge, Latest Chrome, Latest FF, iOS and Android. One thing to know, if we need to assume the json is jsonp since its going to be embeded ina domain that is not in our control please make sure your example properly handles this so we can test in real'ish conditions

Since this big contest we will agree to pay the winner $200, the second place person $100 and the 3rd place winner $50

have you checked my new updates?
Chlegou 12 days ago
Qdev?
gabrielsimoes 4 days ago
8 days ago
Tags
javascript

Crowdsource coding tasks.

3 Solutions


Hi there, ...was hard, but here it is:

i used NET XMLHTTP (4.8KB) interface light weight, and powerful. (less size than jquery)

link: http://xkr.us/code/javascript/Net/

i have modified it, so it's included in this project not dependency anymore (same file as the plugin js code)

for responsive grids, i used Bootstrap responsive code only, not the full CSS library, but only responsive part. was taken from here: https://getbootstrap.com/docs/3.4/customize/ .as result, css file is only (16KB)

this was the best method to handle responsive grids, spent hours working on it, but later on, ended using bootstrap grid only.

a fake news json to work as fake database.

-Ideally we can specify the number of items per row and the number of rows to render at default.

normally, pagination is handled server side, so urls, could accept as parameters "?index=0&size=5"

i made the script work the same way. so you fix what page index (initially 0 for latest) , and size (itemsPerPage)

-Widget is responsive so if it is 3 wide on load and the browser gets smaller it can drop to 2, and then finally to 1 wide.

like bootstrap made it simple, i kept it simple, only by adjusting classes, it will be responsive as always.

you only tell display classes for items like that: "col-lg-3 col-md-4 col-sm-6 col-xs-12"

other requirements are validated also

JSONP Support

since data aren't static (we are fetching server to load more content), i think better to stick with json (by the end, you will send to REST API or PHP file to fetch from database)

Images

you could render images link, they will be posted as images source without problem i think (even less load time comparing with base 64)

Code

the script is injecting code as requested.

there is a php file, might help you to fetch data from database and render it when canceling the fake database (call php file instead of direct json call).

the project is hosted in Github.

link: https://github.com/chlegou/3rd-party-widget

i made to examples, see them here.

demo: https://chlegou.github.io/3rd-party-widget/

demo: https://chlegou.github.io/3rd-party-widget/index.html (try this if the above link didn't work)

hope you like my solution,

Waiting for your review.

Reviewing this now - Thanks for the submission.
Can we make the embed code fully handle calling fonts, loading js etc..? our goal is to give users embed code similar to a youtube video and they simply add it to their page/cms etc.. and we inject everything from there.
Qdev 13 days ago
yes, in theory, we could do that, so we first load fonts and css files, then, injecting the content of it. (i noticed yesterday you are using a premium font "super nova" ). it will be only a single js file, that will inject everything. Please review the code, and tell me what to do next. (if confirmed, i will apply the injection to it) i could make it configurable from the html attributes (if needed)..... waiting for your review.
Chlegou 13 days ago
I was actually noticing all of the custom fonts. i think we would be wise to move to Arial here to avoid some of the performance penalty of calling 3rd party fonts. so with that lets kill the custom fonts and just make it look as good as we can with font family of arial. i think the > symbol we have in the hover might need to move to svg so it looks good and isnt as think as arial will most likely make it.
Qdev 13 days ago
yes i totally agree, better to make it simpler. for the > symbol, tried to follow the same flavor as the Ai design, since there is a lot to focus on, i just used the html symbol. so to resume, only inject css + svg arrow + (maybe svg grid, will be less than base64 grid code) to go?
Chlegou 13 days ago
seems worth testing, base 64 + gzip tend to cancel the bloat out so it might perform well
Qdev 13 days ago
i have uploaded changes to my github repo, the script is now injecting css + js, also, changed base64 images with svg, to save some KBs.
Chlegou 13 days ago

Source: https://github.com/gabrielsimoes/news-cards-widget/

Server Demo: https://news-cards-widget.herokuapp.com/

Client Demos: https://news-cards-widget-demo.herokuapp.com/

Features:

  • Very clean code
  • Output is minimized to reduce size
  • No external libraries
  • Total size (html + js + css) is 8.8KB
  • CSS is loaded on the JS, resulting in simpler configuration but a loading time slightly longer (I can change that if you want.)
  • Responsiveness
  • Follows given design strictly.
  • I have implemented a very simple server, so that you can see how the api works. Instead of using JSONP, I recommend you use CORS, unless your server doesn't support it.
  • SVGs are base64'd
  • Demos:
  1. Client puts div on the html and calls script
  2. Client uses an iframe (the problem with this solution is that the height has to be fixed, and the client can't configure anything).
  3. Same as 1, but div has 50% width.
  • Things I still want to implement:
  1. Better responsiveness (but then the user would have to specify the number of columns like on the bootstrap solution above)
  2. I can improve support for picture in weird sizes, if you want. For now, all images have the same size, etc.
  3. Make it clearer how to setup things (document how stuff works).
  4. Add a default configuration.
  5. You tell me.
Thanks for this, will review tonight!
Qdev 11 days ago
I had forgotten to update the sources on GitHub. Functionality is still the same, but now the sources are minimized as I promised.
gabrielsimoes 10 days ago

Hey Qdev, here's my solution:

Result: everything minified into one file = 7.34kb (2.78kb gzipped). No 3rd party libraries.

Demo: https://wuddrum.github.io/news-widget/dist/

Source: https://github.com/Wuddrum/news-widget

I went ahead with an iframe solution instead of inlining the widget directly into user's page. I did this for the sake of the widget's encapsulation. Mainly because linking to a JS file and executing everything directly on the page poses a security risk. As the script now has direct access to webpage and user's cookies/storage. In case your site gets compromised, the script could be changed to exploit all of that. Another reason is that people who embed the widget won't have a chance to accidentally force some CSS rule on any widget's elements and end up accidentally breaking it (although one could argue that having the ability to directly style the widget is more of a pro than a con). You also don't have to worry about cross-origin calls to the API, since the embed itself is hosted on your own site. If you rather prefer an inline solution, this can be refactored to that, but I would advise against it.

I've added simple messaging to the iframe, so that the height of it gets auto adjusted and it's as responsive as a directly inlined widget. This requires a 200byte script tag with inlined JS before the iframe tag. Here's an example embed code (that you can actually use for testing):

<script>window.addEventListener("message",function(a){var b=a.data;!a.origin||"wuddrum.github.io"!==a.origin.replace(/^https?:\/\//,"")||!+b||0>=b||(document.getElementById("NewsWidget").style.height=b+"px")});!0;</script>
<iframe id="NewsWidget" src="//wuddrum.github.io/news-widget/dist/embed.html?numItems=8&maxItemsPerRow=4" width="100%" frameborder="0" scrolling="no"></iframe>

The user can specify the number of items to load with numItems and how much items there should be per row at a maximum with maxItemsPerRow. I'm not using options for specifying a number of items per column and a number of rows because it makes little sense in a responsive scenario. Even maxItemsPerRow feels a bit weird, since some users might not get to ever see that many items per row, due to width of the widget.

I'm using a most basic "API" for the demo that fully supports only 4 maxItemsPerRow and 8 numItems. If you're testing it with other parameters, be aware that some of the API data might never appear due to the underlying logic of the widget mixed with how basic the demo "API" is.

I've written a minimal responsive grid CSS that's based on Bootstrap's breakpoints (since they're widly used). The classnames for the grid system might seem a bit backwards, but that's because the grid is not based on the usual 12 grid system, instead they're that way to allow 5, 7 and 8 items per column. e.g. lg-5 would tell an element to take up 1/5th of the container's width on large screens.

As for json API, I'm going with a very optimistic approach and sending over only article's id, title, description and color (more on color below). And building links to the article and image internally, based on the id. If in your case the links can't be rebuilt just from the id, then you'll have to add them to your API output.

Further Size/Load Time Reduction

maxItemsPerRow:

A limit of maximum items per row should be decided on. I've currently set it to 8, but even on 1920px width, 8 tiles seem to be too small. Personally, 5 or 6 at best, seemed to be the best values from my testing.

Coming to a concrete number would mean that certain CSS declarations could be removed, because they're never used in any possible scenario.

Image Loading:

As mentioned above, I'm using color as part of API response for each article. This is simply the average/dominant color (that I extracted manually with this tool) of the article's image that's being displayed as a placeholder while the image loads (a very minimalistic lazy loading). This makes the tile to appear ready for use, even though images might not be yet loaded. You can best test this by throttling network speed to slow down images. Overall, I'm not sure of what kind of backend you're dealing with and if it's possible to do such calculations when submitting an article (and a batch job for all the existing articles).

You could also use responsive images to load images that are more accurately sized for the tile size. But this would require a polyfill for IE that would add some overhead. Same could also be applied to allow loading webp images for browsers that support them.

Loading Animations:

I've included two loading animations, for the Read More button and tile's that are in process of fetching API info. If you decide to keep only one of them, some more code and CSS pruning can be done, resulting in lesser widget size.

I'm probably forgetting something, so feel free to ask any questions/clarifications.

P.S. What happened to this bounty?

I second that P.S.
SilverHood Apps 6 days ago
View Timeline