SlideShare a Scribd company logo
1 of 61
Download to read offline
Continuous Integration for
Frontend Code
Presentation
Marcel Birkner - Software Consultant
Bastian Krol - Software Consultant
Marcel Birkner Bastian Krol
@marcelbirkner
github.com/marcelbirkner
marcel.birkner@codecentric.de



@bastiankrol
github.com/basti1302
bastian.krol@codecentric.de



3/62
About codecentric
Big Data Nerds Agile Ninjas Continuous Delivery Gurus
Java Specialists Performance Geeks Hipster Developers
4/62
> 280 employees
And we are looking for more!
6/62
Continuous Integration for Frontend Code
Why should you use it?
What is the benefit?
JavaScript & CSS have grown up
8/62
Frontend Code is Mission Critical!
Broken JavaScript → broken app
Broken CSS → broken layout and/or broken app
It impacts the perceived performance drastically
Even more so on mobile
·
·
·
·
9/62
And Still ...
We often build superior CI/CD pipelines for our backends
But frontend code is often neglected
For our users, it's always the whole package
·
·
·
10/62
We can do better!
11/62
What we will cover
This is frontend only
Ideal: backend & frontend in one CD pipeline
Asset Optimization
Testing
The Delivery Pipeline
Local Development (Docker)
·
·
·
·
12/62
Asset Optimization
Common Problems
Bad Code Quality
Misconfigured Caching
Lots of assets (JS, CSS, images) ⇒Lots of HTTP requests ⇒Slow
·
·
·
14/62
Tools
Grunt — Task Runner
ESLint — Static Code Analysis
grunt-contrib-concat — Concatenation
grunt-contrib-uglify/UglifyJS — Minification
SASS — CSS preprocessor
compass — images → base 64 data URIs
grunt-version-assets — Versioned File Names
·
·
·
·
·
·
·
15/62
Alternatives
Grunt: Gulp | Broccoli | npm | make | ...
ESLint: JSHint | JSLint
SASS: Less | Stylus
Module System + Bundler: Webpack | Browserify
·
·
·
·
16/62
# of HTTP Requests — Concatenation
concat:{
options:{
separator:'n;'
},
app:{
src:[
'<%=jsSrcDir%>/js/**/*.js',
],
dest:'<%=jsTargetDir%>/app.js'
}
}
GRUNT
17/62
Download Size — Minification
uglify:{
app:{
files:{
'<%=jsTargetDir%>/app.min.js':['<%=jsTargetDir%>/app.js'],
}
}
}
GRUNT
18/62
# of HTTP Requests — Embed Images in CSS
.img-foo{
background-image:inline-image("foo.png");
}
SCSS
sass:{
app:{
options:{compass:true,},
files:{'<%=cssTargetDir%>/master.css':'<%=cssSrcDir%>/master.scss',}
}
},
GRUNT
.img-foo{
background-image:
url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAA...');
}
CSS
19/62
Use the Browser Cache
Versioned File Names
time stamp: app.min.20150619-0913.js
hash: app.min.2412fbca2a07a.js
content changes ⇒file name changes
file can be kept in browser cache forever
·
·
·
·
20/62
Versioned File Names (cont'd)
versioning:{
options:{
grepFiles:['<%=appTargetDir%>/**/*.html',]
},
css:{
src:[
'<%=cssTargetDir%>/app.min.css',
]
},
js:{
src:[
'<%=jsTargetDir%>/app.min.js',
'<%=jsTargetDir%>/vendor.min.js',
]
},
},
GRUNT
21/62
Versioned File Names — Before
<!DOCTYPEhtml>
<htmllang="en">
<head>
...
<linkhref="css/app.min.css"rel="stylesheet">
...
</head>
<body>
...
<scriptsrc="js/vendor.min.js"type="text/javascript"></script>
<scriptsrc="js/app.min.js"type="text/javascript"></script>
</body>
</html>
HTML
22/62
Versioned File Names — After
<!DOCTYPEhtml>
<htmllang="en">
<head>
...
<linkhref="css/app.min.b678e30139fc04.css"rel="stylesheet">
...
</head>
<body>
...
<scriptsrc="js/vendor.min.dda09628f6e1da.js"type="text/javascript"></script>
<scriptsrc="js/app.min.8e46534a4f66158.js"type="text/javascript"></script>
</body>
</html>
HTML
23/62
Development: Turnaround Time Is Important
Production Mode vs. Development Mode
grunt watch
Live Reload
·
·
·
24/62
Production Mode versus Development Mode
Production Development
JS concatenated, minified source files, not minified
CSS compiled (SASS), concatenated, minified only compiled (SASS)
Images Embedded into CSS Embedded into CSS (by Sass/Compass)
HTML references optimized assets references source assets
25/62
Development Mode - Replace References
<!DOCTYPEhtml>
<htmllang="en">
<head>
...
<!--build:csscss/app.min.css-->
<linkrel="stylesheet"href="css/master.css">
<linkrel="stylesheet"href="css/dashboard.css">
...
<!--/build-->
</head>
<body>
<!--build:jsjs/app.min.js-->
<scriptsrc="js/app.js"type="text/javascript"></script>
<scriptsrc="js/routes.js"type="text/javascript"></script>
...
<!--/build-->
</body>
</html>
HTML
26/62
Development Mode - Replace References (cont'd)
Alternative: grunt-usemin to concat, minify & replace in one step
processhtml:{
dist:{
files:{
'<%=appTargetDir%>/index.html':['<%=appSrcDir%>/index.html']
}
}
},
GRUNT
27/62
grunt watch
watch:{
files:[
'<%=jsSrcDir%>/**/*.js',
'<%=cssSrcDir%>/**/*.scss',
'<%=htmlSrcDir%>/**/*.html',
],
tasks:[
'dev-build',
],
options:{
livereload:true,
}
}
GRUNT
28/62
dev-build
grunt.registerTask('dev-build',[
'copy:cssThirdParty',
'sass',
]);
GRUNT
29/62
Live Reload
See changes instantly
Never press F5 again
Let's see this in action!
·
·
·
30/62
Measure it
Google PageSpeed
Yslow
Fiddler
·
·
·
31/62
Comparison
Unoptimized Version
Optimized Version
32/62
Testing
Front end unit tests
34/62
Karma
Open Source Test Runner
Created by the AngularJS team
Write tests in Jasmine, Mocha, QUnit
CI support (Jenkins, Travis)
Based on Node.js and Socket.io
Run in Headless Modus with PhantomJS
Supported Browsers: Firefox, Chrome, Safari, IE (Desktop and Mobile)
·
·
·
·
·
·
·
35/62
Karma and Mocha (JS Test Framework)
Running Unit Tests with Karma
varexpect=chai.expect;
beforeEach(module('project-staffing'));
describe('UpperCaseTest',function(){
it('shouldconvertfirstcharactortoUpperCase',inject(function(uppercaseFilter){
expect(uppercaseFilter('a')).to.equal('A');
expect(uppercaseFilter('helloworld')).to.equal('HelloWorld');
}));
});
JAVASCRIPT
npminstall-gkarma-cli
karmastartkarma.conf.js
//or
gruntkarma
BASH
36/62
Sinon (Mocking Framework)
varActivityService;
var$http;
beforeEach(inject(function(_ActivityService_,_$http_){
ActivityService=_ActivityService_;
$http=_$http_;
sinon.stub($http,'post',function(){});
}));
describe('ActivityService',function(){
it('shouldhavesendhttpPOSTtobackendaftersavingoneactivity',
inject(function(ActivityService){
ActivityService.saveActivity('user','action','object');
expect($http.post.callCount).to.equal(1);
}));
});
JAVASCRIPT
37/62
Chai Assertion Library (BDD/TDD framework)
Should
Expect
Assert
chai.should();
foo.should.be.a('string');
foo.should.equal('bar');
JAVASCRIPT
varexpect=chai.expect;
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
JAVASCRIPT
varassert=chai.assert;
assert.typeOf(foo,'string');
assert.equal(foo,'bar');
JAVASCRIPT
38/62
End2End tests
39/62
Protractor
Open Source E2E Testframework for AngularJS Apps
Tests run in a real browser
Tests can be written with Jasmine (default), Mocha, Cucumber
No more waits and sleeps
Build with Node.js on top of WebdriverJS
·
·
·
·
·
40/62
Protractor and Jasmine (BDD framework)
describe('Managecustomer',function(){
varptor;
beforeEach(function(){
browser.get('/');
ptor=protractor.getInstance();
element(by.id('navEmployees')).click();
element(by.id('navListEmployees')).click();
});
it('shouldnavigatetolistemployeespage',function(){
expect(ptor.getCurrentUrl()).toMatch(/#/list-employees/);
});
});
JAVASCRIPT
41/62
Protractor and Jasmine
Running End2End Tests with Protractor
it('shouldfindemployeeMariaonlistsearchpage',function(){
createMultipleEmployees();//Createsemployees:Max,Maria,Daniel,John
...
element(by.id('searchText')).sendKeys('Ma');
expect(element.all(by.id('employee')).count()).toBe(2);
element(by.id('searchText')).sendKeys('ria');
expect(element.all(by.id('employee')).count()).toBe(1);
});
JAVASCRIPT
npminstall-gprotractor
webdriver-managerstart
protractortest/client/e2e/conf.js
BASH
42/62
Demo :: Project Staffing App
44/62
45/62
46/62
Project Staffing App - TEST Environment
http://54.170.140.7:9000/
Delivery Pipeline
http://54.75.209.193/jenkins/view/EnterJS-Pipeline/
Info: Server will be shutdown after talk
47/62
Delivery Pipeline
48/62
Delivery Pipeline Steps
49/62
Collect the reports
Mocha reporter ⇒unit test
Jasmine reporter ⇒end2end tests
ESLint ⇒static code analysis
·
·
·
50/62
Mocha Report (unit tests)
51/62
Protractor Report (end2end tests)
52/62
ESLint Report (static code analysis)
53/62
Using Container during Development
Docker / boot2docker
docker-compose aka fig
Docker Hub / Registry
·
·
·
Docker
Container Technology, Lightweight, Portable
55/62
boot2docker
Based on Tiny Core Linux (required for MacOS and Windows)
56/62
docker-compose
project-staffinggit:(master)✗ docker-compose
Commands:
build Buildorrebuildservices
help Gethelponacommand
kill Killcontainers
logs Viewoutputfromcontainers
port Printthepublicportforaportbinding
ps Listcontainers
pull Pullsserviceimages
rm Removestoppedcontainers
run Runaone-offcommand
scale Setnumberofcontainersforaservice
start Startservices
stop Stopservices
restart Restartservices
up Createandstartcontainers
BASH
57/62
docker-compose up
➜ project-staffinggit:(master)✗ docker-composeup
Recreatingprojectstaffing_mongodb_1...
Creatingprojectstaffing_nodejsserver_1...
Buildingnodejsserver...
Step0:FROMtcnksm/centos-ruby
--->255207061af8
Step1:RUNyuminstall-ynpm
--->Usingcache
--->c8ca0ad1bec0
Step2:COPY./opt/project-staffing/
--->dc70b159f357
...
Step5:CMDnode/opt/project-staffing/server.js
--->Runningin78d831b9f0f0
--->88b07ba248a0
Successfullybuilt88b07ba248a0
...
BASH
58/62
Docker Hub
https://registry.hub.docker.com/
Official Repositories: redis, ubuntu, WordPress, MySQL, mongoDB, nodeJS, ...
Share your own Containers
·
·
·
59/62
estions?
Consultant
nsultant
EnterJS 2015 - Continuous Integration for Frontend Code

More Related Content

What's hot

Playframework + Twitter Bootstrap
Playframework + Twitter BootstrapPlayframework + Twitter Bootstrap
Playframework + Twitter Bootstrap
Kevingo Tsai
 
Google Developer Group(GDG) DevFest Event 2012 Android talk
Google Developer Group(GDG) DevFest Event 2012 Android talkGoogle Developer Group(GDG) DevFest Event 2012 Android talk
Google Developer Group(GDG) DevFest Event 2012 Android talk
Imam Raza
 
Authentication in Node.js
Authentication in Node.jsAuthentication in Node.js
Authentication in Node.js
Jason Pearson
 
Angular vs React for Web Application Development
Angular vs React for Web Application DevelopmentAngular vs React for Web Application Development
Angular vs React for Web Application Development
FITC
 
Building Progressive Web Apps for Android and iOS
Building Progressive Web Apps for Android and iOSBuilding Progressive Web Apps for Android and iOS
Building Progressive Web Apps for Android and iOS
FITC
 

What's hot (20)

Adobe Experience Manager Core Components
Adobe Experience Manager Core ComponentsAdobe Experience Manager Core Components
Adobe Experience Manager Core Components
 
MVC Frameworks for building PHP Web Applications
MVC Frameworks for building PHP Web ApplicationsMVC Frameworks for building PHP Web Applications
MVC Frameworks for building PHP Web Applications
 
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
 
Playframework + Twitter Bootstrap
Playframework + Twitter BootstrapPlayframework + Twitter Bootstrap
Playframework + Twitter Bootstrap
 
Sightly - AEM6 UI Development using JS and JAVA
Sightly - AEM6 UI Development using JS and JAVASightly - AEM6 UI Development using JS and JAVA
Sightly - AEM6 UI Development using JS and JAVA
 
Building a Secure App with Google Polymer and Java / Spring
Building a Secure App with Google Polymer and Java / SpringBuilding a Secure App with Google Polymer and Java / Spring
Building a Secure App with Google Polymer and Java / Spring
 
Java script Tutorial - QaTrainingHub
Java script Tutorial - QaTrainingHubJava script Tutorial - QaTrainingHub
Java script Tutorial - QaTrainingHub
 
Google Developer Group(GDG) DevFest Event 2012 Android talk
Google Developer Group(GDG) DevFest Event 2012 Android talkGoogle Developer Group(GDG) DevFest Event 2012 Android talk
Google Developer Group(GDG) DevFest Event 2012 Android talk
 
AEM Sightly Template Language
AEM Sightly Template LanguageAEM Sightly Template Language
AEM Sightly Template Language
 
Play Framework vs Grails Smackdown - JavaOne 2013
Play Framework vs Grails Smackdown - JavaOne 2013Play Framework vs Grails Smackdown - JavaOne 2013
Play Framework vs Grails Smackdown - JavaOne 2013
 
The Complementarity of React and Web Components
The Complementarity of React and Web ComponentsThe Complementarity of React and Web Components
The Complementarity of React and Web Components
 
WordCamp Greenville 2018 - Beware the Dark Side, or an Intro to Development
WordCamp Greenville 2018 - Beware the Dark Side, or an Intro to DevelopmentWordCamp Greenville 2018 - Beware the Dark Side, or an Intro to Development
WordCamp Greenville 2018 - Beware the Dark Side, or an Intro to Development
 
Web Components & Polymer 1.0 (Webinale Berlin)
Web Components & Polymer 1.0 (Webinale Berlin)Web Components & Polymer 1.0 (Webinale Berlin)
Web Components & Polymer 1.0 (Webinale Berlin)
 
Booting up with polymer
Booting up with polymerBooting up with polymer
Booting up with polymer
 
Authentication in Node.js
Authentication in Node.jsAuthentication in Node.js
Authentication in Node.js
 
Dynamic components using SPA concepts in AEM
Dynamic components using SPA concepts in AEMDynamic components using SPA concepts in AEM
Dynamic components using SPA concepts in AEM
 
CIRCUIT 2015 - Content API's For AEM Sites
CIRCUIT 2015 - Content API's For AEM SitesCIRCUIT 2015 - Content API's For AEM Sites
CIRCUIT 2015 - Content API's For AEM Sites
 
Angular vs React for Web Application Development
Angular vs React for Web Application DevelopmentAngular vs React for Web Application Development
Angular vs React for Web Application Development
 
Polymer and web component
Polymer and web componentPolymer and web component
Polymer and web component
 
Building Progressive Web Apps for Android and iOS
Building Progressive Web Apps for Android and iOSBuilding Progressive Web Apps for Android and iOS
Building Progressive Web Apps for Android and iOS
 

Similar to EnterJS 2015 - Continuous Integration for Frontend Code

BADCamp 2012 -Beginner Best Practices
BADCamp 2012 -Beginner Best PracticesBADCamp 2012 -Beginner Best Practices
BADCamp 2012 -Beginner Best Practices
meghsweet
 

Similar to EnterJS 2015 - Continuous Integration for Frontend Code (20)

Building Performance - ein Frontend-Build-Prozess für Java mit Maven
Building Performance - ein Frontend-Build-Prozess für Java mit MavenBuilding Performance - ein Frontend-Build-Prozess für Java mit Maven
Building Performance - ein Frontend-Build-Prozess für Java mit Maven
 
Not Just a Pretty Face: How to design and build a cross-CMS CSS framework
Not Just a Pretty Face: How to design and build a cross-CMS CSS frameworkNot Just a Pretty Face: How to design and build a cross-CMS CSS framework
Not Just a Pretty Face: How to design and build a cross-CMS CSS framework
 
Using a CSS Framework
Using a CSS FrameworkUsing a CSS Framework
Using a CSS Framework
 
Scott Jehl - Delivering Responsibly - beyond tellerrand Düsseldorf 2015
Scott Jehl - Delivering Responsibly - beyond tellerrand Düsseldorf 2015Scott Jehl - Delivering Responsibly - beyond tellerrand Düsseldorf 2015
Scott Jehl - Delivering Responsibly - beyond tellerrand Düsseldorf 2015
 
Death of a Themer
Death of a ThemerDeath of a Themer
Death of a Themer
 
Hardboiled Front End Development — Found.ation
Hardboiled Front End Development — Found.ationHardboiled Front End Development — Found.ation
Hardboiled Front End Development — Found.ation
 
10 Tips to make your Website lightning-fast - SMX Stockholm 2012
10 Tips to make your Website lightning-fast - SMX Stockholm 201210 Tips to make your Website lightning-fast - SMX Stockholm 2012
10 Tips to make your Website lightning-fast - SMX Stockholm 2012
 
Build Better Responsive websites. Hrvoje Jurišić
Build Better Responsive websites. Hrvoje JurišićBuild Better Responsive websites. Hrvoje Jurišić
Build Better Responsive websites. Hrvoje Jurišić
 
Front End Workflow
Front End WorkflowFront End Workflow
Front End Workflow
 
EdTechJoker Spring 2020 - Lecture 4 - HTML
EdTechJoker Spring 2020 - Lecture 4 - HTMLEdTechJoker Spring 2020 - Lecture 4 - HTML
EdTechJoker Spring 2020 - Lecture 4 - HTML
 
Building performance auf der Developer Conference Hamburg
Building performance auf der Developer Conference HamburgBuilding performance auf der Developer Conference Hamburg
Building performance auf der Developer Conference Hamburg
 
BADCamp 2012 -Beginner Best Practices
BADCamp 2012 -Beginner Best PracticesBADCamp 2012 -Beginner Best Practices
BADCamp 2012 -Beginner Best Practices
 
HTML / CSS / JS Web basics
HTML / CSS / JS Web basicsHTML / CSS / JS Web basics
HTML / CSS / JS Web basics
 
Structuring your CSS for maintainability: rules and guile lines to write CSS
Structuring your CSS for maintainability: rules and guile lines to write CSSStructuring your CSS for maintainability: rules and guile lines to write CSS
Structuring your CSS for maintainability: rules and guile lines to write CSS
 
The Need for Speed - SMX Sydney 2013
The Need for Speed - SMX Sydney 2013The Need for Speed - SMX Sydney 2013
The Need for Speed - SMX Sydney 2013
 
Presentation Tier optimizations
Presentation Tier optimizationsPresentation Tier optimizations
Presentation Tier optimizations
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
css-tools
css-toolscss-tools
css-tools
 
Generate SSIS packages automatically with Biml and BimlScript (SQLKonferenz 2...
Generate SSIS packages automatically with Biml and BimlScript (SQLKonferenz 2...Generate SSIS packages automatically with Biml and BimlScript (SQLKonferenz 2...
Generate SSIS packages automatically with Biml and BimlScript (SQLKonferenz 2...
 
.NET Fest 2018. Martin Ullrich. MSBuild: Understand and Customize Your .NET B...
.NET Fest 2018. Martin Ullrich. MSBuild: Understand and Customize Your .NET B....NET Fest 2018. Martin Ullrich. MSBuild: Understand and Customize Your .NET B...
.NET Fest 2018. Martin Ullrich. MSBuild: Understand and Customize Your .NET B...
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 

EnterJS 2015 - Continuous Integration for Frontend Code