Giter Site home page Giter Site logo

pocketjoso / penthouse Goto Github PK

View Code? Open in Web Editor NEW
2.6K 42.0 165.0 2.71 MB

Generate critical css for your web pages

Home Page: https://jonassebastianohlsson.com/criticalpathcssgenerator

License: MIT License

JavaScript 2.15% CSS 37.89% HTML 59.97%
performance css web nodejs puppeteer

penthouse's Introduction

penthouse

Critical Path CSS Generator

NPM version Build Status Downloads

About

Penthouse is the original critical path css generator, helping you out to speed up page rendering for your websites. Supply your site's full CSS and the page you want to create the critical CSS for, and Penthouse will return the critical CSS needed to perfectly render the above the fold content of the page. Read more about critical path css here.

The process is automatic and the generated CSS is production ready as is. Behind the scenes Penthouse is using puppeteer to generate the critical css via the chromium:headless.

Usage

(If you don’t want to write code, you can use the online hosted version.)

yarn add --dev penthouse

(or npm install, if not using yarn)

Basic example

penthouse({
  url: 'http://google.com',
  cssString: 'body { color: red }'
})
.then(criticalCss => {
  // use the critical css
  fs.writeFileSync('outfile.css', criticalCss);
})

More examples

https://github.com/pocketjoso/penthouse/tree/master/examples

Performance when running many jobs

Penthouse is optimised for running many jobs in parallel. One shared browser instance is re-used and each job runs in its own browser tab. There's only so many jobs you can run in parallel before your machine starts running out of resources. To run many jobs effectively, see the many urls example.

Options

Only url and cssString are required - all other options are optional. Note that the html file found via url is expected to be styled; penthouse does not inject any styles, it just uses cssString (or css) to prune into critical css.

Name Type Default Description
url string Accessible url. Use file:/// protocol for local html files.
cssString string Original css to extract critical css from
css string Path to original css file on disk (if using instead of cssString)
width integer 1300 Width for critical viewport
height integer 900 Height for critical viewport
screenshots object Configuration for screenshots (not used by default). See Screenshot example
keepLargerMediaQueries boolean false Keep media queries even for width/height values larger than critical viewport.
forceInclude array [] Array of css selectors to keep in critical css, even if not appearing in critical viewport. Strings or regex (f.e. ['.keepMeEvenIfNotSeenInDom', /^\.button/])
forceExclude array [] Array of css selectors to remove in critical css, even if appearing in critical viewport. Strings or regex (f.e. ['.doNotKeepMeEvenIfNotSeenInDom', /^\.button/])
propertiesToRemove array ['(.*)transition(.*)', 'cursor', 'pointer-events', '(-webkit-)?tap-highlight-color', '(.*)user-select'] ] Css properties to filter out from critical css
timeout integer 30000 Ms; abort critical CSS generation after this time
puppeteer object Settings for puppeteer. See Custom puppeteer browser example
pageLoadSkipTimeout integer 0 Ms; stop waiting for page load after this time (for sites when page load event is unreliable)
renderWaitTime integer 100 ms; wait time after page load before critical css extraction starts (also before "before" screenshot is taken, if used)
blockJSRequests boolean true set to false to load JS (not recommended)
maxEmbeddedBase64Length integer 1000 characters; strip out inline base64 encoded resources larger than this
maxElementsToCheckPerSelector integer undefined Can be specified to limit nr of elements to inspect per css selector, reducing execution time.
userAgent string 'Penthouse Critical Path CSS Generator' specify which user agent string when loading the page
customPageHeaders object Set extra http headers to be sent with the request for the url.
cookies array [] For formatting of each cookie, see Puppeteer setCookie docs
strict boolean false Make Penthouse throw on errors parsing the original CSS. Legacy option, not recommended.
allowedResponseCode number|regex|function Let Penthouse stop if the server response code is not matching this value. number and regex types are tested against the response.status(). A function is also allowed and gets Response as argument. The function should return a boolean.

Troubleshooting

Enable debug logging

Logging is done via the debug module under the penthouse namespace. You can view more about the logging on their documentation.

# Basic verbose logging for all components
env DEBUG="penthouse,penthouse:*" node script.js

Not working on Linux

Install missing dependencies to get the headless Chrome to run:

sudo apt-get install libnss3

You might possibly need an even longer list of deps, depending on your dist, see this answer

Problems with generated CSS

A good first step can be to test your url + css in the hosted critical path css generator, to determine whether the problem is with the input your passing (css + url), or with your local setup: https://jonassebastianohlsson.com/criticalpathcssgenerator

Unstyled content showing when using the critical css

If you see flashes of unstyled content showing after applying your critical css then something is wrong. Below are the most commont causes and some general related advice:

Your page contains dynamic or JS injected/activated content.

Generally you have to ensure that all elements you want styled in the critical css appears (visible) in the HTML of your page (with Javascript disabled). The first render of your page, the one critical css helps make much faster, happens before JS has loaded, which is why Penthouse runs with JavaScript disabled. So if your html is essentially empty, or your real content is hidden before a loading spinner or similar you have to adress this before you can get the performance benefits of using critical css.

If your html is fine, but varies based on things such as the logged in user, third party advertising etc, then you can use the forceInclude parameter to force specific extra styles to remain in the critical css, even if Penthouse doesn’t see them on the page during critical css generation.

Early DOM content moved out of critical viewport via CSS

This problem can happen if you have an element appearing early in the DOM, but with styles applied to move outside of the critical viewport (using absolute position or transforms). Penthouse does not look at the absolute position and transform values and will just see the element as not being part of the critical viewport, and hence Penthouse will not consider it’s styles critical (so the unstyled element will show when the critical css is used). Solution: Consider whether it really should appear so early in the DOM, or use the forceInclude property to make sure the styles to "hide"/move it are left in the critical css.

Special glyphs not showing/showing incorrectly

Problems with special characters like → after converting? Make sure you use the correct hexadecimal format in your CSS. You can always get this format from your browser console, by entering '→'.charCodeAt(0).toString(16) (answer for this arrow glyph is 2192). When using hexadecimal format in CSS it needs to be prepended with a backslash, like so: \2192 (f.e. content: '\2192';)

penthouse's People

Contributors

alon-rewire avatar bevacqua avatar bezoerb avatar brockduncan avatar bv-sumit avatar corneliusio avatar dependabot[bot] avatar dr0bz avatar fatso83 avatar futureweb avatar gavro avatar imjacobclark avatar joejordanbrown avatar kareemaly avatar lahmatiy avatar lucasrla avatar ndemengel avatar nickdima avatar philipp-winterle avatar pocketjoso avatar pyronaur avatar qasimzee avatar raxbg avatar saturate avatar simllll avatar steveedson avatar sunify avatar therealpecus avatar topaxi avatar xhmikosr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

penthouse's Issues

Content flickers

First off -- awesome module! really easy to set up. I have a minor issue:

  • list-style: none on the navigation items not being pulled up, causing layout to move around slightly
  • (I had another issue, where the title color wasn't getting applied but some selector tweaking fixed that one.)

Here's the crit-css page:

untitled

This is how it looks like when the stylesheet hits:

untitled2

Proposal: simple tools - more powerful Node module

I have been thinking a lot about how we can do the following better without complicating things too much

  1. process multiple files
  2. keep the simple semantics of outputting the file to stdout
  3. keep the PhantomJS core simple

The goals of #1 and #2 are in conflict as it is (see #40), and the semantics become messy to the end user. I have been thinking of fifos and event architectures without really getting anywhere, but what I propose is the following, which might seem radical, but to me is a simplification for the better (compared to the dev branch).

Keep end user tools simple

  • Stick to the way it works today: only process one url in the penthouse tool.
  • Maybe change the options parsing somewhat to support various options (like in the dev branch), but still limit to processing one url

Do hard stuff in the node module

I am guessing 9/10 uses of a multiple url supporting version will be driven by a script of some type, and therefore I think it is reasonable to restrict the user land tools to just accept one url per run.

This could prove to have some interesting effects.

  • We could speed up processing of multiple files through parallelization using a cluster of background instances
  • We could keep the existing API without any changes
  • To process multiple files you call the penthouse function multiple times, as today, but the response should be quicker

Force include

Not a big deal, but nice to have:

Imagine you have a header at the top of page that shows currently login user (otherwise display a login button), because such info is only visible to login users, penthouse won't be able to see that this class is used (it will only inline the login button's css).

While one can argue most existing users should have a cached copy of full css in their browser anyway, there are indeed cases where a login user can run into problems (though eventually the full css will load and all should be fine at that point).

This does make penthouse look a bit like criticalCSS, which has this feature but lack self-signed ssl support for local development. But I guess these 2 tools serves very similar purpose so it's natural to see their feature set converges :)

False positives for unused @font-face

@font-face imports are included in the critical css even when they aren't used above the fold. it would be awesome to have some way to exclude those.

this particular page, for context, works something like:

-- header --
inline crit css
inline a subsetted font via url(data:font/woff;base64 ... );

-- footer --
load main stylesheet, including the complete font

in my case, the complete font isn't used above the fold (the css generated by penthouse confirms this). however, the @font-face import still appears in the above-the-fold/critical stylesheet.

Option for user agent

By default Penthouse sets a custom Penthouse Critical Path CSS Generator user agent. Some sites render differently based on UA; add an option to support using a custom UA.

Add Travis build

We could add a build to Travis CI that ran the tests for us and showed the current build status. This is all that would need to be added to travis.yml:

language: node_js
node_js:
    - "0.10"
    - "0.11"

Suppress errors from phantomjs?

I sometimes see these lines in the output css when running penthouse, is there any way to prevent phantomjs from messing with output?

Unsafe JavaScript attempt to access frame with URL about:blank from frame with URL file:///Users/local/git/mai/node_modules/penthouse/lib/phantomjs/core.js. Domains, protocols and ports must match.

my command look something like this:

penthouse https://local.dev/ public/app.css --width 1366 --height 768 > public/inline.css

Flag for writing output to stdout

As the next version of Penthouse moves to saving the generated CSS to file(s), necessary when generating for multiple urls at the same time, I believe that it's necessary for us to maintain a way to output directly to stdout. This would obviously only be possible when critical css for a single url is requested.

This allows chained calls using Penthouse, as in Critical, gulp(?), and in other places. Writing to file is not always what you want, let's not break useful patterns while moving forward.

Not sure what the flag should be, since we're kind of doing -w by default... I'll think about it, let me know if you have a suggestion.

Penthouse adds extra line breaks (only on Windows(?))

Since a while back when running penthouse on Windows, the output is littered with newlines, for example:

button {
color: black;
}
button:before {
content: 'test';
}

becomes:

button {

color: black;

}

button:before {

content: 'test';

}

I've only had a quick look before and wasn't able to figure out what causes the bug. I'll look again now.

If anyone can let me know whether this bug shows on other OS' as well, that would be helpful. I can't reproduce it on my Linux server, but it's a little bit hard for me to test in that environment.

:hover isn't working

I'm trying generate critical CSS for a site, but because the main navigation is based on :hover it doesn't work until the rest of the CSS is loaded.
Would it be possible to include :hover style as an optional parameter?

Handle multiple URL's in same call

Penthouse should be able to create multiple critical path css files at the same time, from multiple passed in URLs. This way a user can essentially just list a number of pages (via URL's) in their build script, and every time they build, all their critical path css will be updated.

This will be a major version change, since it will change the core API.

What's needed

  • The core script (penthouse.js) needs to be modified to execute the critical path css generating function once per passed in url, rather than just once. The script should also write the output to file(s), rather than just returning it. This leaves room for returning something else useful, perhaps something like how many bytes where saved, how many files where created, perhaps duration of execution. @pocketjoso will take care of this part.
  • An option parser handling the multiple (possible) passed in URL's needs to be built into the penthouse ecosystem. It will also simplify the straight command line penthouse call by wrapping phantomjs and the config. @fatso83 is already on top of this task.

Drop custom options parser

Custom parser should no longer necessary with dropped standalone command line support, as of 0.4.0.

Idea is to find a npm replacement to use instead, such as commander, or nopt which is the one Penthouse already uses.

Different outputs between local usage and online tool

I have a problem where using penthouse in a local gulp workflow doesn't pick up all of the essential styles. Here's what I'm doing (code slightly redacted for simplicity):

var penthouse = require('penthouse');
var Promise = require('bluebird');
var penthouseAsync = Promise.promisify(penthouse);

var CRITICAL_CSS = '';

gulp.task('critical', ['build:base'], function(done){
  penthouseAsync({
    url: 'http://localhost:3000',
    css: paths.dist + '/css/main.css'
  }).then(function (criticalCSS) {
    CRITICAL_CSS = criticalCSS.replace('\n', '');
    done();
  });
});

gulp.task('build:critical', ['critical'], function () {
  return gulp.src(paths.dist + '/index.html')
    .pipe($.replace(
      '<link rel=stylesheet href=css/main.css>',
      '<style>' + CRITICAL_CSS + '</style>'
    ))
    .pipe(gulp.dest(paths.dist));
});

I keep a local express server running on port 3000 while the task is running. Doing it this way, CRITICAL_CSS will rack in at 1364 bytes. However, it's incomplete, and using it will cause my page to show unstyled buttons and what not.

On the other hand, if I use the online tool that you provide, I get what I need. To do this, I manually ran the build:base task, and then I provided the same local express server by tunneling it with ngrok:

$ ngrok 3000
ngrok

Tunnel Status                 online
Version                       1.7/1.6
Forwarding                    http://4abd23f7.ngrok.com -> 127.0.0.1:3000
Forwarding                    https://4abd23f7.ngrok.com -> 127.0.0.1:3000
Web Interface                 127.0.0.1:4040
# Conn                        5
Avg Conn Time                 7.43ms

And I manually copy/pasted the stylesheet into the form:

$ cat dist/css/main.css | pbcopy

Doing this gave me 2049 bytes worth of critical styling information for my page, and if I use it then I end up with what I want.

What do you suggest that I try in order to convince the local phantomjs inside penthouse to be as pedantic as the online one? Perhaps I'm missing some options?

The project that I'm building is this one, if you want to run any experiments yourself on my code.

ReferenceError: Can't find variable: process

Hi,
when I start my script, it's crashing.

phantomjs -v 1.9.7
node -v v0.10.29

ReferenceError: Can't find variable: process
/node_modules/penthouse/node_modules/phantomjs/node_modules/which/which.js:6
/node_modules/penthouse/node_modules/phantomjs/node_modules/which/which.js:105
ReferenceError: Can't find variable: __dirname

/node_modules/penthouse/lib/index.js:9
/node_modules/penthouse/lib/index.js:55
TypeError: '[object Object]' is not a function (evaluating 'penthouse')

Broken CSS returned when used with large CSS Files

Hi there, great lib. Thanks a lot for this! :)

However, I managed to get reproduceable broken output when using penthouse with large css file bases.

Just run the following through your online tool:

  1. URL: http://www.pferd.de/forums/386-westernreitweise
  2. CSS: Contents of this link

When you paste the resulting CSS into the W3C CSS Validator you will recognize unclosed rule blocks that will result in parse errors. The original CSS however seems to be "fine" at those specific places.

If I separate those offending blocks and run them alone against penthouse, the generated css is fine. The issue only appears when penthouse is dealing with large files.

Timeout penthouse after x seconds

Under some circumstances, PhantomJS just hangs (as an example: #70), and at other times response times can go well over 1 min.

I think by default Penthouse should return an error after 30s, but this timeout value should be configurable as an option.

Multiple CSS parameters?

Thanks for creating and maintaining this project. I was just curious if Penthouse supports multiple CSS files as an input?

As an example, I have 2 external CSS files on a page, but I can't bundle them for reasons involving IE8 file size limitations on those types of files. Ideally, penthouse would allow for the following optional parameters:

phantomjs penthouse.js http://mySite.com/page1 bundle1.css bundle2.css > page1-critical-styles.css

Is this possible?

Thanks

Remove old behaviour of outputting to standard out

Ref the discussion around #28, we should remove the old behaviour of outputting to standard out.
This is currently a blocker for #29 (more diagnostic output).

The fix is quite simple and consists of removing the special handling of just dealing with one file, and treat that case as the rest.

Making this work on server

Hi,

Can someone please give me some advice on how this can work on a server when the Gulp file is being run to build the site?

Thanks,

Sam

Tests needed for changes to the core phantomjs script

When trying to integrate changes from a feature branch it is tremendously helpful if I can run a testsuite afterwards and see that everything is still working, including any bug fixes. Since I am not too intimate with the actual workings and bug fixes of the css code, I don't know if I by chance might reintroduce them when handling a conflict.

So I propose making a small test for each of these bug fixes. I hope the tests in basic-tests.js are sufficient as a template.

I would guess creating a test would look something like this:

  • if necessary, add a html file and css file to test/static-server (say, issue-13.html, issue-13.css)
  • if necessary, add a css file to test/expected/issue-13.css
  • run the penthouse function with the relevant params and test that the content matches the expected output

In reality, this is more overhead than needed, if you instead seperating code into functional modules. So if you have an improvement to the say a cleanCss() function, it would be much easier if you moved that into a module of its own (like the options-parser.js) that can required in and be separatly tested. This is how I test the options parser. The module is then concatenated into the final build for penthouse.js. The tests run much quicker too (2ms vs 5 seconds!) as there is no need to fire up phantomjs for testing the logic. A test would then simply look something like this:

it('should clean up css', function() {
    var cleanup = require('../lib/cleanup-css.js');
    var dirtyCss = '.empty-rule {}';
    cleanup(dirtyCss).should.equal('');
});

"@-moz-document" can't be passed by "penthouse"

Warning: css/critical-path.css:834:32: Unexpected } Use --force to continue.

@-moz-document url-prefix() {
  .portal-select {
    overflow: hidden; }

  .portal-select select {
    width: 120%;
    width: -webkit-calc(100% + 3em);
    width: -moz-calc(100% + 3em);
    width: calc(100% + 3em); } }

... will be converted into ...

  .portal-select select {
    width: 120%;
    width: -webkit-calc(100% + 3em);
    width: -moz-calc(100% + 3em);
    width: calc(100% + 3em); } }

Split code into library portion and add more parameters

Great stuff, but it would make it more reusable if you could

  1. Split the code that does the actual magic into a separate module that could be required in (so you could do something like require('critical-path'))
  2. Pass the function some parameters. At least these: url, viewport-x-width, viewport-y-width

Https URL's not working

This appears to be an issue in PhantomJS. I will search for a workaround, as this is pretty detrimental to the value of penthouse.

CSS3 selectors (::selection) result in malformed CSS

CSS3 selectors are causing malformed CSS.

The following source code (part of all.css)

::-moz-selection {
  color: #fff;
  background-color: #FE1486
}
::selection {
  color: #fff;
  background-color: #FE1486
}

Becomes the following after grunt-penthouse:

::-moz-selection {
  color: #fff;
  background-color: #FE1486
}
::selection {
  cul{
    list-style: none
  }
  .clear {
    clear: both!important
  }
  footer,header,nav {
    display: block
  }
  :focus {
    outline: 0
  }
  input {
    border: 1px solid #d8d5d5;
    background: #fff;
    padding: 5px
  }
}

The element cul is unknown (probably malformed code). When the CSS code is minified via cssmin it is further malformed. The bracket of ::selection { does not have an ending anymore, causing a large part of the CSS file to be removed.

CLI progress when processing multiple URLs

This relates to the dev branch, where multi url critical css generation is possible.

Currently there's no feedback given - if processing the multiple URLs will take 2 minutes, then the command line (or alike) will be completely blank during this time. In addition, it will be blank when Penthouse finishes.

My suggestion is that we just log something like generated Critical-1.css (for "http://google.com") each time we finish generating one url of a multi url job.

(For bonus points we could also log the timing for each job, and do fancy color coding like mocha does.)

Node module: return dictionary with a mapping of url : css

Instead of a simple string as of today, the mutiple url version should return a map/dict/hash/jsobject with urls mapping to the corresponding css.

In practice this just means the node module outputs files to a temporary directory and reads the content back into the corresponding values.

Drop standalone support and move into Node

Background

The standalone CLI support has been supported from the start with the intention to make it easier for non developers to use Penthouse, by not requiring them to first setup Node. A year in now it seems to me that very few people use this option, and if that if anything at all it is command line they want to avoid, which they achieve by using the hosted online version of Penthouse. The standalone option therefor seems redundant.

Standalone support has also required @fatso83 to write a lot of custom code (f.e. options parser) because we couldn't rely on node modules. It also means we have two maintain two versions of the code, and all the code to automate creating those versions etc.

Future

Let's discuss in this thread.

Remove the need to specify CSS file

I am not quite sure why we need to specify the CSS file at the command prompt. From a user perspective I would assume that all we needed was to point the browser at a page and get the active css for a specific viewport back.

please explain more

why do you need this, if the CSS file will be cached anyway...it's only the very first refresh that will be "slow", but nothing out of the ordinary. seems like a lot of hassle for nothing, no?

Options to force include / exclude selectors

Hi there. Great library, I'm using it for some time now in various projects. I wanted to ask if there are any options to specify selectors to be forced for inclusion / exclusion. This would be very helpful for various cases.

By default hidden elements (display: none) don't get into the CSSOM and I guess penthouse is not even considering them to include. However, if you work with CSS classes to toggle visibility and the initial state on a landing page is hidden (by a selector .my-page .hidden for example) I'd like to include this style in the critical output. This is important as invisible content will be visible until the full CSS is loaded async.

The same could be done with a selector list called exclude and if you don't want to include minor stylings that don't affect layout so much in this list.

One additional idea would be to have an option to substitute the excludes that allows you to configure some CSS attributes in an object / string. This is particularly interesting if you'd want to substitute some elements on your page with display: none or visibility: hidden until the full CSS is loaded async.

I thought of a config like this:

include: [
  '.page-content > li:last-child',
  '.error-message'
],
exclude: [
  '.huge-hero-banner',
  '.unimportant-styles-on-images'
]

Or together with exclude substitution:

include: [
  '.page-content > li:last-child',
  '.error-message'
],
exclude: {
  '.huge-hero-banner': {
    visibility: 'hidden',
    height: '50vh'
  },
  '.unimportant-styles-on-images': {
    display: 'none'
  }
}

What do you think?

Hangs on invalid CSS

Certain invalid CSS causes Penthouse to hang, f.e.:

{"css":".body{color:red;}"}

Once we drop standalone usage, just throw Error if AST parser can't make sense of css.

Node module against HTTPS

Will it work without any further config than documented, if i want to run it as a node module against an HTTPS source ? :)

Modularise components of penthouse.js script

As brought up in #13, it would be better if the core penthouse.js script was broken up into modules, where possible. This would simplify and speed up testing significantly.

I want a clean setup for this however, that respects the following:

  1. A single file (self contained) easy non Node install of penthouse.js - for those so inclined. This means we can't have single components not included in the root penthouse.js script.
  2. Any differences between the root penthouse.js script and the one included in /lib/phantomjs/ should be relatively minor, and be built automatically.

My current thinking then is that the root penthouse.js file has to include any eventual modules directly in the script itself, whereas the lib version can require them in from other files. Should't be too hard to setup, but if anyone has any good suggestions for this I'm all ears.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.